xref: /aosp_15_r20/external/webrtc/modules/audio_coding/test/Channel.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_coding/test/Channel.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <iostream>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
16*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
19*d9f75844SAndroid Build Coastguard Worker 
SendData(AudioFrameType frameType,uint8_t payloadType,uint32_t timeStamp,const uint8_t * payloadData,size_t payloadSize,int64_t absolute_capture_timestamp_ms)20*d9f75844SAndroid Build Coastguard Worker int32_t Channel::SendData(AudioFrameType frameType,
21*d9f75844SAndroid Build Coastguard Worker                           uint8_t payloadType,
22*d9f75844SAndroid Build Coastguard Worker                           uint32_t timeStamp,
23*d9f75844SAndroid Build Coastguard Worker                           const uint8_t* payloadData,
24*d9f75844SAndroid Build Coastguard Worker                           size_t payloadSize,
25*d9f75844SAndroid Build Coastguard Worker                           int64_t absolute_capture_timestamp_ms) {
26*d9f75844SAndroid Build Coastguard Worker   RTPHeader rtp_header;
27*d9f75844SAndroid Build Coastguard Worker   int32_t status;
28*d9f75844SAndroid Build Coastguard Worker   size_t payloadDataSize = payloadSize;
29*d9f75844SAndroid Build Coastguard Worker 
30*d9f75844SAndroid Build Coastguard Worker   rtp_header.markerBit = false;
31*d9f75844SAndroid Build Coastguard Worker   rtp_header.ssrc = 0;
32*d9f75844SAndroid Build Coastguard Worker   rtp_header.sequenceNumber =
33*d9f75844SAndroid Build Coastguard Worker       (external_sequence_number_ < 0)
34*d9f75844SAndroid Build Coastguard Worker           ? _seqNo++
35*d9f75844SAndroid Build Coastguard Worker           : static_cast<uint16_t>(external_sequence_number_);
36*d9f75844SAndroid Build Coastguard Worker   rtp_header.payloadType = payloadType;
37*d9f75844SAndroid Build Coastguard Worker   rtp_header.timestamp = (external_send_timestamp_ < 0)
38*d9f75844SAndroid Build Coastguard Worker                              ? timeStamp
39*d9f75844SAndroid Build Coastguard Worker                              : static_cast<uint32_t>(external_send_timestamp_);
40*d9f75844SAndroid Build Coastguard Worker 
41*d9f75844SAndroid Build Coastguard Worker   if (frameType == AudioFrameType::kEmptyFrame) {
42*d9f75844SAndroid Build Coastguard Worker     // When frame is empty, we should not transmit it. The frame size of the
43*d9f75844SAndroid Build Coastguard Worker     // next non-empty frame will be based on the previous frame size.
44*d9f75844SAndroid Build Coastguard Worker     _useLastFrameSize = _lastFrameSizeSample > 0;
45*d9f75844SAndroid Build Coastguard Worker     return 0;
46*d9f75844SAndroid Build Coastguard Worker   }
47*d9f75844SAndroid Build Coastguard Worker 
48*d9f75844SAndroid Build Coastguard Worker   memcpy(_payloadData, payloadData, payloadDataSize);
49*d9f75844SAndroid Build Coastguard Worker   if (_isStereo) {
50*d9f75844SAndroid Build Coastguard Worker     if (_leftChannel) {
51*d9f75844SAndroid Build Coastguard Worker       _rtp_header = rtp_header;
52*d9f75844SAndroid Build Coastguard Worker       _leftChannel = false;
53*d9f75844SAndroid Build Coastguard Worker     } else {
54*d9f75844SAndroid Build Coastguard Worker       rtp_header = _rtp_header;
55*d9f75844SAndroid Build Coastguard Worker       _leftChannel = true;
56*d9f75844SAndroid Build Coastguard Worker     }
57*d9f75844SAndroid Build Coastguard Worker   }
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Lock();
60*d9f75844SAndroid Build Coastguard Worker   if (_saveBitStream) {
61*d9f75844SAndroid Build Coastguard Worker     // fwrite(payloadData, sizeof(uint8_t), payloadSize, _bitStreamFile);
62*d9f75844SAndroid Build Coastguard Worker   }
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker   if (!_isStereo) {
65*d9f75844SAndroid Build Coastguard Worker     CalcStatistics(rtp_header, payloadSize);
66*d9f75844SAndroid Build Coastguard Worker   }
67*d9f75844SAndroid Build Coastguard Worker   _useLastFrameSize = false;
68*d9f75844SAndroid Build Coastguard Worker   _lastInTimestamp = timeStamp;
69*d9f75844SAndroid Build Coastguard Worker   _totalBytes += payloadDataSize;
70*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Unlock();
71*d9f75844SAndroid Build Coastguard Worker 
72*d9f75844SAndroid Build Coastguard Worker   if (_useFECTestWithPacketLoss) {
73*d9f75844SAndroid Build Coastguard Worker     _packetLoss += 1;
74*d9f75844SAndroid Build Coastguard Worker     if (_packetLoss == 3) {
75*d9f75844SAndroid Build Coastguard Worker       _packetLoss = 0;
76*d9f75844SAndroid Build Coastguard Worker       return 0;
77*d9f75844SAndroid Build Coastguard Worker     }
78*d9f75844SAndroid Build Coastguard Worker   }
79*d9f75844SAndroid Build Coastguard Worker 
80*d9f75844SAndroid Build Coastguard Worker   if (num_packets_to_drop_ > 0) {
81*d9f75844SAndroid Build Coastguard Worker     num_packets_to_drop_--;
82*d9f75844SAndroid Build Coastguard Worker     return 0;
83*d9f75844SAndroid Build Coastguard Worker   }
84*d9f75844SAndroid Build Coastguard Worker 
85*d9f75844SAndroid Build Coastguard Worker   status =
86*d9f75844SAndroid Build Coastguard Worker       _receiverACM->IncomingPacket(_payloadData, payloadDataSize, rtp_header);
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   return status;
89*d9f75844SAndroid Build Coastguard Worker }
90*d9f75844SAndroid Build Coastguard Worker 
91*d9f75844SAndroid Build Coastguard Worker // TODO(turajs): rewite this method.
CalcStatistics(const RTPHeader & rtp_header,size_t payloadSize)92*d9f75844SAndroid Build Coastguard Worker void Channel::CalcStatistics(const RTPHeader& rtp_header, size_t payloadSize) {
93*d9f75844SAndroid Build Coastguard Worker   int n;
94*d9f75844SAndroid Build Coastguard Worker   if ((rtp_header.payloadType != _lastPayloadType) &&
95*d9f75844SAndroid Build Coastguard Worker       (_lastPayloadType != -1)) {
96*d9f75844SAndroid Build Coastguard Worker     // payload-type is changed.
97*d9f75844SAndroid Build Coastguard Worker     // we have to terminate the calculations on the previous payload type
98*d9f75844SAndroid Build Coastguard Worker     // we ignore the last packet in that payload type just to make things
99*d9f75844SAndroid Build Coastguard Worker     // easier.
100*d9f75844SAndroid Build Coastguard Worker     for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
101*d9f75844SAndroid Build Coastguard Worker       if (_lastPayloadType == _payloadStats[n].payloadType) {
102*d9f75844SAndroid Build Coastguard Worker         _payloadStats[n].newPacket = true;
103*d9f75844SAndroid Build Coastguard Worker         break;
104*d9f75844SAndroid Build Coastguard Worker       }
105*d9f75844SAndroid Build Coastguard Worker     }
106*d9f75844SAndroid Build Coastguard Worker   }
107*d9f75844SAndroid Build Coastguard Worker   _lastPayloadType = rtp_header.payloadType;
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker   bool newPayload = true;
110*d9f75844SAndroid Build Coastguard Worker   ACMTestPayloadStats* currentPayloadStr = NULL;
111*d9f75844SAndroid Build Coastguard Worker   for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
112*d9f75844SAndroid Build Coastguard Worker     if (rtp_header.payloadType == _payloadStats[n].payloadType) {
113*d9f75844SAndroid Build Coastguard Worker       newPayload = false;
114*d9f75844SAndroid Build Coastguard Worker       currentPayloadStr = &_payloadStats[n];
115*d9f75844SAndroid Build Coastguard Worker       break;
116*d9f75844SAndroid Build Coastguard Worker     }
117*d9f75844SAndroid Build Coastguard Worker   }
118*d9f75844SAndroid Build Coastguard Worker 
119*d9f75844SAndroid Build Coastguard Worker   if (!newPayload) {
120*d9f75844SAndroid Build Coastguard Worker     if (!currentPayloadStr->newPacket) {
121*d9f75844SAndroid Build Coastguard Worker       if (!_useLastFrameSize) {
122*d9f75844SAndroid Build Coastguard Worker         _lastFrameSizeSample =
123*d9f75844SAndroid Build Coastguard Worker             (uint32_t)((uint32_t)rtp_header.timestamp -
124*d9f75844SAndroid Build Coastguard Worker                        (uint32_t)currentPayloadStr->lastTimestamp);
125*d9f75844SAndroid Build Coastguard Worker       }
126*d9f75844SAndroid Build Coastguard Worker       RTC_DCHECK_GT(_lastFrameSizeSample, 0);
127*d9f75844SAndroid Build Coastguard Worker       int k = 0;
128*d9f75844SAndroid Build Coastguard Worker       for (; k < MAX_NUM_FRAMESIZES; ++k) {
129*d9f75844SAndroid Build Coastguard Worker         if ((currentPayloadStr->frameSizeStats[k].frameSizeSample ==
130*d9f75844SAndroid Build Coastguard Worker              _lastFrameSizeSample) ||
131*d9f75844SAndroid Build Coastguard Worker             (currentPayloadStr->frameSizeStats[k].frameSizeSample == 0)) {
132*d9f75844SAndroid Build Coastguard Worker           break;
133*d9f75844SAndroid Build Coastguard Worker         }
134*d9f75844SAndroid Build Coastguard Worker       }
135*d9f75844SAndroid Build Coastguard Worker       if (k == MAX_NUM_FRAMESIZES) {
136*d9f75844SAndroid Build Coastguard Worker         // New frame size found but no space to count statistics on it. Skip it.
137*d9f75844SAndroid Build Coastguard Worker         printf("No memory to store statistics for payload %d : frame size %d\n",
138*d9f75844SAndroid Build Coastguard Worker                _lastPayloadType, _lastFrameSizeSample);
139*d9f75844SAndroid Build Coastguard Worker         return;
140*d9f75844SAndroid Build Coastguard Worker       }
141*d9f75844SAndroid Build Coastguard Worker       ACMTestFrameSizeStats* currentFrameSizeStats =
142*d9f75844SAndroid Build Coastguard Worker           &(currentPayloadStr->frameSizeStats[k]);
143*d9f75844SAndroid Build Coastguard Worker       currentFrameSizeStats->frameSizeSample = (int16_t)_lastFrameSizeSample;
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker       // increment the number of encoded samples.
146*d9f75844SAndroid Build Coastguard Worker       currentFrameSizeStats->totalEncodedSamples += _lastFrameSizeSample;
147*d9f75844SAndroid Build Coastguard Worker       // increment the number of recveived packets
148*d9f75844SAndroid Build Coastguard Worker       currentFrameSizeStats->numPackets++;
149*d9f75844SAndroid Build Coastguard Worker       // increment the total number of bytes (this is based on
150*d9f75844SAndroid Build Coastguard Worker       // the previous payload we don't know the frame-size of
151*d9f75844SAndroid Build Coastguard Worker       // the current payload.
152*d9f75844SAndroid Build Coastguard Worker       currentFrameSizeStats->totalPayloadLenByte +=
153*d9f75844SAndroid Build Coastguard Worker           currentPayloadStr->lastPayloadLenByte;
154*d9f75844SAndroid Build Coastguard Worker       // store the maximum payload-size (this is based on
155*d9f75844SAndroid Build Coastguard Worker       // the previous payload we don't know the frame-size of
156*d9f75844SAndroid Build Coastguard Worker       // the current payload.
157*d9f75844SAndroid Build Coastguard Worker       if (currentFrameSizeStats->maxPayloadLen <
158*d9f75844SAndroid Build Coastguard Worker           currentPayloadStr->lastPayloadLenByte) {
159*d9f75844SAndroid Build Coastguard Worker         currentFrameSizeStats->maxPayloadLen =
160*d9f75844SAndroid Build Coastguard Worker             currentPayloadStr->lastPayloadLenByte;
161*d9f75844SAndroid Build Coastguard Worker       }
162*d9f75844SAndroid Build Coastguard Worker       // store the current values for the next time
163*d9f75844SAndroid Build Coastguard Worker       currentPayloadStr->lastTimestamp = rtp_header.timestamp;
164*d9f75844SAndroid Build Coastguard Worker       currentPayloadStr->lastPayloadLenByte = payloadSize;
165*d9f75844SAndroid Build Coastguard Worker     } else {
166*d9f75844SAndroid Build Coastguard Worker       currentPayloadStr->newPacket = false;
167*d9f75844SAndroid Build Coastguard Worker       currentPayloadStr->lastPayloadLenByte = payloadSize;
168*d9f75844SAndroid Build Coastguard Worker       currentPayloadStr->lastTimestamp = rtp_header.timestamp;
169*d9f75844SAndroid Build Coastguard Worker       currentPayloadStr->payloadType = rtp_header.payloadType;
170*d9f75844SAndroid Build Coastguard Worker       memset(currentPayloadStr->frameSizeStats, 0,
171*d9f75844SAndroid Build Coastguard Worker              MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
172*d9f75844SAndroid Build Coastguard Worker     }
173*d9f75844SAndroid Build Coastguard Worker   } else {
174*d9f75844SAndroid Build Coastguard Worker     n = 0;
175*d9f75844SAndroid Build Coastguard Worker     while (_payloadStats[n].payloadType != -1) {
176*d9f75844SAndroid Build Coastguard Worker       n++;
177*d9f75844SAndroid Build Coastguard Worker     }
178*d9f75844SAndroid Build Coastguard Worker     // first packet
179*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].newPacket = false;
180*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].lastPayloadLenByte = payloadSize;
181*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].lastTimestamp = rtp_header.timestamp;
182*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].payloadType = rtp_header.payloadType;
183*d9f75844SAndroid Build Coastguard Worker     memset(_payloadStats[n].frameSizeStats, 0,
184*d9f75844SAndroid Build Coastguard Worker            MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
185*d9f75844SAndroid Build Coastguard Worker   }
186*d9f75844SAndroid Build Coastguard Worker }
187*d9f75844SAndroid Build Coastguard Worker 
Channel(int16_t chID)188*d9f75844SAndroid Build Coastguard Worker Channel::Channel(int16_t chID)
189*d9f75844SAndroid Build Coastguard Worker     : _receiverACM(NULL),
190*d9f75844SAndroid Build Coastguard Worker       _seqNo(0),
191*d9f75844SAndroid Build Coastguard Worker       _bitStreamFile(NULL),
192*d9f75844SAndroid Build Coastguard Worker       _saveBitStream(false),
193*d9f75844SAndroid Build Coastguard Worker       _lastPayloadType(-1),
194*d9f75844SAndroid Build Coastguard Worker       _isStereo(false),
195*d9f75844SAndroid Build Coastguard Worker       _leftChannel(true),
196*d9f75844SAndroid Build Coastguard Worker       _lastInTimestamp(0),
197*d9f75844SAndroid Build Coastguard Worker       _useLastFrameSize(false),
198*d9f75844SAndroid Build Coastguard Worker       _lastFrameSizeSample(0),
199*d9f75844SAndroid Build Coastguard Worker       _packetLoss(0),
200*d9f75844SAndroid Build Coastguard Worker       _useFECTestWithPacketLoss(false),
201*d9f75844SAndroid Build Coastguard Worker       _beginTime(rtc::TimeMillis()),
202*d9f75844SAndroid Build Coastguard Worker       _totalBytes(0),
203*d9f75844SAndroid Build Coastguard Worker       external_send_timestamp_(-1),
204*d9f75844SAndroid Build Coastguard Worker       external_sequence_number_(-1),
205*d9f75844SAndroid Build Coastguard Worker       num_packets_to_drop_(0) {
206*d9f75844SAndroid Build Coastguard Worker   int n;
207*d9f75844SAndroid Build Coastguard Worker   int k;
208*d9f75844SAndroid Build Coastguard Worker   for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
209*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].payloadType = -1;
210*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].newPacket = true;
211*d9f75844SAndroid Build Coastguard Worker     for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
212*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
213*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
214*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].numPackets = 0;
215*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
216*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
217*d9f75844SAndroid Build Coastguard Worker     }
218*d9f75844SAndroid Build Coastguard Worker   }
219*d9f75844SAndroid Build Coastguard Worker   if (chID >= 0) {
220*d9f75844SAndroid Build Coastguard Worker     _saveBitStream = true;
221*d9f75844SAndroid Build Coastguard Worker     rtc::StringBuilder ss;
222*d9f75844SAndroid Build Coastguard Worker     ss.AppendFormat("bitStream_%d.dat", chID);
223*d9f75844SAndroid Build Coastguard Worker     _bitStreamFile = fopen(ss.str().c_str(), "wb");
224*d9f75844SAndroid Build Coastguard Worker   } else {
225*d9f75844SAndroid Build Coastguard Worker     _saveBitStream = false;
226*d9f75844SAndroid Build Coastguard Worker   }
227*d9f75844SAndroid Build Coastguard Worker }
228*d9f75844SAndroid Build Coastguard Worker 
~Channel()229*d9f75844SAndroid Build Coastguard Worker Channel::~Channel() {}
230*d9f75844SAndroid Build Coastguard Worker 
RegisterReceiverACM(AudioCodingModule * acm)231*d9f75844SAndroid Build Coastguard Worker void Channel::RegisterReceiverACM(AudioCodingModule* acm) {
232*d9f75844SAndroid Build Coastguard Worker   _receiverACM = acm;
233*d9f75844SAndroid Build Coastguard Worker   return;
234*d9f75844SAndroid Build Coastguard Worker }
235*d9f75844SAndroid Build Coastguard Worker 
ResetStats()236*d9f75844SAndroid Build Coastguard Worker void Channel::ResetStats() {
237*d9f75844SAndroid Build Coastguard Worker   int n;
238*d9f75844SAndroid Build Coastguard Worker   int k;
239*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Lock();
240*d9f75844SAndroid Build Coastguard Worker   _lastPayloadType = -1;
241*d9f75844SAndroid Build Coastguard Worker   for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
242*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].payloadType = -1;
243*d9f75844SAndroid Build Coastguard Worker     _payloadStats[n].newPacket = true;
244*d9f75844SAndroid Build Coastguard Worker     for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
245*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
246*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
247*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].numPackets = 0;
248*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
249*d9f75844SAndroid Build Coastguard Worker       _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
250*d9f75844SAndroid Build Coastguard Worker     }
251*d9f75844SAndroid Build Coastguard Worker   }
252*d9f75844SAndroid Build Coastguard Worker   _beginTime = rtc::TimeMillis();
253*d9f75844SAndroid Build Coastguard Worker   _totalBytes = 0;
254*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Unlock();
255*d9f75844SAndroid Build Coastguard Worker }
256*d9f75844SAndroid Build Coastguard Worker 
LastInTimestamp()257*d9f75844SAndroid Build Coastguard Worker uint32_t Channel::LastInTimestamp() {
258*d9f75844SAndroid Build Coastguard Worker   uint32_t timestamp;
259*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Lock();
260*d9f75844SAndroid Build Coastguard Worker   timestamp = _lastInTimestamp;
261*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Unlock();
262*d9f75844SAndroid Build Coastguard Worker   return timestamp;
263*d9f75844SAndroid Build Coastguard Worker }
264*d9f75844SAndroid Build Coastguard Worker 
BitRate()265*d9f75844SAndroid Build Coastguard Worker double Channel::BitRate() {
266*d9f75844SAndroid Build Coastguard Worker   double rate;
267*d9f75844SAndroid Build Coastguard Worker   uint64_t currTime = rtc::TimeMillis();
268*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Lock();
269*d9f75844SAndroid Build Coastguard Worker   rate = ((double)_totalBytes * 8.0) / (double)(currTime - _beginTime);
270*d9f75844SAndroid Build Coastguard Worker   _channelCritSect.Unlock();
271*d9f75844SAndroid Build Coastguard Worker   return rate;
272*d9f75844SAndroid Build Coastguard Worker }
273*d9f75844SAndroid Build Coastguard Worker 
274*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
275