summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/audio_coding/test/Channel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/audio_coding/test/Channel.cc')
-rw-r--r--third_party/libwebrtc/modules/audio_coding/test/Channel.cc274
1 files changed, 274 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/audio_coding/test/Channel.cc b/third_party/libwebrtc/modules/audio_coding/test/Channel.cc
new file mode 100644
index 0000000000..35aa6cb6b4
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_coding/test/Channel.cc
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/audio_coding/test/Channel.h"
+
+#include <iostream>
+
+#include "rtc_base/strings/string_builder.h"
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+
+int32_t Channel::SendData(AudioFrameType frameType,
+ uint8_t payloadType,
+ uint32_t timeStamp,
+ const uint8_t* payloadData,
+ size_t payloadSize,
+ int64_t absolute_capture_timestamp_ms) {
+ RTPHeader rtp_header;
+ int32_t status;
+ size_t payloadDataSize = payloadSize;
+
+ rtp_header.markerBit = false;
+ rtp_header.ssrc = 0;
+ rtp_header.sequenceNumber =
+ (external_sequence_number_ < 0)
+ ? _seqNo++
+ : static_cast<uint16_t>(external_sequence_number_);
+ rtp_header.payloadType = payloadType;
+ rtp_header.timestamp = (external_send_timestamp_ < 0)
+ ? timeStamp
+ : static_cast<uint32_t>(external_send_timestamp_);
+
+ if (frameType == AudioFrameType::kEmptyFrame) {
+ // When frame is empty, we should not transmit it. The frame size of the
+ // next non-empty frame will be based on the previous frame size.
+ _useLastFrameSize = _lastFrameSizeSample > 0;
+ return 0;
+ }
+
+ memcpy(_payloadData, payloadData, payloadDataSize);
+ if (_isStereo) {
+ if (_leftChannel) {
+ _rtp_header = rtp_header;
+ _leftChannel = false;
+ } else {
+ rtp_header = _rtp_header;
+ _leftChannel = true;
+ }
+ }
+
+ _channelCritSect.Lock();
+ if (_saveBitStream) {
+ // fwrite(payloadData, sizeof(uint8_t), payloadSize, _bitStreamFile);
+ }
+
+ if (!_isStereo) {
+ CalcStatistics(rtp_header, payloadSize);
+ }
+ _useLastFrameSize = false;
+ _lastInTimestamp = timeStamp;
+ _totalBytes += payloadDataSize;
+ _channelCritSect.Unlock();
+
+ if (_useFECTestWithPacketLoss) {
+ _packetLoss += 1;
+ if (_packetLoss == 3) {
+ _packetLoss = 0;
+ return 0;
+ }
+ }
+
+ if (num_packets_to_drop_ > 0) {
+ num_packets_to_drop_--;
+ return 0;
+ }
+
+ status =
+ _receiverACM->IncomingPacket(_payloadData, payloadDataSize, rtp_header);
+
+ return status;
+}
+
+// TODO(turajs): rewite this method.
+void Channel::CalcStatistics(const RTPHeader& rtp_header, size_t payloadSize) {
+ int n;
+ if ((rtp_header.payloadType != _lastPayloadType) &&
+ (_lastPayloadType != -1)) {
+ // payload-type is changed.
+ // we have to terminate the calculations on the previous payload type
+ // we ignore the last packet in that payload type just to make things
+ // easier.
+ for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
+ if (_lastPayloadType == _payloadStats[n].payloadType) {
+ _payloadStats[n].newPacket = true;
+ break;
+ }
+ }
+ }
+ _lastPayloadType = rtp_header.payloadType;
+
+ bool newPayload = true;
+ ACMTestPayloadStats* currentPayloadStr = NULL;
+ for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
+ if (rtp_header.payloadType == _payloadStats[n].payloadType) {
+ newPayload = false;
+ currentPayloadStr = &_payloadStats[n];
+ break;
+ }
+ }
+
+ if (!newPayload) {
+ if (!currentPayloadStr->newPacket) {
+ if (!_useLastFrameSize) {
+ _lastFrameSizeSample =
+ (uint32_t)((uint32_t)rtp_header.timestamp -
+ (uint32_t)currentPayloadStr->lastTimestamp);
+ }
+ RTC_DCHECK_GT(_lastFrameSizeSample, 0);
+ int k = 0;
+ for (; k < MAX_NUM_FRAMESIZES; ++k) {
+ if ((currentPayloadStr->frameSizeStats[k].frameSizeSample ==
+ _lastFrameSizeSample) ||
+ (currentPayloadStr->frameSizeStats[k].frameSizeSample == 0)) {
+ break;
+ }
+ }
+ if (k == MAX_NUM_FRAMESIZES) {
+ // New frame size found but no space to count statistics on it. Skip it.
+ printf("No memory to store statistics for payload %d : frame size %d\n",
+ _lastPayloadType, _lastFrameSizeSample);
+ return;
+ }
+ ACMTestFrameSizeStats* currentFrameSizeStats =
+ &(currentPayloadStr->frameSizeStats[k]);
+ currentFrameSizeStats->frameSizeSample = (int16_t)_lastFrameSizeSample;
+
+ // increment the number of encoded samples.
+ currentFrameSizeStats->totalEncodedSamples += _lastFrameSizeSample;
+ // increment the number of recveived packets
+ currentFrameSizeStats->numPackets++;
+ // increment the total number of bytes (this is based on
+ // the previous payload we don't know the frame-size of
+ // the current payload.
+ currentFrameSizeStats->totalPayloadLenByte +=
+ currentPayloadStr->lastPayloadLenByte;
+ // store the maximum payload-size (this is based on
+ // the previous payload we don't know the frame-size of
+ // the current payload.
+ if (currentFrameSizeStats->maxPayloadLen <
+ currentPayloadStr->lastPayloadLenByte) {
+ currentFrameSizeStats->maxPayloadLen =
+ currentPayloadStr->lastPayloadLenByte;
+ }
+ // store the current values for the next time
+ currentPayloadStr->lastTimestamp = rtp_header.timestamp;
+ currentPayloadStr->lastPayloadLenByte = payloadSize;
+ } else {
+ currentPayloadStr->newPacket = false;
+ currentPayloadStr->lastPayloadLenByte = payloadSize;
+ currentPayloadStr->lastTimestamp = rtp_header.timestamp;
+ currentPayloadStr->payloadType = rtp_header.payloadType;
+ memset(currentPayloadStr->frameSizeStats, 0,
+ MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
+ }
+ } else {
+ n = 0;
+ while (_payloadStats[n].payloadType != -1) {
+ n++;
+ }
+ // first packet
+ _payloadStats[n].newPacket = false;
+ _payloadStats[n].lastPayloadLenByte = payloadSize;
+ _payloadStats[n].lastTimestamp = rtp_header.timestamp;
+ _payloadStats[n].payloadType = rtp_header.payloadType;
+ memset(_payloadStats[n].frameSizeStats, 0,
+ MAX_NUM_FRAMESIZES * sizeof(ACMTestFrameSizeStats));
+ }
+}
+
+Channel::Channel(int16_t chID)
+ : _receiverACM(NULL),
+ _seqNo(0),
+ _bitStreamFile(NULL),
+ _saveBitStream(false),
+ _lastPayloadType(-1),
+ _isStereo(false),
+ _leftChannel(true),
+ _lastInTimestamp(0),
+ _useLastFrameSize(false),
+ _lastFrameSizeSample(0),
+ _packetLoss(0),
+ _useFECTestWithPacketLoss(false),
+ _beginTime(rtc::TimeMillis()),
+ _totalBytes(0),
+ external_send_timestamp_(-1),
+ external_sequence_number_(-1),
+ num_packets_to_drop_(0) {
+ int n;
+ int k;
+ for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
+ _payloadStats[n].payloadType = -1;
+ _payloadStats[n].newPacket = true;
+ for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
+ _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
+ _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
+ _payloadStats[n].frameSizeStats[k].numPackets = 0;
+ _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
+ _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
+ }
+ }
+ if (chID >= 0) {
+ _saveBitStream = true;
+ rtc::StringBuilder ss;
+ ss.AppendFormat("bitStream_%d.dat", chID);
+ _bitStreamFile = fopen(ss.str().c_str(), "wb");
+ } else {
+ _saveBitStream = false;
+ }
+}
+
+Channel::~Channel() {}
+
+void Channel::RegisterReceiverACM(AudioCodingModule* acm) {
+ _receiverACM = acm;
+ return;
+}
+
+void Channel::ResetStats() {
+ int n;
+ int k;
+ _channelCritSect.Lock();
+ _lastPayloadType = -1;
+ for (n = 0; n < MAX_NUM_PAYLOADS; n++) {
+ _payloadStats[n].payloadType = -1;
+ _payloadStats[n].newPacket = true;
+ for (k = 0; k < MAX_NUM_FRAMESIZES; k++) {
+ _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
+ _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0;
+ _payloadStats[n].frameSizeStats[k].numPackets = 0;
+ _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
+ _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
+ }
+ }
+ _beginTime = rtc::TimeMillis();
+ _totalBytes = 0;
+ _channelCritSect.Unlock();
+}
+
+uint32_t Channel::LastInTimestamp() {
+ uint32_t timestamp;
+ _channelCritSect.Lock();
+ timestamp = _lastInTimestamp;
+ _channelCritSect.Unlock();
+ return timestamp;
+}
+
+double Channel::BitRate() {
+ double rate;
+ uint64_t currTime = rtc::TimeMillis();
+ _channelCritSect.Lock();
+ rate = ((double)_totalBytes * 8.0) / (double)(currTime - _beginTime);
+ _channelCritSect.Unlock();
+ return rate;
+}
+
+} // namespace webrtc