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