| /* |
| * Copyright (c) 2011 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 <cassert> |
| #include <windows.h> |
| #include <iostream> |
| #include <tchar.h> |
| |
| #include "rtp_rtcp.h" |
| #include "common_types.h" |
| #include "rtcp_utility.h" |
| #include "tmmbr_help.h" |
| |
| #define TEST_STR "Test TMMBR." |
| #define TEST_PASSED() std::cerr << TEST_STR << " : [OK]" << std::endl |
| #define PRINT_LINE std::cout << "------------------------------------------" << std::endl; |
| |
| |
| const int maxFileLen = 200; |
| WebRtc_UWord8* dataFile[maxFileLen]; |
| |
| |
| struct InputSet |
| { |
| WebRtc_UWord32 TMMBR; |
| WebRtc_UWord32 packetOH; |
| WebRtc_UWord32 SSRC; |
| }; |
| |
| const InputSet set0 = {220, 80, 11111}; // bitRate, packetOH, ssrc |
| const InputSet set1 = {180, 90, 22222}; |
| const InputSet set2 = {100, 210, 33333}; |
| const InputSet set3 = { 35, 40, 44444}; |
| const InputSet set4 = { 40, 60, 55555}; |
| const InputSet set4_1 = {100, 60, 55555}; |
| const InputSet set4_2 = { 10, 60, 55555}; |
| const InputSet set5 = {200, 40, 66666}; |
| const InputSet set00 = { 0, 40, 66666}; |
| |
| const int maxBitrate = 230; // if this is lower than max in the list above test should fail |
| |
| void Verify(TMMBRSet* boundingSet, int index, InputSet set) |
| { |
| assert(boundingSet->ptrTmmbrSet[index] == set.TMMBR); |
| assert(boundingSet->ptrPacketOHSet[index] == set.packetOH); |
| assert(boundingSet->ptrSsrcSet[index] == set.SSRC); |
| }; |
| |
| int ParseRTCPPacket(const void *data, int len, TMMBRSet*& boundingSet) |
| { |
| int numItems = -1; |
| RTCPUtility::RTCPParserV2 rtcpParser((const WebRtc_UWord8*)data, len, true); |
| RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Begin(); |
| while (pktType != RTCPUtility::kRtcpNotValidCode) |
| { |
| const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet(); |
| if (pktType == RTCPUtility::kRtcpRtpfbTmmbnCode) |
| { |
| assert(0 == rtcpPacket.TMMBN.SenderSSRC); |
| assert(0 == rtcpPacket.TMMBN.MediaSSRC); |
| numItems = 0; |
| } |
| if (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode) |
| { |
| boundingSet->ptrTmmbrSet[numItems] = rtcpPacket.TMMBNItem.MaxTotalMediaBitRate; |
| boundingSet->ptrPacketOHSet[numItems] = rtcpPacket.TMMBNItem.MeasuredOverhead; |
| boundingSet->ptrSsrcSet[numItems] = rtcpPacket.TMMBNItem.SSRC; |
| ++numItems; |
| } |
| pktType = rtcpParser.Iterate(); |
| } |
| return numItems; |
| }; |
| |
| WebRtc_Word32 GetFile(char* fileName) |
| { |
| if (!fileName[0]) |
| { |
| return 0; |
| } |
| |
| FILE* openFile = fopen(fileName, "rb"); |
| assert(openFile != NULL); |
| fseek(openFile, 0, SEEK_END); |
| int len = (WebRtc_Word16)(ftell(openFile)); |
| rewind(openFile); |
| assert(len > 0 && len < maxFileLen); |
| fread(dataFile, 1, len, openFile); |
| fclose(openFile); |
| return len; |
| }; |
| |
| |
| class LoopBackTransport2 : public webrtc::Transport, private TMMBRHelp |
| { |
| public: |
| LoopBackTransport2(RtpRtcp* rtpRtcpModule) : |
| TMMBRHelp(false), |
| _rtpRtcpModule(rtpRtcpModule), |
| _cnt(0) |
| { |
| } |
| virtual int SendPacket(int channel, const void *data, int len) |
| { |
| if( 0 == _rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)data, len)) |
| { |
| return len; |
| } |
| return -1; |
| } |
| virtual int SendRTCPPacket(int channel, const void *data, int len) |
| { |
| char fileName[256] = {0}; |
| TMMBRSet* boundingSet = BoundingSet(); |
| boundingSet->VerifyAndAllocateSet(3); |
| |
| if (_cnt == 0) |
| { |
| // TMMBN {} |
| // TMMBN {} |
| // TMMBN {} |
| // TMMBN {2,4,0} -> {4,2} |
| assert(2 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set4); |
| Verify(boundingSet, 1, set2); |
| |
| strcpy(fileName, "RTCPPacketTMMBR3.bin"); |
| } |
| |
| ++_cnt; |
| |
| // Get stored rtcp packet w/ TMMBR |
| len = GetFile(fileName); |
| if (len == 0) |
| { |
| return 1; |
| } |
| |
| // Send in bitrate request |
| if(_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)dataFile, len) == 0) |
| { |
| return len; |
| } |
| return -1; |
| } |
| RtpRtcp* _rtpRtcpModule; |
| WebRtc_UWord32 _cnt; |
| }; |
| |
| |
| class LoopBackTransportVideo : public webrtc::Transport, private TMMBRHelp |
| { |
| public: |
| LoopBackTransportVideo(RtpRtcp* rtpRtcpModule) : |
| TMMBRHelp(false), |
| _rtpRtcpModule(rtpRtcpModule), |
| _cnt(0) |
| { |
| } |
| virtual int SendPacket(int channel, const void *data, int len) |
| { |
| if(_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)data, len)== 0) |
| { |
| return len; |
| } |
| return -1; |
| } |
| virtual int SendRTCPPacket(int channel, const void *data, int len) |
| { |
| char fileName[256] = {0}; |
| TMMBRSet* boundingSet = BoundingSet(); |
| boundingSet->VerifyAndAllocateSet(3); |
| |
| if (_cnt == 0) |
| { |
| strcpy(fileName, "RTCPPacketTMMBR0.bin"); |
| } |
| else if (_cnt == 1) |
| { |
| // TMMBN {0} -> {0} |
| assert(1 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set0); |
| |
| strcpy(fileName, "RTCPPacketTMMBR1.bin"); |
| } |
| else if (_cnt == 2) |
| { |
| // TMMBN {0,1} -> {1} |
| assert(1 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set1); |
| |
| strcpy(fileName, "RTCPPacketTMMBR2.bin"); |
| } |
| else if (_cnt == 3) |
| { |
| // TMMBN {0,1,2} -> {2} |
| assert(1 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set2); |
| |
| strcpy(fileName, "RTCPPacketTMMBR3.bin"); |
| } |
| else if (_cnt == 4) |
| { |
| // TMMBN {0,1,2,3} -> {3,2} |
| assert(2 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set2); |
| |
| strcpy(fileName, "RTCPPacketTMMBR4.bin"); |
| } |
| else if (_cnt == 5) |
| { |
| // TMMBN {0,1,2,3,4} -> {3,4,2} |
| assert(3 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set4); |
| Verify(boundingSet, 2, set2); |
| |
| strcpy(fileName, "RTCPPacketTMMBR5.bin"); |
| } |
| else if (_cnt == 6) |
| { |
| // TMMBN {0,1,2,3,4,5} -> {3,4,2} |
| assert(3 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set4); |
| Verify(boundingSet, 2, set2); |
| |
| strcpy(fileName, "RTCPPacketTMMBR4_2.bin"); |
| } |
| else if (_cnt == 7) |
| { |
| // TMMBN {0,1,2,3,4_2,5} -> {4_2} |
| assert(1 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set4_2); |
| |
| ++_cnt; |
| ::Sleep(5*RTCP_INTERVAL_AUDIO_MS + 1000); // time out receiver |
| _rtpRtcpModule->Process(); // SendRTCP() (_cnt == 8) |
| // a receiver has timed out -> UpdateTMMBR() |
| } |
| else if (_cnt == 8) |
| { |
| // No TMMBN in this packet |
| assert(-1 == ParseRTCPPacket(data, len, boundingSet)); |
| } |
| else if (_cnt == 10) |
| { |
| // TMMBN {} -> {}, empty set |
| assert(0 == ParseRTCPPacket(data, len, boundingSet)); |
| |
| strcpy(fileName, "RTCPPacketTMMBR2.bin"); |
| } |
| else if (_cnt == 11) |
| { |
| // TMMBN {2} -> {2} |
| assert(1 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set2); |
| } |
| else if (_cnt == 12) // ----- multi module ------------- |
| { |
| // No TMMBN in this packet |
| assert(-1 == ParseRTCPPacket(data, len, boundingSet)); |
| |
| strcpy(fileName, "RTCPPacketTMMBR4.bin"); |
| } |
| else if (_cnt == 13) |
| { |
| // TMMBN {} |
| // TMMBN {} |
| // TMMBN {} |
| // TMMBN {2,4} -> {4,2} |
| assert(2 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set4); |
| Verify(boundingSet, 1, set2); |
| |
| strcpy(fileName, "RTCPPacketTMMBR0.bin"); |
| } |
| else if (_cnt == 14) |
| { |
| // TMMBN {} |
| // TMMBN {3} |
| // TMMBN {} |
| // TMMBN {2,4,0} -> {3,4,2} |
| assert(3 == ParseRTCPPacket(data, len, boundingSet)); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set4); |
| Verify(boundingSet, 2, set2); |
| |
| strcpy(fileName, "RTCPPacketTMMBR1.bin"); |
| } |
| //else if (_cnt == 15) |
| //{ |
| // // TMMBN {} |
| // // TMMBN {} |
| // // TMMBN {} |
| // // TMMBN {2,4,0,1} -> {4,2} |
| // //assert(2 == ParseRTCPPacket(data, len, boundingSet)); |
| // //Verify(boundingSet, 0, set4); |
| // //Verify(boundingSet, 1, set2); |
| //} |
| //else if (_cnt == 15) |
| //{ |
| // // No TMMBN in this packet |
| // assert(-1 == ParseRTCPPacket(data, len, boundingSet)); |
| //} |
| else if (_cnt == 15) |
| { |
| // TMMBN {} |
| // TMMBN {} |
| // TMMBN {} |
| // TMMBN {} -> {}, empty set |
| assert(0 == ParseRTCPPacket(data, len, boundingSet)); |
| } |
| |
| ++_cnt; |
| |
| // Get stored rtcp packet w/ TMMBR |
| len = GetFile(fileName); |
| if (len == 0) |
| { |
| return 1; |
| } |
| |
| // Send in bitrate request |
| if( 0 == _rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)dataFile, len)) |
| { |
| return len; |
| } |
| return -1; |
| } |
| |
| RtpRtcp* _rtpRtcpModule; |
| WebRtc_UWord32 _cnt; |
| }; |
| |
| class TestTMMBR : private TMMBRHelp |
| { |
| public: |
| TestTMMBR() : TMMBRHelp(false) {}; |
| |
| void Add(TMMBRSet* candidateSet, int index, InputSet set) |
| { |
| candidateSet->ptrTmmbrSet[index] = set.TMMBR; |
| candidateSet->ptrPacketOHSet[index] = set.packetOH; |
| candidateSet->ptrSsrcSet[index] = set.SSRC; |
| }; |
| |
| void Start() |
| { |
| // Get sets |
| TMMBRSet* candidateSet = CandidateSet(); |
| assert(0 == candidateSet->sizeOfSet); |
| TMMBRSet* boundingSet = BoundingSet(); |
| assert(0 == boundingSet->sizeOfSet); |
| TMMBRSet* boundingSetToSend = BoundingSetToSend(); |
| assert(0 == boundingSetToSend->sizeOfSet); |
| |
| WebRtc_Word32 numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(0 == numBoundingSet); // should be empty |
| |
| assert( 0 == SetTMMBRBoundingSetToSend(NULL,0)); // ok to send empty set |
| assert( 0 == SetTMMBRBoundingSetToSend(boundingSet,0)); // ok to send empty set |
| |
| WebRtc_UWord32 minBitrateKbit = 0; |
| WebRtc_UWord32 maxBitrateKbit = 0; |
| assert(-1 == CalcMinMaxBitRate(0, 0, 1, false, minBitrateKbit, maxBitrateKbit)); // no bounding set |
| |
| // --------------------------------- |
| // Test candidate set {0} -> {0} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(1); |
| assert(1 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set0); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(1 == numBoundingSet); |
| Verify(boundingSet, 0, set0); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, 0)); // incorrect length |
| assert(!IsOwner(set1.SSRC, 100)); // incorrect length |
| |
| assert( IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert(!IsOwner(set2.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| assert(boundingSetToSend->sizeOfSet == numBoundingSet); |
| Verify(boundingSetToSend, 0, set0); |
| |
| // Get net bitrate depending on packet rate |
| assert( 0 == CalcMinMaxBitRate(0, numBoundingSet, false,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set0.TMMBR == minBitrateKbit); |
| assert(set0.TMMBR == maxBitrateKbit); |
| assert(0 == CalcMinMaxBitRate(0, 100, false,0, minBitrateKbit, maxBitrateKbit)); // incorrect length |
| assert(set0.TMMBR == minBitrateKbit); |
| assert(set0.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {0,1} -> {1} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(2); |
| assert(2 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set0); |
| Add(candidateSet, 1, set1); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(1 == numBoundingSet); |
| Verify(boundingSet, 0, set1); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert( IsOwner(set1.SSRC, numBoundingSet)); |
| assert(!IsOwner(set2.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| assert(boundingSetToSend->sizeOfSet == numBoundingSet); |
| Verify(boundingSetToSend, 0, set1); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set1.TMMBR == minBitrateKbit); |
| assert(set0.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {0,1,2} -> {2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(3); |
| assert(3 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set0); |
| Add(candidateSet, 1, set1); |
| Add(candidateSet, 2, set2); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(1 == numBoundingSet); |
| Verify(boundingSet, 0, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| assert(boundingSetToSend->sizeOfSet == numBoundingSet); |
| Verify(boundingSetToSend, 0, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set2.TMMBR == minBitrateKbit); |
| assert(set0.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {0,1,2,3} -> {3,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(4); |
| assert(4 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set0); |
| Add(candidateSet, 1, set1); |
| Add(candidateSet, 2, set2); |
| Add(candidateSet, 3, set3); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(2 == numBoundingSet); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert( IsOwner(set3.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| assert(boundingSetToSend->sizeOfSet == numBoundingSet); |
| Verify(boundingSetToSend, 0, set3); |
| Verify(boundingSetToSend, 1, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set3.TMMBR == minBitrateKbit); |
| assert(set0.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {0,1,2,3,4} -> {3,4,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(5); |
| assert(5 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set0); |
| Add(candidateSet, 1, set1); |
| Add(candidateSet, 2, set2); |
| Add(candidateSet, 3, set3); |
| Add(candidateSet, 4, set4); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(3 == numBoundingSet); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set4); |
| Verify(boundingSet, 2, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert( IsOwner(set3.SSRC, numBoundingSet)); |
| assert( IsOwner(set4.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| assert(boundingSetToSend->sizeOfSet == numBoundingSet); |
| Verify(boundingSetToSend, 0, set3); |
| Verify(boundingSetToSend, 1, set4); |
| Verify(boundingSetToSend, 2, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0,numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set3.TMMBR == minBitrateKbit); |
| assert(set0.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {0,1,2,3,4,5} -> {3,4,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(6); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set0); |
| Add(candidateSet, 1, set1); |
| Add(candidateSet, 2, set2); |
| Add(candidateSet, 3, set3); |
| Add(candidateSet, 4, set4); |
| Add(candidateSet, 5, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(3 == numBoundingSet); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set4); |
| Verify(boundingSet, 2, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert( IsOwner(set3.SSRC, numBoundingSet)); |
| assert( IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| assert(boundingSetToSend->sizeOfSet == numBoundingSet); |
| Verify(boundingSetToSend, 0, set3); |
| Verify(boundingSetToSend, 1, set4); |
| Verify(boundingSetToSend, 2, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0,numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set3.TMMBR == minBitrateKbit); |
| assert(set0.TMMBR == maxBitrateKbit); |
| |
| |
| // --------------------------------- |
| // Test candidate set {1,2,3,4,5} -> {3,4,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(5); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set1); |
| Add(candidateSet, 1, set2); |
| Add(candidateSet, 2, set3); |
| Add(candidateSet, 3, set4); |
| Add(candidateSet, 4, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(3 == numBoundingSet); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set4); |
| Verify(boundingSet, 2, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert( IsOwner(set3.SSRC, numBoundingSet)); |
| assert( IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| assert(boundingSetToSend->sizeOfSet == numBoundingSet); |
| Verify(boundingSetToSend, 0, set3); |
| Verify(boundingSetToSend, 1, set4); |
| Verify(boundingSetToSend, 2, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0,numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set3.TMMBR == minBitrateKbit); |
| assert(set5.TMMBR == maxBitrateKbit); |
| |
| |
| // --------------------------------- |
| // Test candidate set {1,3,4,5} -> {3,4} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(4); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set1); |
| Add(candidateSet, 1, set3); |
| Add(candidateSet, 2, set4); |
| Add(candidateSet, 3, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(2 == numBoundingSet); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set4); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert(!IsOwner(set2.SSRC, numBoundingSet)); |
| assert( IsOwner(set3.SSRC, numBoundingSet)); |
| assert( IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| Verify(boundingSetToSend, 0, set3); |
| Verify(boundingSetToSend, 1, set4); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet,true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set3.TMMBR == minBitrateKbit); |
| assert(set5.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {1,2,4,5} -> {4,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(4); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set1); |
| Add(candidateSet, 1, set2); |
| Add(candidateSet, 2, set4); |
| Add(candidateSet, 3, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(2 == numBoundingSet); |
| Verify(boundingSet, 0, set4); |
| Verify(boundingSet, 1, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert(!IsOwner(set3.SSRC, numBoundingSet)); |
| assert( IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| Verify(boundingSetToSend, 0, set4); |
| Verify(boundingSetToSend, 1, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set4.TMMBR == minBitrateKbit); |
| assert(set5.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {1,2,3,5} -> {3,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(4); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set1); |
| Add(candidateSet, 1, set2); |
| Add(candidateSet, 2, set3); |
| Add(candidateSet, 3, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(2 == numBoundingSet); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert( IsOwner(set3.SSRC, numBoundingSet)); |
| assert(!IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| Verify(boundingSetToSend, 0, set3); |
| Verify(boundingSetToSend, 1, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set3.TMMBR == minBitrateKbit); |
| assert(set5.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {1,2,3,4_1,5} -> {3,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(5); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set1); |
| Add(candidateSet, 1, set2); |
| Add(candidateSet, 2, set3); |
| Add(candidateSet, 3, set4_1); |
| Add(candidateSet, 4, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(2 == numBoundingSet); |
| Verify(boundingSet, 0, set3); |
| Verify(boundingSet, 1, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert( IsOwner(set3.SSRC, numBoundingSet)); |
| assert(!IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| Verify(boundingSetToSend, 0, set3); |
| Verify(boundingSetToSend, 1, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set3.TMMBR == minBitrateKbit); |
| assert(set5.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {1,2,3,4_2,5} -> {4_2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(5); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set1); |
| Add(candidateSet, 1, set2); |
| Add(candidateSet, 2, set3); |
| Add(candidateSet, 3, set4_2); |
| Add(candidateSet, 4, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(1 == numBoundingSet); |
| Verify(boundingSet, 0, set4_2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert(!IsOwner(set2.SSRC, numBoundingSet)); |
| assert(!IsOwner(set3.SSRC, numBoundingSet)); |
| assert( IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| Verify(boundingSetToSend, 0, set4_2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0, numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(MIN_VIDEO_BW_MANAGEMENT_BITRATE == minBitrateKbit); |
| assert(set5.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {} -> {} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(0); |
| assert(6 == candidateSet->sizeOfSet); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(0 == numBoundingSet); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert(!IsOwner(set2.SSRC, numBoundingSet)); |
| assert(!IsOwner(set3.SSRC, numBoundingSet)); |
| assert(!IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| |
| // Get net bitrate depending on packet rate |
| assert(-1 == CalcMinMaxBitRate(0,numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| |
| // --------------------------------- |
| // Test candidate set {x0,5} -> {5} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(2); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set00); |
| Add(candidateSet, 1, set5); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(1 == numBoundingSet); |
| Verify(boundingSet, 0, set5); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert(!IsOwner(set2.SSRC, numBoundingSet)); |
| assert(!IsOwner(set3.SSRC, numBoundingSet)); |
| assert(!IsOwner(set4.SSRC, numBoundingSet)); |
| assert( IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| Verify(boundingSetToSend, 0, set5); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0,numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set5.TMMBR == minBitrateKbit); |
| assert(set5.TMMBR == maxBitrateKbit); |
| |
| // --------------------------------- |
| // Test candidate set {x0,4,2} -> {4,2} |
| // --------------------------------- |
| candidateSet = VerifyAndAllocateCandidateSet(3); |
| assert(6 == candidateSet->sizeOfSet); |
| Add(candidateSet, 0, set00); |
| Add(candidateSet, 1, set4); |
| Add(candidateSet, 2, set2); |
| |
| // Find bounding set |
| numBoundingSet = FindTMMBRBoundingSet(boundingSet); |
| assert(2 == numBoundingSet); |
| Verify(boundingSet, 0, set4); |
| Verify(boundingSet, 1, set2); |
| |
| // Is owner of set |
| assert(!IsOwner(set0.SSRC, numBoundingSet)); |
| assert(!IsOwner(set1.SSRC, numBoundingSet)); |
| assert( IsOwner(set2.SSRC, numBoundingSet)); |
| assert(!IsOwner(set3.SSRC, numBoundingSet)); |
| assert( IsOwner(set4.SSRC, numBoundingSet)); |
| assert(!IsOwner(set5.SSRC, numBoundingSet)); |
| |
| // Set boundingSet to send |
| assert(0 == SetTMMBRBoundingSetToSend(boundingSet, maxBitrate)); |
| |
| // Get boundingSet to send |
| boundingSetToSend = BoundingSetToSend(); |
| Verify(boundingSetToSend, 0, set4); |
| Verify(boundingSetToSend, 1, set2); |
| |
| // Get net bitrate depending on packet rate |
| assert(0 == CalcMinMaxBitRate(0,numBoundingSet, true,0, minBitrateKbit, maxBitrateKbit)); |
| assert(set4.TMMBR == minBitrateKbit); |
| assert(set2.TMMBR == maxBitrateKbit); |
| }; |
| }; |
| |
| class NULLDataZink: public RtpData |
| { |
| virtual WebRtc_Word32 OnReceivedPayloadData(const WebRtc_UWord8* payloadData, |
| const WebRtc_UWord16 payloadSize, |
| const webrtc::WebRtcRTPHeader* rtpHeader, |
| const WebRtc_UWord8* incomingRtpPacket, |
| const WebRtc_UWord16 incomingRtpPacketLengt) |
| { |
| return 0; |
| }; |
| }; |
| |
| |
| int _tmain(int argc, _TCHAR* argv[]) |
| { |
| |
| std::string str; |
| std::cout << "------------------------" << std::endl; |
| std::cout << "------ Test TMMBR ------" << std::endl; |
| std::cout << "------------------------" << std::endl; |
| std::cout << " " << std::endl; |
| |
| // -------------------- |
| // Test TMMBRHelp class |
| // -------------------- |
| TestTMMBR test; |
| test.Start(); |
| |
| printf("TMMBRHelp-class test done.\n"); |
| |
| // ------------------------ |
| // Test TMMBR single module |
| // ------------------------ |
| RtpRtcp* rtpRtcpModuleVideo = RtpRtcp::CreateRtpRtcp(0, false); |
| |
| LoopBackTransportVideo* myLoopBackTransportVideo = new LoopBackTransportVideo(rtpRtcpModuleVideo); |
| assert(0 == rtpRtcpModuleVideo->RegisterSendTransport(myLoopBackTransportVideo)); |
| |
| assert(false == rtpRtcpModuleVideo->TMMBR()); |
| rtpRtcpModuleVideo->SetTMMBRStatus(true); |
| assert(true == rtpRtcpModuleVideo->TMMBR()); |
| |
| assert(0 == rtpRtcpModuleVideo->RegisterSendPayload( "I420", 96)); |
| assert(0 == rtpRtcpModuleVideo->RegisterReceivePayload( "I420", 96)); |
| |
| // send a RTP packet with SSRC 11111 to get 11111 as the received SSRC |
| assert(0 == rtpRtcpModuleVideo->SetSSRC(11111)); |
| const WebRtc_UWord8 testStream[9] = "testtest"; |
| assert(0 == rtpRtcpModuleVideo->RegisterIncomingDataCallback(new NULLDataZink())); // needed to avoid error from parsing the incoming stream |
| assert(0 == rtpRtcpModuleVideo->SendOutgoingData(webrtc::kVideoFrameKey,96, 0, testStream, 8)); |
| |
| // set the SSRC to 0 |
| assert(0 == rtpRtcpModuleVideo->SetSSRC(0)); |
| |
| // |
| assert(0 == rtpRtcpModuleVideo->SetRTCPStatus(kRtcpCompound)); |
| |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {0} // should this make us remember a TMMBR? |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {1}, verify TMMBN {0} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {2}, verify TMMBN {1} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {3}, verify TMMBN {2} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {4}, verify TMMBN {3,2} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {5}, verify TMMBN {3,4,2} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {4_2}, verify TMMBN {3,4,2} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> time out receivers, verify TMMBN {4_2} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {2} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> verify TMMBN {2} |
| |
| printf("Single module test done.\n"); |
| |
| // ------------------------ |
| // Test TMMBR multi module |
| // ------------------------ |
| RtpRtcp* rtpRtcpModuleVideoDef = RtpRtcp::CreateRtpRtcp(10, false); |
| assert(0 == rtpRtcpModuleVideo->RegisterDefaultModule(rtpRtcpModuleVideoDef)); |
| |
| RtpRtcp* rtpRtcpModuleVideo1 = RtpRtcp::CreateRtpRtcp(1, false); |
| assert(0 == rtpRtcpModuleVideo1->RegisterDefaultModule(rtpRtcpModuleVideoDef)); |
| |
| RtpRtcp* rtpRtcpModuleVideo2 = RtpRtcp::CreateRtpRtcp(2, false); |
| assert(0 == rtpRtcpModuleVideo2->RegisterDefaultModule(rtpRtcpModuleVideoDef)); |
| |
| RtpRtcp* rtpRtcpModuleVideo3 = RtpRtcp::CreateRtpRtcp(3, false); |
| assert(0 == rtpRtcpModuleVideo3->RegisterDefaultModule(rtpRtcpModuleVideoDef)); |
| |
| LoopBackTransport2* myLoopBackTransport2 = new LoopBackTransport2(rtpRtcpModuleVideo2); |
| assert(0 == rtpRtcpModuleVideo2->RegisterSendTransport(myLoopBackTransport2)); |
| |
| assert(0 == rtpRtcpModuleVideo2->SetRTCPStatus(kRtcpCompound)); |
| |
| // set the SSRC to 0 |
| assert(0 == rtpRtcpModuleVideo2->SetSSRC(0)); |
| |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {4}, verify no TMMBN in this packet |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {0}, verify TMMBN {4,2} |
| assert(0 == rtpRtcpModuleVideo2->SendRTCP()); // -> incoming TMMBR {3}, verify TMMBN {4,2} |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // -> incoming TMMBR {1}, verify TMMBN {3,4,2} |
| ::Sleep(5*RTCP_INTERVAL_AUDIO_MS + 1000); |
| rtpRtcpModuleVideo2->Process(); // time out receiver2 -> UpdateTMMBR() |
| assert(0 == rtpRtcpModuleVideo->SendRTCP()); // verify TMMBN {} |
| |
| printf("Multi module test done.\n"); |
| |
| |
| RtpRtcp::DestroyRtpRtcp(rtpRtcpModuleVideo); |
| RtpRtcp::DestroyRtpRtcp(rtpRtcpModuleVideo1); |
| RtpRtcp::DestroyRtpRtcp(rtpRtcpModuleVideo2); |
| RtpRtcp::DestroyRtpRtcp(rtpRtcpModuleVideo3); |
| RtpRtcp::DestroyRtpRtcp(rtpRtcpModuleVideoDef); |
| |
| TEST_PASSED(); |
| ::Sleep(5000); |
| |
| return 0; |
| } |
| |