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