blob: 3590891e422f5d1afa75012dd11a1bdd7d86d4a1 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
tina.legrand@webrtc.org16b6b902012-04-12 11:02:38 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_coding/test/Channel.h"
turaj@webrtc.orga305e962013-06-06 19:00:09 +000012
niklase@google.com470e71d2011-07-07 08:21:25 +000013#include <assert.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
niklase@google.com470e71d2011-07-07 08:21:25 +000015#include <iostream>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "rtc_base/format_macros.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/time_utils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000019
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000020namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000021
Niels Möller87e2d782019-03-07 10:18:23 +010022int32_t Channel::SendData(AudioFrameType frameType,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000023 uint8_t payloadType,
24 uint32_t timeStamp,
25 const uint8_t* payloadData,
Minyue Liff0e4db2020-01-23 13:45:50 +010026 size_t payloadSize,
27 int64_t absolute_capture_timestamp_ms) {
Niels Möllerbf474952019-02-18 12:00:06 +010028 RTPHeader rtp_header;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000029 int32_t status;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000030 size_t payloadDataSize = payloadSize;
niklase@google.com470e71d2011-07-07 08:21:25 +000031
Niels Möllerbf474952019-02-18 12:00:06 +010032 rtp_header.markerBit = false;
33 rtp_header.ssrc = 0;
34 rtp_header.sequenceNumber =
Yves Gerey665174f2018-06-19 15:03:05 +020035 (external_sequence_number_ < 0)
36 ? _seqNo++
37 : static_cast<uint16_t>(external_sequence_number_);
Niels Möllerbf474952019-02-18 12:00:06 +010038 rtp_header.payloadType = payloadType;
39 rtp_header.timestamp = (external_send_timestamp_ < 0)
40 ? timeStamp
41 : static_cast<uint32_t>(external_send_timestamp_);
turaj@webrtc.orga305e962013-06-06 19:00:09 +000042
Niels Möllerc936cb62019-03-19 14:10:16 +010043 if (frameType == AudioFrameType::kEmptyFrame) {
minyue@webrtc.org05617162015-03-03 12:02:30 +000044 // When frame is empty, we should not transmit it. The frame size of the
45 // next non-empty frame will be based on the previous frame size.
46 _useLastFrameSize = _lastFrameSizeSample > 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000047 return 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000048 }
niklase@google.com470e71d2011-07-07 08:21:25 +000049
Niels Möllerc35b6e62019-04-25 16:31:18 +020050 memcpy(_payloadData, payloadData, payloadDataSize);
51 if (_isStereo) {
52 if (_leftChannel) {
53 _rtp_header = rtp_header;
54 _leftChannel = false;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000055 } else {
Niels Möllerc35b6e62019-04-25 16:31:18 +020056 rtp_header = _rtp_header;
57 _leftChannel = true;
niklase@google.com470e71d2011-07-07 08:21:25 +000058 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000059 }
niklase@google.com470e71d2011-07-07 08:21:25 +000060
Tommi9090e0b2016-01-20 13:39:36 +010061 _channelCritSect.Enter();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000062 if (_saveBitStream) {
Yves Gerey665174f2018-06-19 15:03:05 +020063 // fwrite(payloadData, sizeof(uint8_t), payloadSize, _bitStreamFile);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000064 }
niklase@google.com470e71d2011-07-07 08:21:25 +000065
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000066 if (!_isStereo) {
Niels Möllerbf474952019-02-18 12:00:06 +010067 CalcStatistics(rtp_header, payloadSize);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000068 }
minyue@webrtc.org05617162015-03-03 12:02:30 +000069 _useLastFrameSize = false;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000070 _lastInTimestamp = timeStamp;
71 _totalBytes += payloadDataSize;
Tommi9090e0b2016-01-20 13:39:36 +010072 _channelCritSect.Leave();
niklase@google.com470e71d2011-07-07 08:21:25 +000073
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000074 if (_useFECTestWithPacketLoss) {
75 _packetLoss += 1;
76 if (_packetLoss == 3) {
77 _packetLoss = 0;
78 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000079 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000080 }
niklase@google.com470e71d2011-07-07 08:21:25 +000081
turaj@webrtc.orga305e962013-06-06 19:00:09 +000082 if (num_packets_to_drop_ > 0) {
83 num_packets_to_drop_--;
84 return 0;
85 }
86
Niels Möllerbf474952019-02-18 12:00:06 +010087 status =
88 _receiverACM->IncomingPacket(_payloadData, payloadDataSize, rtp_header);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000089
90 return status;
91}
92
turaj@webrtc.orgc2d69d32014-02-19 20:31:17 +000093// TODO(turajs): rewite this method.
Niels Möllerbf474952019-02-18 12:00:06 +010094void Channel::CalcStatistics(const RTPHeader& rtp_header, size_t payloadSize) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000095 int n;
Niels Möllerbf474952019-02-18 12:00:06 +010096 if ((rtp_header.payloadType != _lastPayloadType) &&
Yves Gerey665174f2018-06-19 15:03:05 +020097 (_lastPayloadType != -1)) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000098 // payload-type is changed.
99 // we have to terminate the calculations on the previous payload type
100 // we ignore the last packet in that payload type just to make things
101 // easier.
102 for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
103 if (_lastPayloadType == _payloadStats[n].payloadType) {
104 _payloadStats[n].newPacket = true;
105 break;
106 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000107 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000108 }
Niels Möllerbf474952019-02-18 12:00:06 +0100109 _lastPayloadType = rtp_header.payloadType;
niklase@google.com470e71d2011-07-07 08:21:25 +0000110
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000111 bool newPayload = true;
112 ACMTestPayloadStats* currentPayloadStr = NULL;
113 for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
Niels Möllerbf474952019-02-18 12:00:06 +0100114 if (rtp_header.payloadType == _payloadStats[n].payloadType) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000115 newPayload = false;
116 currentPayloadStr = &_payloadStats[n];
117 break;
118 }
119 }
120
121 if (!newPayload) {
122 if (!currentPayloadStr->newPacket) {
minyue@webrtc.org05617162015-03-03 12:02:30 +0000123 if (!_useLastFrameSize) {
Yves Gerey665174f2018-06-19 15:03:05 +0200124 _lastFrameSizeSample =
Niels Möllerbf474952019-02-18 12:00:06 +0100125 (uint32_t)((uint32_t)rtp_header.timestamp -
Yves Gerey665174f2018-06-19 15:03:05 +0200126 (uint32_t)currentPayloadStr->lastTimestamp);
minyue@webrtc.org05617162015-03-03 12:02:30 +0000127 }
128 assert(_lastFrameSizeSample > 0);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000129 int k = 0;
minyue@webrtc.org05617162015-03-03 12:02:30 +0000130 for (; k < MAX_NUM_FRAMESIZES; ++k) {
131 if ((currentPayloadStr->frameSizeStats[k].frameSizeSample ==
Yves Gerey665174f2018-06-19 15:03:05 +0200132 _lastFrameSizeSample) ||
minyue@webrtc.org05617162015-03-03 12:02:30 +0000133 (currentPayloadStr->frameSizeStats[k].frameSizeSample == 0)) {
134 break;
135 }
136 }
137 if (k == MAX_NUM_FRAMESIZES) {
138 // New frame size found but no space to count statistics on it. Skip it.
139 printf("No memory to store statistics for payload %d : frame size %d\n",
140 _lastPayloadType, _lastFrameSizeSample);
141 return;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000142 }
Yves Gerey665174f2018-06-19 15:03:05 +0200143 ACMTestFrameSizeStats* currentFrameSizeStats =
144 &(currentPayloadStr->frameSizeStats[k]);
145 currentFrameSizeStats->frameSizeSample = (int16_t)_lastFrameSizeSample;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000146
147 // increment the number of encoded samples.
minyue@webrtc.org05617162015-03-03 12:02:30 +0000148 currentFrameSizeStats->totalEncodedSamples += _lastFrameSizeSample;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000149 // increment the number of recveived packets
150 currentFrameSizeStats->numPackets++;
151 // increment the total number of bytes (this is based on
152 // the previous payload we don't know the frame-size of
153 // the current payload.
Yves Gerey665174f2018-06-19 15:03:05 +0200154 currentFrameSizeStats->totalPayloadLenByte +=
155 currentPayloadStr->lastPayloadLenByte;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000156 // store the maximum payload-size (this is based on
157 // the previous payload we don't know the frame-size of
158 // the current payload.
Yves Gerey665174f2018-06-19 15:03:05 +0200159 if (currentFrameSizeStats->maxPayloadLen <
160 currentPayloadStr->lastPayloadLenByte) {
161 currentFrameSizeStats->maxPayloadLen =
162 currentPayloadStr->lastPayloadLenByte;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000163 }
164 // store the current values for the next time
Niels Möllerbf474952019-02-18 12:00:06 +0100165 currentPayloadStr->lastTimestamp = rtp_header.timestamp;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000166 currentPayloadStr->lastPayloadLenByte = payloadSize;
167 } else {
168 currentPayloadStr->newPacket = false;
169 currentPayloadStr->lastPayloadLenByte = payloadSize;
Niels Möllerbf474952019-02-18 12:00:06 +0100170 currentPayloadStr->lastTimestamp = rtp_header.timestamp;
171 currentPayloadStr->payloadType = rtp_header.payloadType;
Yves Gerey665174f2018-06-19 15:03:05 +0200172 memset(currentPayloadStr->frameSizeStats, 0,
173 MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000174 }
175 } else {
176 n = 0;
177 while (_payloadStats[n].payloadType != -1) {
178 n++;
179 }
180 // first packet
181 _payloadStats[n].newPacket = false;
182 _payloadStats[n].lastPayloadLenByte = payloadSize;
Niels Möllerbf474952019-02-18 12:00:06 +0100183 _payloadStats[n].lastTimestamp = rtp_header.timestamp;
184 _payloadStats[n].payloadType = rtp_header.payloadType;
Yves Gerey665174f2018-06-19 15:03:05 +0200185 memset(_payloadStats[n].frameSizeStats, 0,
186 MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000187 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000188}
189
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000190Channel::Channel(int16_t chID)
191 : _receiverACM(NULL),
192 _seqNo(0),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000193 _bitStreamFile(NULL),
194 _saveBitStream(false),
195 _lastPayloadType(-1),
196 _isStereo(false),
197 _leftChannel(true),
198 _lastInTimestamp(0),
minyue@webrtc.org05617162015-03-03 12:02:30 +0000199 _useLastFrameSize(false),
200 _lastFrameSizeSample(0),
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000201 _packetLoss(0),
202 _useFECTestWithPacketLoss(false),
Niels Möllerd28db7f2016-05-10 16:31:47 +0200203 _beginTime(rtc::TimeMillis()),
turaj@webrtc.orga305e962013-06-06 19:00:09 +0000204 _totalBytes(0),
205 external_send_timestamp_(-1),
206 external_sequence_number_(-1),
207 num_packets_to_drop_(0) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000208 int n;
209 int k;
210 for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
211 _payloadStats[n].payloadType = -1;
212 _payloadStats[n].newPacket = true;
213 for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
214 _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
215 _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
216 _payloadStats[n].frameSizeStats[k].numPackets = 0;
217 _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
218 _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
219 }
220 }
221 if (chID >= 0) {
222 _saveBitStream = true;
223 char bitStreamFileName[500];
224 sprintf(bitStreamFileName, "bitStream_%d.dat", chID);
225 _bitStreamFile = fopen(bitStreamFileName, "wb");
226 } else {
227 _saveBitStream = false;
228 }
229}
230
Yves Gerey665174f2018-06-19 15:03:05 +0200231Channel::~Channel() {}
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000232
233void Channel::RegisterReceiverACM(AudioCodingModule* acm) {
234 _receiverACM = acm;
235 return;
236}
237
238void Channel::ResetStats() {
239 int n;
240 int k;
Tommi9090e0b2016-01-20 13:39:36 +0100241 _channelCritSect.Enter();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000242 _lastPayloadType = -1;
243 for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
244 _payloadStats[n].payloadType = -1;
245 _payloadStats[n].newPacket = true;
246 for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
247 _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
248 _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
249 _payloadStats[n].frameSizeStats[k].numPackets = 0;
250 _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
251 _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
252 }
253 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200254 _beginTime = rtc::TimeMillis();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000255 _totalBytes = 0;
Tommi9090e0b2016-01-20 13:39:36 +0100256 _channelCritSect.Leave();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000257}
258
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000259uint32_t Channel::LastInTimestamp() {
260 uint32_t timestamp;
Tommi9090e0b2016-01-20 13:39:36 +0100261 _channelCritSect.Enter();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000262 timestamp = _lastInTimestamp;
Tommi9090e0b2016-01-20 13:39:36 +0100263 _channelCritSect.Leave();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000264 return timestamp;
265}
266
267double Channel::BitRate() {
268 double rate;
Niels Möllerd28db7f2016-05-10 16:31:47 +0200269 uint64_t currTime = rtc::TimeMillis();
Tommi9090e0b2016-01-20 13:39:36 +0100270 _channelCritSect.Enter();
Yves Gerey665174f2018-06-19 15:03:05 +0200271 rate = ((double)_totalBytes * 8.0) / (double)(currTime - _beginTime);
Tommi9090e0b2016-01-20 13:39:36 +0100272 _channelCritSect.Leave();
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000273 return rate;
274}
275
276} // namespace webrtc