| /* |
| * 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 "RateControlDetector.h" |
| /*#include "rtcp_utility.h" |
| #include "tmmbr_help.h"*/ |
| |
| #define TEST_STR "Test RateControl." |
| #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}; |
| |
| |
| |
| |
| 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 |
| { |
| public: |
| LoopBackTransport2(RtpRtcp* rtpRtcpModule) : |
| _rtpRtcpModule(rtpRtcpModule), |
| _cnt(0) |
| { |
| } |
| virtual int SendPacket(int channel, const void *data, int len) |
| { |
| return _rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)data, len); |
| } |
| virtual int SendRTCPPacket(int channel, const void *data, int len) |
| { |
| char fileName[256] = {0}; |
| |
| |
| // Get stored rtcp packet w/ TMMBR |
| len = GetFile(fileName); |
| if (len == 0) |
| { |
| return 0; |
| } |
| |
| // Send in bitrate request |
| return _rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)dataFile, len); |
| } |
| RtpRtcp* _rtpRtcpModule; |
| WebRtc_UWord32 _cnt; |
| }; |
| |
| |
| class LoopBackTransportVideo : public webrtc::Transport |
| { |
| public: |
| LoopBackTransportVideo(RtpRtcp* rtpRtcpModule) : |
| _rtpRtcpModule(rtpRtcpModule), |
| _cnt(0) |
| { |
| } |
| virtual int SendPacket(int channel, const void *data, int len) |
| { |
| return _rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)data, len); |
| } |
| virtual int SendRTCPPacket(int channel, const void *data, int len) |
| { |
| char fileName[256] = {0}; |
| |
| strcpy(fileName, "RTCPPacketTMMBR0.bin"); |
| |
| ++_cnt; |
| |
| // Get stored rtcp packet w/ TMMBR |
| len = GetFile(fileName); |
| if (len == 0) |
| { |
| return 0; |
| } |
| |
| // Send in bitrate request*/ |
| return _rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)dataFile, len); |
| } |
| |
| RtpRtcp* _rtpRtcpModule; |
| WebRtc_UWord32 _cnt; |
| }; |
| |
| class TestRateControl : private RateControlDetector |
| { |
| public: |
| TestRateControl():RateControlDetector(0) |
| { |
| } |
| ~TestRateControl() |
| { |
| } |
| void Start() |
| { |
| //Test perfect conditions |
| // But only one packet per frame |
| SetLastUsedBitRate(500); |
| WebRtc_UWord32 rtpTs=1234*90; |
| WebRtc_UWord32 framePeriod=33; // In Ms |
| WebRtc_UWord32 rtpDelta=framePeriod*90; |
| WebRtc_UWord32 netWorkDelay=10; |
| WebRtc_UWord32 arrivalTime=rtpTs/90+netWorkDelay; |
| WebRtc_UWord32 newBitRate=0; |
| for(WebRtc_UWord32 k=0;k<10;k++) |
| { |
| // Receive 10 packets |
| for(WebRtc_UWord32 i=0;i<10;i++) |
| { |
| NotifyNewArrivedPacket(rtpTs,arrivalTime); |
| rtpTs+=rtpDelta; |
| arrivalTime=rtpTs/90+netWorkDelay; |
| } |
| newBitRate=RateControl(2*netWorkDelay); |
| SetLastUsedBitRate(newBitRate); |
| Sleep(10*framePeriod); |
| std::cout << "RTCP Packet " << k << " new bitrate " << newBitRate << std::endl; |
| } |
| Reset(); |
| |
| |
| //Test increasing RTT |
| std::cout << "Test increasing RTT - No Receive timing changes" << std::endl; |
| SetLastUsedBitRate(500); |
| |
| for(WebRtc_UWord32 k=0;k<10;k++) |
| { |
| // Receive 10 packets |
| for(WebRtc_UWord32 i=0;i<10;i++) |
| { |
| NotifyNewArrivedPacket(rtpTs,arrivalTime); |
| rtpTs+=rtpDelta; |
| arrivalTime=rtpTs/90+netWorkDelay; |
| } |
| WebRtc_UWord32 rtt=2*netWorkDelay+k*20; |
| newBitRate=RateControl(rtt); |
| Sleep(10*framePeriod); |
| SetLastUsedBitRate(newBitRate); |
| std::cout << "RTCP Packet " << k << " RTT "<< rtt << " new bitrate " << newBitRate << std::endl; |
| |
| } |
| |
| Reset(); |
| |
| |
| //Test increasing RTT |
| std::cout << "Test increasing RTT - Changed receive timing" << std::endl; |
| SetLastUsedBitRate(500); |
| |
| for(WebRtc_UWord32 k=0;k<10;k++) |
| { |
| // Receive 10 packets |
| for(WebRtc_UWord32 i=0;i<10;i++) |
| { |
| NotifyNewArrivedPacket(rtpTs,arrivalTime); |
| rtpTs+=rtpDelta; |
| arrivalTime=rtpTs/90+netWorkDelay+i+(k*20); |
| } |
| WebRtc_UWord32 rtt=2*netWorkDelay+k*20; |
| newBitRate=RateControl(rtt); |
| Sleep(10*framePeriod); |
| SetLastUsedBitRate(newBitRate); |
| std::cout << "RTCP Packet " << k << " RTT "<< rtt << " new bitrate " << newBitRate << std::endl; |
| |
| } |
| |
| |
| |
| }; |
| }; |
| |
| class NULLDataZink: public RtpData |
| { |
| virtual WebRtc_Word32 OnReceivedPayloadData(const WebRtc_UWord8* payloadData, |
| const WebRtc_UWord16 payloadSize, |
| const webrtc::WebRtcRTPHeader* rtpHeader) |
| { |
| return 0; |
| }; |
| }; |
| |
| |
| int _tmain(int argc, _TCHAR* argv[]) |
| { |
| |
| std::string str; |
| std::cout << "------------------------" << std::endl; |
| std::cout << "---Test RateControl ----" << std::endl; |
| std::cout << "------------------------" << std::endl; |
| std::cout << " " << std::endl; |
| |
| // -------------------- |
| // Test TMMBRHelp class |
| |
| // -------------------- |
| TestRateControl test; |
| test.Start(); |
| |
| printf("RateControl-class test done.\n"); |
| |
| // ------------------------ |
| // Test RateControl single module |
| // ------------------------ |
| RtpRtcp* rtpRtcpModuleVideo = RtpRtcp::CreateRtpRtcp(0, false); |
| |
| LoopBackTransportVideo* myLoopBackTransportVideo = new LoopBackTransportVideo(rtpRtcpModuleVideo); |
| assert(0 == rtpRtcpModuleVideo->RegisterSendTransport(myLoopBackTransportVideo)); |
| printf("Multi module test done.\n"); |
| |
| |
| RtpRtcp::DestroyRtpRtcp(rtpRtcpModuleVideo); |
| delete myLoopBackTransportVideo; |
| |
| TEST_PASSED(); |
| ::Sleep(5000); |
| |
| return 0; |
| } |
| |