diff options
author | Chih-hung Hsieh <chh@google.com> | 2016-01-20 17:50:13 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-01-20 17:50:13 +0000 |
commit | b3cb8ab4ede8bb77f0bdef2715efc2c1e6267072 (patch) | |
tree | 28c4cf735dd5bd9cc8f1ccd06fff8a173b20d1cb /webrtc/modules/audio_coding/test/Channel.cc | |
parent | a4acd9d6bc9b3b033d7d274316e75ee067df8d20 (diff) | |
parent | 9a337512d97e37afc142dee4fd50a41b741a87d2 (diff) | |
download | webrtc-b3cb8ab4ede8bb77f0bdef2715efc2c1e6267072.tar.gz |
Merge "Merge upstream SHA 04cb763"android-cts_7.1_r1android-cts-7.1_r9android-cts-7.1_r8android-cts-7.1_r7android-cts-7.1_r6android-cts-7.1_r5android-cts-7.1_r4android-cts-7.1_r3android-cts-7.1_r29android-cts-7.1_r28android-cts-7.1_r27android-cts-7.1_r26android-cts-7.1_r25android-cts-7.1_r24android-cts-7.1_r23android-cts-7.1_r22android-cts-7.1_r21android-cts-7.1_r20android-cts-7.1_r2android-cts-7.1_r19android-cts-7.1_r18android-cts-7.1_r17android-cts-7.1_r16android-cts-7.1_r15android-cts-7.1_r14android-cts-7.1_r13android-cts-7.1_r12android-cts-7.1_r11android-cts-7.1_r10android-cts-7.1_r1android-cts-7.0_r9android-cts-7.0_r8android-cts-7.0_r7android-cts-7.0_r6android-cts-7.0_r5android-cts-7.0_r4android-cts-7.0_r33android-cts-7.0_r32android-cts-7.0_r31android-cts-7.0_r30android-cts-7.0_r3android-cts-7.0_r29android-cts-7.0_r28android-cts-7.0_r27android-cts-7.0_r26android-cts-7.0_r25android-cts-7.0_r24android-cts-7.0_r23android-cts-7.0_r22android-cts-7.0_r21android-cts-7.0_r20android-cts-7.0_r2android-cts-7.0_r19android-cts-7.0_r18android-cts-7.0_r17android-cts-7.0_r16android-cts-7.0_r15android-cts-7.0_r14android-cts-7.0_r13android-cts-7.0_r12android-cts-7.0_r11android-cts-7.0_r10android-cts-7.0_r1android-7.1.2_r9android-7.1.2_r8android-7.1.2_r6android-7.1.2_r5android-7.1.2_r4android-7.1.2_r39android-7.1.2_r38android-7.1.2_r37android-7.1.2_r36android-7.1.2_r33android-7.1.2_r32android-7.1.2_r30android-7.1.2_r3android-7.1.2_r29android-7.1.2_r28android-7.1.2_r27android-7.1.2_r25android-7.1.2_r24android-7.1.2_r23android-7.1.2_r2android-7.1.2_r19android-7.1.2_r18android-7.1.2_r17android-7.1.2_r16android-7.1.2_r15android-7.1.2_r14android-7.1.2_r13android-7.1.2_r12android-7.1.2_r11android-7.1.2_r10android-7.1.2_r1android-7.1.1_r9android-7.1.1_r8android-7.1.1_r7android-7.1.1_r61android-7.1.1_r60android-7.1.1_r6android-7.1.1_r59android-7.1.1_r58android-7.1.1_r57android-7.1.1_r56android-7.1.1_r55android-7.1.1_r54android-7.1.1_r53android-7.1.1_r52android-7.1.1_r51android-7.1.1_r50android-7.1.1_r49android-7.1.1_r48android-7.1.1_r47android-7.1.1_r46android-7.1.1_r45android-7.1.1_r44android-7.1.1_r43android-7.1.1_r42android-7.1.1_r41android-7.1.1_r40android-7.1.1_r4android-7.1.1_r39android-7.1.1_r38android-7.1.1_r35android-7.1.1_r33android-7.1.1_r32android-7.1.1_r31android-7.1.1_r3android-7.1.1_r28android-7.1.1_r27android-7.1.1_r26android-7.1.1_r25android-7.1.1_r24android-7.1.1_r23android-7.1.1_r22android-7.1.1_r21android-7.1.1_r20android-7.1.1_r2android-7.1.1_r17android-7.1.1_r16android-7.1.1_r15android-7.1.1_r14android-7.1.1_r13android-7.1.1_r12android-7.1.1_r11android-7.1.1_r10android-7.1.1_r1android-7.1.0_r7android-7.1.0_r6android-7.1.0_r5android-7.1.0_r4android-7.1.0_r3android-7.1.0_r2android-7.1.0_r1android-7.0.0_r9android-7.0.0_r8android-7.0.0_r7android-7.0.0_r6android-7.0.0_r5android-7.0.0_r4android-7.0.0_r36android-7.0.0_r35android-7.0.0_r34android-7.0.0_r33android-7.0.0_r32android-7.0.0_r31android-7.0.0_r30android-7.0.0_r3android-7.0.0_r29android-7.0.0_r28android-7.0.0_r27android-7.0.0_r24android-7.0.0_r21android-7.0.0_r19android-7.0.0_r17android-7.0.0_r15android-7.0.0_r14android-7.0.0_r13android-7.0.0_r12android-7.0.0_r11android-7.0.0_r10android-7.0.0_r1nougat-releasenougat-mr2.3-releasenougat-mr2.2-releasenougat-mr2.1-releasenougat-mr2-security-releasenougat-mr2-releasenougat-mr2-pixel-releasenougat-mr2-devnougat-mr1.8-releasenougat-mr1.7-releasenougat-mr1.6-releasenougat-mr1.5-releasenougat-mr1.4-releasenougat-mr1.3-releasenougat-mr1.2-releasenougat-mr1.1-releasenougat-mr1-volantis-releasenougat-mr1-security-releasenougat-mr1-releasenougat-mr1-flounder-releasenougat-mr1-devnougat-mr1-cts-releasenougat-mr0.5-releasenougat-dr1-releasenougat-devnougat-cts-releasenougat-bugfix-release
am: 9a337512d9
* commit '9a337512d97e37afc142dee4fd50a41b741a87d2': (797 commits)
Add tests for verifying transport feedback for audio and video.
Eliminate defines in talk/
Revert of Update with new default boringssl no-aes cipher suites. Re-enable tests. (patchset #3 id:40001 of https://codereview.webrtc.org/1550773002/ )
Remove assert which was incorrectly added to TcpPort::OnSentPacket.
Reland Connect TurnPort and TCPPort to AsyncPacketSocket::SignalSentPacket.
Update with new default boringssl no-aes cipher suites. Re-enable tests.
Revert of Connect TurnPort and TCPPort to AsyncPacketSocket::SignalSentPacket. (patchset #3 id:40001 of https://codereview.webrtc.org/1577873003/ )
Re-land: "Use an explicit identifier in Config"
Connect TurnPort and TCPPort to AsyncPacketSocket::SignalSentPacket.
Revert of Delete remnants of non-square pixel support from cricket::VideoFrame. (patchset #1 id:1 of https://codereview.webrtc.org/1586613002/ )
Remove libfuzzer trybot from default trybot set.
Add ramp-up tests for transport sequence number with and w/o audio.
Delete remnants of non-square pixel support from cricket::VideoFrame.
Fix IPAddress::ToSensitiveString() to avoid dependency on inet_ntop().
Revert of Storing raw audio sink for default audio track. (patchset #7 id:120001 of https://codereview.chromium.org/1551813002/ )
Re-enable tests that failed under Linux_Msan.
Revert of Use an explicit identifier in Config (patchset #4 id:60001 of https://codereview.webrtc.org/1538643004/ )
Roll chromium_revision 346fea9..099be58 (369082:369139)
Disable WebRtcVideoChannel2BaseTest.SendManyResizeOnce for TSan
Add build_protobuf variable.
...
Diffstat (limited to 'webrtc/modules/audio_coding/test/Channel.cc')
-rw-r--r-- | webrtc/modules/audio_coding/test/Channel.cc | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/webrtc/modules/audio_coding/test/Channel.cc b/webrtc/modules/audio_coding/test/Channel.cc new file mode 100644 index 0000000000..31521fe1e3 --- /dev/null +++ b/webrtc/modules/audio_coding/test/Channel.cc @@ -0,0 +1,424 @@ +/* + * 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 "webrtc/modules/audio_coding/test/Channel.h" + +#include <assert.h> +#include <iostream> + +#include "webrtc/base/format_macros.h" +#include "webrtc/system_wrappers/include/tick_util.h" +#include "webrtc/system_wrappers/include/critical_section_wrapper.h" + +namespace webrtc { + +int32_t Channel::SendData(FrameType frameType, + uint8_t payloadType, + uint32_t timeStamp, + const uint8_t* payloadData, + size_t payloadSize, + const RTPFragmentationHeader* fragmentation) { + WebRtcRTPHeader rtpInfo; + int32_t status; + size_t payloadDataSize = payloadSize; + + rtpInfo.header.markerBit = false; + rtpInfo.header.ssrc = 0; + rtpInfo.header.sequenceNumber = (external_sequence_number_ < 0) ? + _seqNo++ : static_cast<uint16_t>(external_sequence_number_); + rtpInfo.header.payloadType = payloadType; + rtpInfo.header.timestamp = (external_send_timestamp_ < 0) ? timeStamp : + static_cast<uint32_t>(external_send_timestamp_); + + if (frameType == kAudioFrameCN) { + rtpInfo.type.Audio.isCNG = true; + } else { + rtpInfo.type.Audio.isCNG = false; + } + if (frameType == 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; + } + + rtpInfo.type.Audio.channel = 1; + // Treat fragmentation separately + if (fragmentation != NULL) { + // If silence for too long, send only new data. + if ((fragmentation->fragmentationVectorSize == 2) && + (fragmentation->fragmentationTimeDiff[1] <= 0x3fff)) { + // only 0x80 if we have multiple blocks + _payloadData[0] = 0x80 + fragmentation->fragmentationPlType[1]; + size_t REDheader = (fragmentation->fragmentationTimeDiff[1] << 10) + + fragmentation->fragmentationLength[1]; + _payloadData[1] = uint8_t((REDheader >> 16) & 0x000000FF); + _payloadData[2] = uint8_t((REDheader >> 8) & 0x000000FF); + _payloadData[3] = uint8_t(REDheader & 0x000000FF); + + _payloadData[4] = fragmentation->fragmentationPlType[0]; + // copy the RED data + memcpy(_payloadData + 5, + payloadData + fragmentation->fragmentationOffset[1], + fragmentation->fragmentationLength[1]); + // copy the normal data + memcpy(_payloadData + 5 + fragmentation->fragmentationLength[1], + payloadData + fragmentation->fragmentationOffset[0], + fragmentation->fragmentationLength[0]); + payloadDataSize += 5; + } else { + // single block (newest one) + memcpy(_payloadData, payloadData + fragmentation->fragmentationOffset[0], + fragmentation->fragmentationLength[0]); + payloadDataSize = fragmentation->fragmentationLength[0]; + rtpInfo.header.payloadType = fragmentation->fragmentationPlType[0]; + } + } else { + memcpy(_payloadData, payloadData, payloadDataSize); + if (_isStereo) { + if (_leftChannel) { + memcpy(&_rtpInfo, &rtpInfo, sizeof(WebRtcRTPHeader)); + _leftChannel = false; + rtpInfo.type.Audio.channel = 1; + } else { + memcpy(&rtpInfo, &_rtpInfo, sizeof(WebRtcRTPHeader)); + _leftChannel = true; + rtpInfo.type.Audio.channel = 2; + } + } + } + + _channelCritSect->Enter(); + if (_saveBitStream) { + //fwrite(payloadData, sizeof(uint8_t), payloadSize, _bitStreamFile); + } + + if (!_isStereo) { + CalcStatistics(rtpInfo, payloadSize); + } + _useLastFrameSize = false; + _lastInTimestamp = timeStamp; + _totalBytes += payloadDataSize; + _channelCritSect->Leave(); + + 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, rtpInfo); + + return status; +} + +// TODO(turajs): rewite this method. +void Channel::CalcStatistics(WebRtcRTPHeader& rtpInfo, size_t payloadSize) { + int n; + if ((rtpInfo.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 = rtpInfo.header.payloadType; + + bool newPayload = true; + ACMTestPayloadStats* currentPayloadStr = NULL; + for (n = 0; n < MAX_NUM_PAYLOADS; n++) { + if (rtpInfo.header.payloadType == _payloadStats[n].payloadType) { + newPayload = false; + currentPayloadStr = &_payloadStats[n]; + break; + } + } + + if (!newPayload) { + if (!currentPayloadStr->newPacket) { + if (!_useLastFrameSize) { + _lastFrameSizeSample = (uint32_t) ((uint32_t) rtpInfo.header.timestamp - + (uint32_t) currentPayloadStr->lastTimestamp); + } + assert(_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 = rtpInfo.header.timestamp; + currentPayloadStr->lastPayloadLenByte = payloadSize; + } else { + currentPayloadStr->newPacket = false; + currentPayloadStr->lastPayloadLenByte = payloadSize; + currentPayloadStr->lastTimestamp = rtpInfo.header.timestamp; + currentPayloadStr->payloadType = rtpInfo.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 = rtpInfo.header.timestamp; + _payloadStats[n].payloadType = rtpInfo.header.payloadType; + memset(_payloadStats[n].frameSizeStats, 0, MAX_NUM_FRAMESIZES * + sizeof(ACMTestFrameSizeStats)); + } +} + +Channel::Channel(int16_t chID) + : _receiverACM(NULL), + _seqNo(0), + _channelCritSect(CriticalSectionWrapper::CreateCriticalSection()), + _bitStreamFile(NULL), + _saveBitStream(false), + _lastPayloadType(-1), + _isStereo(false), + _leftChannel(true), + _lastInTimestamp(0), + _useLastFrameSize(false), + _lastFrameSizeSample(0), + _packetLoss(0), + _useFECTestWithPacketLoss(false), + _beginTime(TickTime::MillisecondTimestamp()), + _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; + char bitStreamFileName[500]; + sprintf(bitStreamFileName, "bitStream_%d.dat", chID); + _bitStreamFile = fopen(bitStreamFileName, "wb"); + } else { + _saveBitStream = false; + } +} + +Channel::~Channel() { + delete _channelCritSect; +} + +void Channel::RegisterReceiverACM(AudioCodingModule* acm) { + _receiverACM = acm; + return; +} + +void Channel::ResetStats() { + int n; + int k; + _channelCritSect->Enter(); + _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 = TickTime::MillisecondTimestamp(); + _totalBytes = 0; + _channelCritSect->Leave(); +} + +int16_t Channel::Stats(CodecInst& codecInst, + ACMTestPayloadStats& payloadStats) { + _channelCritSect->Enter(); + int n; + payloadStats.payloadType = -1; + for (n = 0; n < MAX_NUM_PAYLOADS; n++) { + if (_payloadStats[n].payloadType == codecInst.pltype) { + memcpy(&payloadStats, &_payloadStats[n], sizeof(ACMTestPayloadStats)); + break; + } + } + if (payloadStats.payloadType == -1) { + _channelCritSect->Leave(); + return -1; + } + for (n = 0; n < MAX_NUM_FRAMESIZES; n++) { + if (payloadStats.frameSizeStats[n].frameSizeSample == 0) { + _channelCritSect->Leave(); + return 0; + } + payloadStats.frameSizeStats[n].usageLenSec = (double) payloadStats + .frameSizeStats[n].totalEncodedSamples / (double) codecInst.plfreq; + + payloadStats.frameSizeStats[n].rateBitPerSec = + payloadStats.frameSizeStats[n].totalPayloadLenByte * 8 + / payloadStats.frameSizeStats[n].usageLenSec; + + } + _channelCritSect->Leave(); + return 0; +} + +void Channel::Stats(uint32_t* numPackets) { + _channelCritSect->Enter(); + int k; + int n; + memset(numPackets, 0, MAX_NUM_PAYLOADS * sizeof(uint32_t)); + for (k = 0; k < MAX_NUM_PAYLOADS; k++) { + if (_payloadStats[k].payloadType == -1) { + break; + } + numPackets[k] = 0; + for (n = 0; n < MAX_NUM_FRAMESIZES; n++) { + if (_payloadStats[k].frameSizeStats[n].frameSizeSample == 0) { + break; + } + numPackets[k] += _payloadStats[k].frameSizeStats[n].numPackets; + } + } + _channelCritSect->Leave(); +} + +void Channel::Stats(uint8_t* payloadType, uint32_t* payloadLenByte) { + _channelCritSect->Enter(); + + int k; + int n; + memset(payloadLenByte, 0, MAX_NUM_PAYLOADS * sizeof(uint32_t)); + for (k = 0; k < MAX_NUM_PAYLOADS; k++) { + if (_payloadStats[k].payloadType == -1) { + break; + } + payloadType[k] = (uint8_t) _payloadStats[k].payloadType; + payloadLenByte[k] = 0; + for (n = 0; n < MAX_NUM_FRAMESIZES; n++) { + if (_payloadStats[k].frameSizeStats[n].frameSizeSample == 0) { + break; + } + payloadLenByte[k] += (uint16_t) _payloadStats[k].frameSizeStats[n] + .totalPayloadLenByte; + } + } + + _channelCritSect->Leave(); +} + +void Channel::PrintStats(CodecInst& codecInst) { + ACMTestPayloadStats payloadStats; + Stats(codecInst, payloadStats); + printf("%s %d kHz\n", codecInst.plname, codecInst.plfreq / 1000); + printf("=====================================================\n"); + if (payloadStats.payloadType == -1) { + printf("No Packets are sent with payload-type %d (%s)\n\n", + codecInst.pltype, codecInst.plname); + return; + } + for (int k = 0; k < MAX_NUM_FRAMESIZES; k++) { + if (payloadStats.frameSizeStats[k].frameSizeSample == 0) { + break; + } + printf("Frame-size.................... %d samples\n", + payloadStats.frameSizeStats[k].frameSizeSample); + printf("Average Rate.................. %.0f bits/sec\n", + payloadStats.frameSizeStats[k].rateBitPerSec); + printf("Maximum Payload-Size.......... %" PRIuS " Bytes\n", + payloadStats.frameSizeStats[k].maxPayloadLen); + printf( + "Maximum Instantaneous Rate.... %.0f bits/sec\n", + ((double) payloadStats.frameSizeStats[k].maxPayloadLen * 8.0 + * (double) codecInst.plfreq) + / (double) payloadStats.frameSizeStats[k].frameSizeSample); + printf("Number of Packets............. %u\n", + (unsigned int) payloadStats.frameSizeStats[k].numPackets); + printf("Duration...................... %0.3f sec\n\n", + payloadStats.frameSizeStats[k].usageLenSec); + + } + +} + +uint32_t Channel::LastInTimestamp() { + uint32_t timestamp; + _channelCritSect->Enter(); + timestamp = _lastInTimestamp; + _channelCritSect->Leave(); + return timestamp; +} + +double Channel::BitRate() { + double rate; + uint64_t currTime = TickTime::MillisecondTimestamp(); + _channelCritSect->Enter(); + rate = ((double) _totalBytes * 8.0) / (double) (currTime - _beginTime); + _channelCritSect->Leave(); + return rate; +} + +} // namespace webrtc |