diff --git a/src/modules/video_coding/main/source/video_coding_test.gypi b/src/modules/video_coding/main/source/video_coding_test.gypi index e017f822f..0d004fcec 100644 --- a/src/modules/video_coding/main/source/video_coding_test.gypi +++ b/src/modules/video_coding/main/source/video_coding_test.gypi @@ -58,6 +58,7 @@ '../test/receiver_tests.h', '../test/release_test.h', '../test/rtp_player.h', + '../test/test_callbacks.h', '../test/test_util.h', '../test/video_source.h', @@ -73,6 +74,7 @@ '../test/quality_modes_test.cc', '../test/receiver_timing_tests.cc', '../test/rtp_player.cc', + '../test/test_callbacks.cc', '../test/test_util.cc', '../test/tester_main.cc', '../test/video_rtp_play_mt.cc', diff --git a/src/modules/video_coding/main/test/codec_database_test.cc b/src/modules/video_coding/main/test/codec_database_test.cc index 5030bf626..000218c8a 100644 --- a/src/modules/video_coding/main/test/codec_database_test.cc +++ b/src/modules/video_coding/main/test/codec_database_test.cc @@ -18,6 +18,7 @@ #include "../../../../engine_configurations.h" #include "../source/event.h" +#include "test_callbacks.h" #include "test_macros.h" #include "test_util.h" #include "video_metrics.h" diff --git a/src/modules/video_coding/main/test/generic_codec_test.cc b/src/modules/video_coding/main/test/generic_codec_test.cc index f3c47c0fe..54bce4aee 100644 --- a/src/modules/video_coding/main/test/generic_codec_test.cc +++ b/src/modules/video_coding/main/test/generic_codec_test.cc @@ -16,10 +16,11 @@ #include "rtp_rtcp.h" #include "module_common_types.h" #include "test_macros.h" -#include "test_util.h" using namespace webrtc; +enum { kMaxWaitEncTimeMs = 100 }; + int GenericCodecTest::RunTest(CmdArgs& args) { // Don't run this test with debug time diff --git a/src/modules/video_coding/main/test/generic_codec_test.h b/src/modules/video_coding/main/test/generic_codec_test.h index 49e19e34a..abfc23989 100644 --- a/src/modules/video_coding/main/test/generic_codec_test.h +++ b/src/modules/video_coding/main/test/generic_codec_test.h @@ -12,11 +12,12 @@ #define WEBRTC_MODULES_VIDEO_CODING_TEST_GENERIC_CODEC_TEST_H_ #include "video_coding.h" -#include "test_util.h" #include #include +#include "test_callbacks.h" +#include "test_util.h" /* Test consists of: 1. Sanity checks diff --git a/src/modules/video_coding/main/test/media_opt_test.cc b/src/modules/video_coding/main/test/media_opt_test.cc index db6828e0f..1d15e3916 100644 --- a/src/modules/video_coding/main/test/media_opt_test.cc +++ b/src/modules/video_coding/main/test/media_opt_test.cc @@ -20,7 +20,7 @@ #include "../source/event.h" #include "receiver_tests.h" // receive side callbacks -#include "rtp_rtcp.h" +#include "test_callbacks.h" #include "test_macros.h" #include "test_util.h" // send side callback #include "video_coding.h" @@ -277,7 +277,7 @@ MediaOptTest::Perform() RtpDataCallback dataCallback(_vcm); _rtp->RegisterIncomingDataCallback(&dataCallback); - VCMTestProtectionCallback protectionCallback; + VideoProtectionCallback protectionCallback; _vcm->RegisterProtectionCallback(&protectionCallback); // set error resilience / test parameters: @@ -544,86 +544,3 @@ MediaOptTest::TearDown() fclose(_actualSourceFile); return; } - - -VCMTestProtectionCallback::VCMTestProtectionCallback(): -_deltaFECRate(0), -_keyFECRate(0), -_deltaUseUepProtection(0), -_keyUseUepProtection(0), -_nack(kNackOff) -{ - // -} - -VCMTestProtectionCallback::~VCMTestProtectionCallback() -{ - // -} - -WebRtc_Word32 -VCMTestProtectionCallback::ProtectionRequest(const WebRtc_UWord8 deltaFECRate, - const WebRtc_UWord8 keyFECRate, - const bool deltaUseUepProtection, - const bool keyUseUepProtection, - const bool nack) -{ - _deltaFECRate = deltaFECRate; - _keyFECRate = keyFECRate; - _deltaUseUepProtection = deltaUseUepProtection; - _keyUseUepProtection = keyUseUepProtection; - if (nack == true) - { - _nack = kNackRtcp; - } - else - { - _nack = kNackOff; - } - return VCM_OK; - -} -NACKMethod -VCMTestProtectionCallback::NACKMethod() -{ - return _nack; -} - -WebRtc_UWord8 -VCMTestProtectionCallback::FECDeltaRate() -{ - return _deltaFECRate; -} - -WebRtc_UWord8 -VCMTestProtectionCallback::FECKeyRate() -{ - return _keyFECRate; -} - -bool -VCMTestProtectionCallback::FECDeltaUepProtection() -{ - return _deltaUseUepProtection; -} - -bool -VCMTestProtectionCallback::FECKeyUepProtection() -{ - return _keyUseUepProtection; -} - - - -void -RTPFeedbackCallback::OnNetworkChanged(const WebRtc_Word32 id, - const WebRtc_UWord16 bitrateTargetKbit, - const WebRtc_UWord8 fractionLost, - const WebRtc_UWord16 roundTripTimeMs, - const WebRtc_UWord32 jitterMS, - const WebRtc_UWord16 bwEstimateKbitMin, - const WebRtc_UWord16 bwEstimateKbitMax) -{ - - _vcm->SetChannelParameters(bitrateTargetKbit, fractionLost,(WebRtc_UWord8)roundTripTimeMs); -} diff --git a/src/modules/video_coding/main/test/media_opt_test.h b/src/modules/video_coding/main/test/media_opt_test.h index 43be41446..e2bc6f8d0 100644 --- a/src/modules/video_coding/main/test/media_opt_test.h +++ b/src/modules/video_coding/main/test/media_opt_test.h @@ -12,14 +12,15 @@ #ifndef WEBRTC_MODULES_VIDEO_CODING_TEST_MEDIA_OPT_TEST_H_ #define WEBRTC_MODULES_VIDEO_CODING_TEST_MEDIA_OPT_TEST_H_ -#include "video_coding.h" -#include "test_util.h" -#include "video_source.h" #include +#include "rtp_rtcp.h" +#include "test_util.h" +#include "video_coding.h" +#include "video_source.h" + using namespace std; -// // media optimization test // This test simulates a complete encode-decode cycle via the RTP module. @@ -29,31 +30,6 @@ using namespace std; // 1 - Standard, basic settings, one run // 2 - Release test - iterates over a number of video sequences, bit rates, packet loss values ,etc. -class VCMTestProtectionCallback: public webrtc::VCMProtectionCallback -{ -public: - VCMTestProtectionCallback(); - virtual ~VCMTestProtectionCallback(); - WebRtc_Word32 ProtectionRequest(const WebRtc_UWord8 deltaFECRate, - const WebRtc_UWord8 keyFECRate, - const bool deltaUseUepProtection, - const bool keyUseUepProtection, - const bool nack); - enum webrtc::NACKMethod NACKMethod(); - WebRtc_UWord8 FECDeltaRate(); - WebRtc_UWord8 FECKeyRate(); - bool FECDeltaUepProtection(); - bool FECKeyUepProtection(); -private: - WebRtc_UWord8 _deltaFECRate; - WebRtc_UWord8 _keyFECRate; - bool _deltaUseUepProtection; - bool _keyUseUepProtection; - enum webrtc::NACKMethod _nack; - -}; - - class MediaOptTest { public: @@ -114,25 +90,4 @@ private: }; // end of MediaOptTest class definition - -// Feed back from the RTP Module callback -class RTPFeedbackCallback: public webrtc::RtpVideoFeedback -{ -public: - RTPFeedbackCallback(webrtc::VideoCodingModule* vcm) {_vcm = vcm;}; - void OnReceivedIntraFrameRequest(const WebRtc_Word32 id, - const WebRtc_UWord8 message = 0){}; - - void OnNetworkChanged(const WebRtc_Word32 id, - const WebRtc_UWord16 bitrateTargetKbit, - const WebRtc_UWord8 fractionLost, - const WebRtc_UWord16 roundTripTimeMs, - const WebRtc_UWord32 jitterMS, - const WebRtc_UWord16 bwEstimateKbitMin, - const WebRtc_UWord16 bwEstimateKbitMax); - -private: - webrtc::VideoCodingModule* _vcm; - -}; #endif // WEBRTC_MODULES_VIDEO_CODING_TEST_MEDIA_OPT_TEST_H_ diff --git a/src/modules/video_coding/main/test/mt_rx_tx_test.cc b/src/modules/video_coding/main/test/mt_rx_tx_test.cc index 3e5531530..77eb0f3c0 100644 --- a/src/modules/video_coding/main/test/mt_rx_tx_test.cc +++ b/src/modules/video_coding/main/test/mt_rx_tx_test.cc @@ -212,7 +212,7 @@ int MTRxTxTest(CmdArgs& args) rtp->RegisterIncomingDataCallback(&dataCallback); vcm->RegisterReceiveCallback(&receiveCallback); - VCMTestProtectionCallback protectionCallback; + VideoProtectionCallback protectionCallback; vcm->RegisterProtectionCallback(&protectionCallback); outgoingTransport->SetLossPct(lossRate); diff --git a/src/modules/video_coding/main/test/mt_test_common.h b/src/modules/video_coding/main/test/mt_test_common.h index 24d7912db..6dcbceda9 100644 --- a/src/modules/video_coding/main/test/mt_test_common.h +++ b/src/modules/video_coding/main/test/mt_test_common.h @@ -16,6 +16,7 @@ #define WEBRTC_MODULES_VIDEO_CODING_TEST_MT_TEST_COMMON_H_ #include "rtp_rtcp.h" +#include "test_callbacks.h" #include "test_util.h" #include "video_coding.h" diff --git a/src/modules/video_coding/main/test/normal_test.cc b/src/modules/video_coding/main/test/normal_test.cc index bfded77b5..f0eb4b42c 100644 --- a/src/modules/video_coding/main/test/normal_test.cc +++ b/src/modules/video_coding/main/test/normal_test.cc @@ -17,6 +17,7 @@ #include "../source/event.h" #include "common_types.h" +#include "test_callbacks.h" #include "test_macros.h" #include "test_util.h" #include "tick_time.h" diff --git a/src/modules/video_coding/main/test/quality_modes_test.cc b/src/modules/video_coding/main/test/quality_modes_test.cc index da8517d95..c8215daf3 100644 --- a/src/modules/video_coding/main/test/quality_modes_test.cc +++ b/src/modules/video_coding/main/test/quality_modes_test.cc @@ -15,6 +15,7 @@ #include #include "../source/event.h" +#include "test_callbacks.h" #include "test_macros.h" #include "video_metrics.h" #include "vplib.h" diff --git a/src/modules/video_coding/main/test/test_callbacks.cc b/src/modules/video_coding/main/test/test_callbacks.cc new file mode 100644 index 000000000..28f2d25a7 --- /dev/null +++ b/src/modules/video_coding/main/test/test_callbacks.cc @@ -0,0 +1,515 @@ +/* + * 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 "test_callbacks.h" + +#include + +#include "rtp_dump.h" +#include "test_macros.h" + +/****************************** + * VCMEncodeCompleteCallback + *****************************/ +// Basic callback implementation +// passes the encoded frame directly to the encoder +// Packetization callback implementation +VCMEncodeCompleteCallback::VCMEncodeCompleteCallback(FILE* encodedFile): + _encodedFile(encodedFile), + _encodedBytes(0), + _VCMReceiver(NULL), + _seqNo(0), + _encodeComplete(false), + _width(0), + _height(0), + _codecType(kRTPVideoNoVideo) +{ + // +} +VCMEncodeCompleteCallback::~VCMEncodeCompleteCallback() +{ +} + +void +VCMEncodeCompleteCallback::RegisterTransportCallback( + VCMPacketizationCallback* transport) +{ +} + +WebRtc_Word32 +VCMEncodeCompleteCallback::SendData( + const FrameType frameType, + const WebRtc_UWord8 payloadType, + const WebRtc_UWord32 timeStamp, + const WebRtc_UWord8* payloadData, + const WebRtc_UWord32 payloadSize, + const RTPFragmentationHeader& fragmentationHeader, + const RTPVideoTypeHeader* videoTypeHdr) +{ + // will call the VCMReceiver input packet + _frameType = frameType; + // writing encodedData into file + fwrite(payloadData, 1, payloadSize, _encodedFile); + WebRtcRTPHeader rtpInfo; + rtpInfo.header.markerBit = true; // end of frame + rtpInfo.type.Video.isFirstPacket = true; + rtpInfo.type.Video.codec = _codecType; + switch (_codecType) + { + case webrtc::kRTPVideoH263: + rtpInfo.type.Video.codecHeader.H263.bits = false; + rtpInfo.type.Video.codecHeader.H263.independentlyDecodable = false; + rtpInfo.type.Video.height = (WebRtc_UWord16)_height; + rtpInfo.type.Video.width = (WebRtc_UWord16)_width; + break; + case webrtc::kRTPVideoVP8: + rtpInfo.type.Video.codecHeader.VP8.nonReference = + videoTypeHdr->VP8.nonReference; + rtpInfo.type.Video.codecHeader.VP8.pictureId = + videoTypeHdr->VP8.pictureId; + break; + case webrtc::kRTPVideoI420: + break; + default: + assert(false); + return -1; + } + + rtpInfo.header.payloadType = payloadType; + rtpInfo.header.sequenceNumber = _seqNo++; + rtpInfo.header.ssrc = 0; + rtpInfo.header.timestamp = timeStamp; + rtpInfo.frameType = frameType; + // Size should also be received from that table, since the payload type + // defines the size. + + _encodedBytes += payloadSize; + // directly to receiver + int ret = _VCMReceiver->IncomingPacket(payloadData, payloadSize, rtpInfo); + _encodeComplete = true; + + return ret; +} + +float +VCMEncodeCompleteCallback::EncodedBytes() +{ + return _encodedBytes; +} + +bool +VCMEncodeCompleteCallback::EncodeComplete() +{ + if (_encodeComplete) + { + _encodeComplete = false; + return true; + } + return false; +} + +void +VCMEncodeCompleteCallback::Initialize() +{ + _encodeComplete = false; + _encodedBytes = 0; + _seqNo = 0; + return; +} + +void +VCMEncodeCompleteCallback::ResetByteCount() +{ + _encodedBytes = 0; +} + +/***********************************/ +/* VCMRTPEncodeCompleteCallback */ +/***********************************/ +// Encode Complete callback implementation +// passes the encoded frame via the RTP module to the decoder +// Packetization callback implementation + +WebRtc_Word32 +VCMRTPEncodeCompleteCallback::SendData( + const FrameType frameType, + const WebRtc_UWord8 payloadType, + const WebRtc_UWord32 timeStamp, + const WebRtc_UWord8* payloadData, + const WebRtc_UWord32 payloadSize, + const RTPFragmentationHeader& fragmentationHeader, + const RTPVideoTypeHeader* videoTypeHdr) +{ + _frameType = frameType; + _encodedBytes+= payloadSize; + _encodeComplete = true; + return _RTPModule->SendOutgoingData(frameType, + payloadType, + timeStamp, + payloadData, + payloadSize, + &fragmentationHeader, + videoTypeHdr); +} + +float +VCMRTPEncodeCompleteCallback::EncodedBytes() +{ + // only good for one call - after which will reset value; + float tmp = _encodedBytes; + _encodedBytes = 0; + return tmp; + } + +bool +VCMRTPEncodeCompleteCallback::EncodeComplete() +{ + if (_encodeComplete) + { + _encodeComplete = false; + return true; + } + return false; +} + +// Decoded Frame Callback Implementation + +WebRtc_Word32 +VCMDecodeCompleteCallback::FrameToRender(VideoFrame& videoFrame) +{ + fwrite(videoFrame.Buffer(), 1, videoFrame.Length(), _decodedFile); + _decodedBytes+= videoFrame.Length(); + return VCM_OK; + } + +WebRtc_Word32 +VCMDecodeCompleteCallback::DecodedBytes() +{ + return _decodedBytes; +} + +RTPSendCompleteCallback::RTPSendCompleteCallback(RtpRtcp* rtp, + const char* filename): + _sendCount(0), + _rtp(rtp), + _lossPct(0), + _burstLength(0), + _networkDelayMs(0), + _jitterVar(0), + _prevLossState(0), + _totalSentLength(0), + _rtpPackets(), + _rtpDump(NULL) +{ + if (filename != NULL) + { + _rtpDump = RtpDump::CreateRtpDump(); + _rtpDump->Start(filename); + } +} + +RTPSendCompleteCallback::~RTPSendCompleteCallback() +{ + if (_rtpDump != NULL) + { + _rtpDump->Stop(); + RtpDump::DestroyRtpDump(_rtpDump); + } + // Delete remaining packets + while (!_rtpPackets.Empty()) + { + // Take first packet in list + delete static_cast((_rtpPackets.First())->GetItem()); + _rtpPackets.PopFront(); + } +} + +int +RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len) +{ + _sendCount++; + _totalSentLength += len; + + if (_rtpDump != NULL) + { + if (_rtpDump->DumpPacket((const WebRtc_UWord8*)data, len) != 0) + { + return -1; + } + } + + bool transmitPacket = true; + transmitPacket = PacketLoss(); + + WebRtc_UWord64 now = VCMTickTime::MillisecondTimestamp(); + // Insert outgoing packet into list + if (transmitPacket) + { + rtpPacket* newPacket = new rtpPacket(); + memcpy(newPacket->data, data, len); + newPacket->length = len; + // Simulate receive time = network delay + packet jitter + // simulated as a Normal distribution random variable with + // mean = networkDelay and variance = jitterVar + WebRtc_Word32 + simulatedDelay = (WebRtc_Word32)NormalDist(_networkDelayMs, + sqrt(_jitterVar)); + newPacket->receiveTime = now + simulatedDelay; + _rtpPackets.PushBack(newPacket); + } + + // Are we ready to send packets to the receiver? + rtpPacket* packet = NULL; + + while (!_rtpPackets.Empty()) + { + // Take first packet in list + packet = static_cast((_rtpPackets.First())->GetItem()); + WebRtc_Word64 timeToReceive = packet->receiveTime - now; + if (timeToReceive > 0) + { + // No available packets to send + break; + } + + _rtpPackets.PopFront(); + // Send to receive side + if (_rtp->IncomingPacket((const WebRtc_UWord8*)packet->data, + packet->length) < 0) + { + delete packet; + packet = NULL; + // Will return an error after the first packet that goes wrong + return -1; + } + delete packet; + packet = NULL; + } + return len; // OK +} + +int +RTPSendCompleteCallback::SendRTCPPacket(int channel, const void *data, int len) +{ + // Incorporate network conditions + return SendPacket(channel, data, len); +} + +void +RTPSendCompleteCallback::SetLossPct(double lossPct) +{ + _lossPct = lossPct; + return; +} + +void +RTPSendCompleteCallback::SetBurstLength(double burstLength) +{ + _burstLength = burstLength; + return; +} + +bool +RTPSendCompleteCallback::PacketLoss() +{ + bool transmitPacket = true; + if (_burstLength <= 1.0) + { + // Random loss: if _burstLength parameter is not set, or <=1 + if (UnifomLoss(_lossPct)) + { + // drop + transmitPacket = false; + } + } + else + { + // Simulate bursty channel (Gilbert model) + // (1st order) Markov chain model with memory of the previous/last + // packet state (loss or received) + + // 0 = received state + // 1 = loss state + + // probTrans10: if previous packet is lost, prob. to -> received state + // probTrans11: if previous packet is lost, prob. to -> loss state + + // probTrans01: if previous packet is received, prob. to -> loss state + // probTrans00: if previous packet is received, prob. to -> received + + // Map the two channel parameters (average loss rate and burst length) + // to the transition probabilities: + double probTrans10 = 100 * (1.0 / _burstLength); + double probTrans11 = (100.0 - probTrans10); + double probTrans01 = (probTrans10 * ( _lossPct / (100.0 - _lossPct))); + + // Note: Random loss (Bernoulli) model is a special case where: + // burstLength = 100.0 / (100.0 - _lossPct) (i.e., p10 + p01 = 100) + + if (_prevLossState == 0 ) + { + // previous packet was received + if (UnifomLoss(probTrans01)) + { + // drop, update previous state to loss + _prevLossState = 1; + transmitPacket = false; + } + } + else if (_prevLossState == 1) + { + _prevLossState = 0; + // previous packet was lost + if (UnifomLoss(probTrans11)) + { + // drop, update previous state to loss + _prevLossState = 1; + transmitPacket = false; + } + } + } + return transmitPacket; +} + + +bool +RTPSendCompleteCallback::UnifomLoss(double lossPct) +{ + double randVal = (std::rand() + 1.0)/(RAND_MAX + 1.0); + return randVal < lossPct/100; +} + +WebRtc_Word32 +PacketRequester::ResendPackets(const WebRtc_UWord16* sequenceNumbers, + WebRtc_UWord16 length) +{ + return _rtp.SendNACK(sequenceNumbers, length); +} + +WebRtc_Word32 +SendStatsTest::SendStatistics(const WebRtc_UWord32 bitRate, + const WebRtc_UWord32 frameRate) +{ + TEST(frameRate <= _frameRate); + TEST(bitRate > 0 && bitRate < 100000); + printf("VCM 1 sec: Bit rate: %u\tFrame rate: %u\n", bitRate, frameRate); + return 0; +} + +WebRtc_Word32 +KeyFrameReqTest::FrameTypeRequest(const FrameType frameType) +{ + TEST(frameType == kVideoFrameKey); + if (frameType == kVideoFrameKey) + { + printf("Key frame requested\n"); + } + else + { + printf("Non-key frame requested: %d\n", frameType); + } + return 0; +} + + +VideoProtectionCallback::VideoProtectionCallback(): +_deltaFECRate(0), +_keyFECRate(0), +_deltaUseUepProtection(0), +_keyUseUepProtection(0), +_nack(kNackOff) +{ + // +} + +VideoProtectionCallback::~VideoProtectionCallback() +{ + // +} + +WebRtc_Word32 +VideoProtectionCallback::ProtectionRequest(const WebRtc_UWord8 deltaFECRate, + const WebRtc_UWord8 keyFECRate, + const bool deltaUseUepProtection, + const bool keyUseUepProtection, + const bool nack) +{ + _deltaFECRate = deltaFECRate; + _keyFECRate = keyFECRate; + _deltaUseUepProtection = deltaUseUepProtection; + _keyUseUepProtection = keyUseUepProtection; + if (nack == true) + { + _nack = kNackRtcp; + } + else + { + _nack = kNackOff; + } + + // Update RTP + if (_rtp->SetFECCodeRate(keyFECRate, deltaFECRate) != 0) + { + printf("Error in Setting FEC rate\n"); + return -1; + + } + if (_rtp->SetFECUepProtection(keyUseUepProtection, + deltaUseUepProtection) != 0) + { + printf("Error in Setting FEC UEP protection\n"); + return -1; + } + return 0; + +} +NACKMethod +VideoProtectionCallback::NACKMethod() +{ + return _nack; +} + +WebRtc_UWord8 +VideoProtectionCallback::FECDeltaRate() +{ + return _deltaFECRate; +} + +WebRtc_UWord8 +VideoProtectionCallback::FECKeyRate() +{ + return _keyFECRate; +} + +bool +VideoProtectionCallback::FECDeltaUepProtection() +{ + return _deltaUseUepProtection; +} + +bool +VideoProtectionCallback::FECKeyUepProtection() +{ + return _keyUseUepProtection; +} + +void +RTPFeedbackCallback::OnNetworkChanged(const WebRtc_Word32 id, + const WebRtc_UWord16 bitrateTargetKbit, + const WebRtc_UWord8 fractionLost, + const WebRtc_UWord16 roundTripTimeMs, + const WebRtc_UWord32 jitterMS, + const WebRtc_UWord16 bwEstimateKbitMin, + const WebRtc_UWord16 bwEstimateKbitMax) +{ + + _vcm->SetChannelParameters(bitrateTargetKbit, fractionLost, + (WebRtc_UWord8)roundTripTimeMs); +} diff --git a/src/modules/video_coding/main/test/test_callbacks.h b/src/modules/video_coding/main/test/test_callbacks.h new file mode 100644 index 000000000..f97809659 --- /dev/null +++ b/src/modules/video_coding/main/test/test_callbacks.h @@ -0,0 +1,281 @@ +/* + * 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. + */ + +#ifndef WEBRTC_MODULES_VIDEO_CODING_TEST_TEST_CALLBACKS_H_ +#define WEBRTC_MODULES_VIDEO_CODING_TEST_TEST_CALLBACKS_H_ + +/* + * Declaration of general callbacks that are used throughout VCM's offline tests + */ + + +#include +#include +#include + +#include "list_wrapper.h" +#include "module_common_types.h" +#include "rtp_rtcp.h" +#include "test_util.h" +#include "tick_time.h" +#include "trace.h" +#include "video_coding.h" + +using namespace webrtc; + +namespace webrtc +{ + class RtpDump; +} + +// Send Side - Packetization callback - send an encoded frame to the VCMReceiver +class VCMEncodeCompleteCallback: public VCMPacketizationCallback +{ +public: + // Constructor input: file in which encoded data will be written + VCMEncodeCompleteCallback(FILE* encodedFile); + virtual ~VCMEncodeCompleteCallback(); + // Register transport callback + void RegisterTransportCallback(VCMPacketizationCallback* transport); + // Process encoded data received from the encoder, pass stream to the + // VCMReceiver module + WebRtc_Word32 SendData(const FrameType frameType, + const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp, + const WebRtc_UWord8* payloadData, const WebRtc_UWord32 payloadSize, + const RTPFragmentationHeader& fragmentationHeader, + const RTPVideoTypeHeader* videoTypeHdr); + // Register exisitng VCM. Currently - encode and decode under same module. + void RegisterReceiverVCM(VideoCodingModule *vcm) {_VCMReceiver = vcm;} + // Return size of last encoded frame data (all frames in the sequence) + // Good for only one call - after which will reset value + // (to allow detection of frame drop) + float EncodedBytes(); + // Return encode complete (true/false) + bool EncodeComplete(); + // Inform callback of codec used + void SetCodecType(RTPVideoCodecTypes codecType) + {_codecType = codecType;} + // Inform callback of frame dimensions + void SetFrameDimensions(WebRtc_Word32 width, WebRtc_Word32 height) + { + _width = width; + _height = height; + } + // Initialize callback data + void Initialize(); + void ResetByteCount(); + + // Conversion function for payload type (needed for the callback function) + +private: + FILE* _encodedFile; + float _encodedBytes; + VideoCodingModule* _VCMReceiver; + FrameType _frameType; + WebRtc_UWord8* _payloadData; + WebRtc_UWord8 _seqNo; + bool _encodeComplete; + WebRtc_Word32 _width; + WebRtc_Word32 _height; + RTPVideoCodecTypes _codecType; + +}; // end of VCMEncodeCompleteCallback + +// Send Side - Packetization callback - packetize an encoded frame via the +// RTP module +class VCMRTPEncodeCompleteCallback: public VCMPacketizationCallback +{ +public: + VCMRTPEncodeCompleteCallback(RtpRtcp* rtp) : + _encodedBytes(0), + _seqNo(0), + _encodeComplete(false), + _RTPModule(rtp) {} + + virtual ~VCMRTPEncodeCompleteCallback() {} + // Process encoded data received from the encoder, pass stream to the + // RTP module + WebRtc_Word32 SendData(const FrameType frameType, + const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp, + const WebRtc_UWord8* payloadData, const WebRtc_UWord32 payloadSize, + const RTPFragmentationHeader& fragmentationHeader, + const RTPVideoTypeHeader* videoTypeHdr); + // Return size of last encoded frame. Value good for one call + // (resets to zero after call to inform test of frame drop) + float EncodedBytes(); + // Return encode complete (true/false) + bool EncodeComplete(); + // Inform callback of codec used + void SetCodecType(RTPVideoCodecTypes codecType) + {_codecType = codecType;} + + // Inform callback of frame dimensions + void SetFrameDimensions(WebRtc_Word16 width, WebRtc_Word16 height) + { + _width = width; + _height = height; + } + +private: + float _encodedBytes; + FrameType _frameType; + WebRtc_UWord8* _payloadData; + WebRtc_UWord16 _seqNo; + bool _encodeComplete; + RtpRtcp* _RTPModule; + WebRtc_Word16 _width; + WebRtc_Word16 _height; + RTPVideoCodecTypes _codecType; +}; // end of VCMEncodeCompleteCallback + +// Decode Complete callback +// Writes the decoded frames to a given file. +class VCMDecodeCompleteCallback: public VCMReceiveCallback +{ +public: + VCMDecodeCompleteCallback(FILE* decodedFile) : + _decodedFile(decodedFile), _decodedBytes(0) {} + virtual ~VCMDecodeCompleteCallback() {} + // Write decoded frame into file + WebRtc_Word32 FrameToRender(webrtc::VideoFrame& videoFrame); + WebRtc_Word32 DecodedBytes(); +private: + FILE* _decodedFile; + WebRtc_UWord32 _decodedBytes; +}; // end of VCMDecodeCompleCallback class + + +// Transport callback +// Called by the RTP Sender - simulates sending packets through a network to the +// RTP receiver. User can set network conditions as: RTT, packet loss, +// burst length and jitter. +class RTPSendCompleteCallback: public Transport +{ +public: + // Constructor input: (receive side) rtp module to send encoded data to + RTPSendCompleteCallback(RtpRtcp* rtp, + const char* filename = NULL); + virtual ~RTPSendCompleteCallback(); + // Send Packet to receive side RTP module + virtual int SendPacket(int channel, const void *data, int len); + // Send RTCP Packet to receive side RTP module + virtual int SendRTCPPacket(int channel, const void *data, int len); + // Set percentage of channel loss in the network + void SetLossPct(double lossPct); + // Set average size of burst loss + void SetBurstLength(double burstLength); + // Set network delay in the network + void SetNetworkDelay(WebRtc_UWord32 networkDelayMs) + {_networkDelayMs = networkDelayMs;}; + // Set Packet jitter delay + void SetJitterVar(WebRtc_UWord32 jitterVar) + {_jitterVar = jitterVar;}; + // Return send count + int SendCount() {return _sendCount; } + // Return accumulated length in bytes of transmitted packets + WebRtc_UWord32 TotalSentLength() {return _totalSentLength;} +protected: + // Randomly decide whether to drop packets, based on the channel model + bool PacketLoss(); + // Random uniform loss model + bool UnifomLoss(double lossPct); + + WebRtc_UWord32 _sendCount; + RtpRtcp* _rtp; + double _lossPct; + double _burstLength; + WebRtc_UWord32 _networkDelayMs; + double _jitterVar; + bool _prevLossState; + WebRtc_UWord32 _totalSentLength; + ListWrapper _rtpPackets; + RtpDump* _rtpDump; +}; + +// Request re-transmission of packets (NACK) +class PacketRequester: public VCMPacketRequestCallback +{ +public: + PacketRequester(RtpRtcp& rtp) : + _rtp(rtp) {} + WebRtc_Word32 ResendPackets(const WebRtc_UWord16* sequenceNumbers, + WebRtc_UWord16 length); +private: + webrtc::RtpRtcp& _rtp; +}; + +// Key frame request +class KeyFrameReqTest: public VCMFrameTypeCallback +{ +public: + WebRtc_Word32 FrameTypeRequest(const FrameType frameType); +}; + + +// VCM statistics +class SendStatsTest: public webrtc::VCMSendStatisticsCallback +{ +public: + SendStatsTest() : _frameRate(15) {} + WebRtc_Word32 SendStatistics(const WebRtc_UWord32 bitRate, + const WebRtc_UWord32 frameRate); + void SetTargetFrameRate(WebRtc_UWord32 frameRate) {_frameRate = frameRate;} +private: + WebRtc_UWord32 _frameRate; +}; + +// Protection callback - allows the VCM (media optimization) to inform the RTP +// module of the required protection(FEC rates/settings and NACK mode). +class VideoProtectionCallback: public VCMProtectionCallback +{ +public: + VideoProtectionCallback(); + virtual ~VideoProtectionCallback(); + void RegisterRtpModule(RtpRtcp* rtp){_rtp = rtp;} + WebRtc_Word32 ProtectionRequest(const WebRtc_UWord8 deltaFECRate, + const WebRtc_UWord8 keyFECRate, + const bool deltaUseUepProtection, + const bool keyUseUepProtection, + const bool nack); + enum NACKMethod NACKMethod(); + WebRtc_UWord8 FECDeltaRate(); + WebRtc_UWord8 FECKeyRate(); + bool FECDeltaUepProtection(); + bool FECKeyUepProtection(); +private: + RtpRtcp* _rtp; + WebRtc_UWord8 _deltaFECRate; + WebRtc_UWord8 _keyFECRate; + bool _deltaUseUepProtection; + bool _keyUseUepProtection; + enum NACKMethod _nack; +}; + +// Feed back from the RTP Module callback +class RTPFeedbackCallback: public RtpVideoFeedback +{ +public: + RTPFeedbackCallback(VideoCodingModule* vcm) {_vcm = vcm;}; + void OnReceivedIntraFrameRequest(const WebRtc_Word32 id, + const WebRtc_UWord8 message = 0){}; + + void OnNetworkChanged(const WebRtc_Word32 id, + const WebRtc_UWord16 bitrateTargetKbit, + const WebRtc_UWord8 fractionLost, + const WebRtc_UWord16 roundTripTimeMs, + const WebRtc_UWord32 jitterMS, + const WebRtc_UWord16 bwEstimateKbitMin, + const WebRtc_UWord16 bwEstimateKbitMax); +private: + VideoCodingModule* _vcm; +}; + + +#endif diff --git a/src/modules/video_coding/main/test/test_util.cc b/src/modules/video_coding/main/test/test_util.cc index 19e7ab90f..be9f352ae 100644 --- a/src/modules/video_coding/main/test/test_util.cc +++ b/src/modules/video_coding/main/test/test_util.cc @@ -27,384 +27,6 @@ NormalDist(double mean, double stdDev) return (mean + stdDev * sqrt(-2 * log(uniform1)) * cos(2 * PI * uniform2)); } - -/****************************** - * VCMEncodeCompleteCallback - *****************************/ -// Basic callback implementation -// passes the encoded frame directly to the encoder -// Packetization callback implementation -VCMEncodeCompleteCallback::VCMEncodeCompleteCallback(FILE* encodedFile): - _encodedFile(encodedFile), - _encodedBytes(0), - _VCMReceiver(NULL), - _seqNo(0), - _encodeComplete(false), - _width(0), - _height(0), - _codecType(kRTPVideoNoVideo) -{ - // -} -VCMEncodeCompleteCallback::~VCMEncodeCompleteCallback() -{ -} - -void -VCMEncodeCompleteCallback::RegisterTransportCallback( - VCMPacketizationCallback* transport) -{ -} - -WebRtc_Word32 -VCMEncodeCompleteCallback::SendData( - const FrameType frameType, - const WebRtc_UWord8 payloadType, - const WebRtc_UWord32 timeStamp, - const WebRtc_UWord8* payloadData, - const WebRtc_UWord32 payloadSize, - const RTPFragmentationHeader& fragmentationHeader, - const webrtc::RTPVideoTypeHeader* videoTypeHdr) -{ - // will call the VCMReceiver input packet - _frameType = frameType; - // writing encodedData into file - fwrite(payloadData, 1, payloadSize, _encodedFile); - WebRtcRTPHeader rtpInfo; - rtpInfo.header.markerBit = true; // end of frame - rtpInfo.type.Video.isFirstPacket = true; - rtpInfo.type.Video.codec = _codecType; - switch (_codecType) - { - case webrtc::kRTPVideoH263: - rtpInfo.type.Video.codecHeader.H263.bits = false; - rtpInfo.type.Video.codecHeader.H263.independentlyDecodable = false; - rtpInfo.type.Video.height = (WebRtc_UWord16)_height; - rtpInfo.type.Video.width = (WebRtc_UWord16)_width; - break; - case webrtc::kRTPVideoVP8: - rtpInfo.type.Video.codecHeader.VP8.nonReference = - videoTypeHdr->VP8.nonReference; - rtpInfo.type.Video.codecHeader.VP8.pictureId = - videoTypeHdr->VP8.pictureId; - break; - case webrtc::kRTPVideoI420: - break; - default: - assert(false); - return -1; - } - - rtpInfo.header.payloadType = payloadType; - rtpInfo.header.sequenceNumber = _seqNo++; - rtpInfo.header.ssrc = 0; - rtpInfo.header.timestamp = timeStamp; - rtpInfo.frameType = frameType; - // Size should also be received from that table, since the payload type - // defines the size. - - _encodedBytes += payloadSize; - // directly to receiver - int ret = _VCMReceiver->IncomingPacket(payloadData, payloadSize, rtpInfo); - _encodeComplete = true; - - return ret; -} - -float -VCMEncodeCompleteCallback::EncodedBytes() -{ - return _encodedBytes; -} - -bool -VCMEncodeCompleteCallback::EncodeComplete() -{ - if (_encodeComplete) - { - _encodeComplete = false; - return true; - } - return false; -} - -void -VCMEncodeCompleteCallback::Initialize() -{ - _encodeComplete = false; - _encodedBytes = 0; - _seqNo = 0; - return; -} - -void -VCMEncodeCompleteCallback::ResetByteCount() -{ - _encodedBytes = 0; -} - -/***********************************/ -/* VCMRTPEncodeCompleteCallback */ -/***********************************/ -// Encode Complete callback implementation -// passes the encoded frame via the RTP module to the decoder -// Packetization callback implementation - -WebRtc_Word32 -VCMRTPEncodeCompleteCallback::SendData( - const FrameType frameType, - const WebRtc_UWord8 payloadType, - const WebRtc_UWord32 timeStamp, - const WebRtc_UWord8* payloadData, - const WebRtc_UWord32 payloadSize, - const RTPFragmentationHeader& fragmentationHeader, - const webrtc::RTPVideoTypeHeader* videoTypeHdr) -{ - _frameType = frameType; - _encodedBytes+= payloadSize; - _encodeComplete = true; - return _RTPModule->SendOutgoingData(frameType, - payloadType, - timeStamp, - payloadData, - payloadSize, - &fragmentationHeader, - videoTypeHdr); -} - -float -VCMRTPEncodeCompleteCallback::EncodedBytes() -{ - // only good for one call - after which will reset value; - float tmp = _encodedBytes; - _encodedBytes = 0; - return tmp; - } - -bool -VCMRTPEncodeCompleteCallback::EncodeComplete() -{ - if (_encodeComplete) - { - _encodeComplete = false; - return true; - } - return false; -} - -// Decoded Frame Callback Implementation - -WebRtc_Word32 -VCMDecodeCompleteCallback::FrameToRender(VideoFrame& videoFrame) -{ - fwrite(videoFrame.Buffer(), 1, videoFrame.Length(), _decodedFile); - _decodedBytes+= videoFrame.Length(); - return VCM_OK; - } - -WebRtc_Word32 -VCMDecodeCompleteCallback::DecodedBytes() -{ - return _decodedBytes; -} - -RTPSendCompleteCallback::RTPSendCompleteCallback(RtpRtcp* rtp, - const char* filename): - _sendCount(0), - _rtp(rtp), - _lossPct(0), - _burstLength(0), - _networkDelayMs(0), - _jitterVar(0), - _prevLossState(0), - _totalSentLength(0), - _rtpPackets(), - _rtpDump(NULL) -{ - if (filename != NULL) - { - _rtpDump = RtpDump::CreateRtpDump(); - _rtpDump->Start(filename); - } -} - -RTPSendCompleteCallback::~RTPSendCompleteCallback() -{ - if (_rtpDump != NULL) - { - _rtpDump->Stop(); - RtpDump::DestroyRtpDump(_rtpDump); - } - // Delete remaining packets - while (!_rtpPackets.Empty()) - { - // Take first packet in list - delete static_cast((_rtpPackets.First())->GetItem()); - _rtpPackets.PopFront(); - } -} - -int -RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len) -{ - _sendCount++; - _totalSentLength += len; - - if (_rtpDump != NULL) - { - if (_rtpDump->DumpPacket((const WebRtc_UWord8*)data, len) != 0) - { - return -1; - } - } - - bool transmitPacket = PacketLoss(); - - WebRtc_UWord64 now = VCMTickTime::MillisecondTimestamp(); - // Insert outgoing packet into list - if (transmitPacket) - { - rtpPacket* newPacket = new rtpPacket(); - memcpy(newPacket->data, data, len); - newPacket->length = len; - // Simulate receive time = network delay + packet jitter - // simulated as a Normal distribution random variable with - // mean = networkDelay and variance = jitterVar - WebRtc_Word32 - simulatedDelay = (WebRtc_Word32)NormalDist(_networkDelayMs, - sqrt(_jitterVar)); - newPacket->receiveTime = now + simulatedDelay; - _rtpPackets.PushBack(newPacket); - } - - // Are we ready to send packets to the receiver? - rtpPacket* packet = NULL; - - while (!_rtpPackets.Empty()) - { - // Take first packet in list - packet = static_cast((_rtpPackets.First())->GetItem()); - WebRtc_Word64 timeToReceive = packet->receiveTime - now; - if (timeToReceive > 0) - { - // No available packets to send - break; - } - - _rtpPackets.PopFront(); - // Send to receive side - if (_rtp->IncomingPacket((const WebRtc_UWord8*)packet->data, - packet->length) < 0) - { - delete packet; - packet = NULL; - // Will return an error after the first packet that goes wrong - return -1; - } - delete packet; - packet = NULL; - } - return len; // OK -} - -int -RTPSendCompleteCallback::SendRTCPPacket(int channel, const void *data, int len) -{ - // Incorporate network conditions - return SendPacket(channel, data, len); -} - -void -RTPSendCompleteCallback::SetLossPct(double lossPct) -{ - _lossPct = lossPct; - return; -} - -void -RTPSendCompleteCallback::SetBurstLength(double burstLength) -{ - _burstLength = burstLength; - return; -} - -bool -RTPSendCompleteCallback::PacketLoss() -{ - bool transmitPacket = true; - if (_burstLength <= 1.0) - { - // Random loss: if _burstLength parameter is not set, or <=1 - if (UnifomLoss(_lossPct)) - { - // drop - transmitPacket = false; - } - } - else - { - // Simulate bursty channel (Gilbert model) - // (1st order) Markov chain model with memory of the previous/last - // packet state (loss or received) - - // 0 = received state - // 1 = loss state - - // probTrans10: if previous packet is lost, prob. to -> received state - // probTrans11: if previous packet is lost, prob. to -> loss state - - // probTrans01: if previous packet is received, prob. to -> loss state - // probTrans00: if previous packet is received, prob. to -> received - - // Map the two channel parameters (average loss rate and burst length) - // to the transition probabilities: - double probTrans10 = 100 * (1.0 / _burstLength); - double probTrans11 = (100.0 - probTrans10); - double probTrans01 = (probTrans10 * ( _lossPct / (100.0 - _lossPct))); - - // Note: Random loss (Bernoulli) model is a special case where: - // burstLength = 100.0 / (100.0 - _lossPct) (i.e., p10 + p01 = 100) - - if (_prevLossState == 0 ) - { - // previous packet was received - if (UnifomLoss(probTrans01)) - { - // drop, update previous state to loss - _prevLossState = 1; - transmitPacket = false; - } - } - else if (_prevLossState == 1) - { - _prevLossState = 0; - // previous packet was lost - if (UnifomLoss(probTrans11)) - { - // drop, update previous state to loss - _prevLossState = 1; - transmitPacket = false; - } - } - } - return transmitPacket; -} - - -bool -RTPSendCompleteCallback::UnifomLoss(double lossPct) -{ - double randVal = (std::rand() + 1.0)/(RAND_MAX + 1.0); - return randVal < lossPct/100; -} - -WebRtc_Word32 -PacketRequester::ResendPackets(const WebRtc_UWord16* sequenceNumbers, - WebRtc_UWord16 length) -{ - return _rtp.SendNACK(sequenceNumbers, length); -} - RTPVideoCodecTypes ConvertCodecType(const char* plname) { @@ -428,30 +50,5 @@ ConvertCodecType(const char* plname) { return kRTPVideoNoVideo; // Default value } - } -WebRtc_Word32 -SendStatsTest::SendStatistics(const WebRtc_UWord32 bitRate, - const WebRtc_UWord32 frameRate) -{ - TEST(frameRate <= _frameRate); - TEST(bitRate > 0 && bitRate < 100000); - printf("VCM 1 sec: Bit rate: %u\tFrame rate: %u\n", bitRate, frameRate); - return 0; -} - -WebRtc_Word32 -KeyFrameReqTest::FrameTypeRequest(const FrameType frameType) -{ - TEST(frameType == kVideoFrameKey); - if (frameType == kVideoFrameKey) - { - printf("Key frame requested\n"); - } - else - { - printf("Non-key frame requested: %d\n", frameType); - } - return 0; -} diff --git a/src/modules/video_coding/main/test/test_util.h b/src/modules/video_coding/main/test/test_util.h index c1c1e21d5..84e35bfbc 100644 --- a/src/modules/video_coding/main/test/test_util.h +++ b/src/modules/video_coding/main/test/test_util.h @@ -8,22 +8,19 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef TEST_UTIL_H -#define TEST_UTIL_H +#ifndef WEBRTC_MODULES_VIDEO_CODING_TEST_TEST_UTIL_H_ +#define WEBRTC_MODULES_VIDEO_CODING_TEST_TEST_UTIL_H_ + +/* + * General declarations used through out VCM offline tests. + */ -#include "video_coding.h" -#include "rtp_rtcp.h" -#include "trace.h" #include "module_common_types.h" -#include "tick_time.h" -#include "test_util.h" -#include "list_wrapper.h" #include #include #include -enum { kMaxWaitEncTimeMs = 100 }; // Class used for passing command line arguments to tests class CmdArgs @@ -52,136 +49,6 @@ public: // forward declaration int MTRxTxTest(CmdArgs& args); double NormalDist(double mean, double stdDev); -namespace webrtc -{ - class RtpDump; -} - -// Definition of general test function to be used by VCM tester -// (mainly send side) -/* - Includes the following: - 1. General Callback definition for VCM test functions - no RTP. - 2. EncodeComplete callback: - 2a. Transfer encoded data directly to the decoder - 2b. Pass encoded data via the RTP module - 3. Calculate PSNR from file function (for now: does not deal with frame drops) - */ - -// Send Side - Packetization callback - send an encoded frame to the VCMReceiver -class VCMEncodeCompleteCallback: public webrtc::VCMPacketizationCallback -{ -public: - // constructor input: file in which encoded data will be written - VCMEncodeCompleteCallback(FILE* encodedFile); - virtual ~VCMEncodeCompleteCallback(); - // Register transport callback - void RegisterTransportCallback(webrtc::VCMPacketizationCallback* transport); - // Process encoded data received from the encoder, pass stream to the - // VCMReceiver module - WebRtc_Word32 SendData(const webrtc::FrameType frameType, - const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp, - const WebRtc_UWord8* payloadData, const WebRtc_UWord32 payloadSize, - const webrtc::RTPFragmentationHeader& fragmentationHeader, - const webrtc::RTPVideoTypeHeader* videoTypeHdr); - // Register exisitng VCM. Currently - encode and decode under same module. - void RegisterReceiverVCM(webrtc::VideoCodingModule *vcm) {_VCMReceiver = vcm;} - // Return size of last encoded frame encoded data (all frames in the sequence) - // Good for only one call - after which will reset value - // (to allow detection of frame drop) - float EncodedBytes(); - // Return encode complete (true/false) - bool EncodeComplete(); - // Inform callback of codec used - void SetCodecType(webrtc::RTPVideoCodecTypes codecType) - {_codecType = codecType;} - // Inform callback of frame dimensions - void SetFrameDimensions(WebRtc_Word32 width, WebRtc_Word32 height) - { - _width = width; - _height = height; - } - //Initialize callback data - void Initialize(); - void ResetByteCount(); - - // Conversion function for payload type (needed for the callback function) - -private: - FILE* _encodedFile; - float _encodedBytes; - webrtc::VideoCodingModule* _VCMReceiver; - webrtc::FrameType _frameType; - WebRtc_UWord8* _payloadData; - WebRtc_UWord8 _seqNo; - bool _encodeComplete; - WebRtc_Word32 _width; - WebRtc_Word32 _height; - webrtc::RTPVideoCodecTypes _codecType; - -}; // end of VCMEncodeCompleteCallback - -// Send Side - Packetization callback - packetize an encoded frame via the -// RTP module -class VCMRTPEncodeCompleteCallback: public webrtc::VCMPacketizationCallback -{ -public: - VCMRTPEncodeCompleteCallback(webrtc::RtpRtcp* rtp) : - _encodedBytes(0), - _seqNo(0), - _encodeComplete(false), - _RTPModule(rtp) {} - - virtual ~VCMRTPEncodeCompleteCallback() {} - // Process encoded data received from the encoder, pass stream to the - // RTP module - WebRtc_Word32 SendData(const webrtc::FrameType frameType, - const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp, - const WebRtc_UWord8* payloadData, const WebRtc_UWord32 payloadSize, - const webrtc::RTPFragmentationHeader& fragmentationHeader, - const webrtc::RTPVideoTypeHeader* videoTypeHdr); - // Return size of last encoded frame. Value good for one call - // (resets to zero after call to inform test of frame drop) - float EncodedBytes(); - // return encode complete (true/false) - bool EncodeComplete(); - // Inform callback of codec used - void SetCodecType(webrtc::RTPVideoCodecTypes codecType) - {_codecType = codecType;} - - // Inform callback of frame dimensions - void SetFrameDimensions(WebRtc_Word16 width, WebRtc_Word16 height) - { - _width = width; - _height = height; - } - -private: - float _encodedBytes; - webrtc::FrameType _frameType; - WebRtc_UWord8* _payloadData; - WebRtc_UWord16 _seqNo; - bool _encodeComplete; - webrtc::RtpRtcp* _RTPModule; - WebRtc_Word16 _width; - WebRtc_Word16 _height; - webrtc::RTPVideoCodecTypes _codecType; -}; // end of VCMEncodeCompleteCallback - -class VCMDecodeCompleteCallback: public webrtc::VCMReceiveCallback -{ -public: - VCMDecodeCompleteCallback(FILE* decodedFile) : - _decodedFile(decodedFile), _decodedBytes(0) {} - virtual ~VCMDecodeCompleteCallback() {} - // will write decoded frame into file - WebRtc_Word32 FrameToRender(webrtc::VideoFrame& videoFrame); - WebRtc_Word32 DecodedBytes(); -private: - FILE* _decodedFile; - WebRtc_UWord32 _decodedBytes; -}; // end of VCMDecodeCompleCallback class - typedef struct { @@ -191,80 +58,8 @@ typedef struct } rtpPacket; -class RTPSendCompleteCallback: public webrtc::Transport -{ -public: - // constructor input: (receive side) rtp module to send encoded data to - RTPSendCompleteCallback(webrtc::RtpRtcp* rtp, - const char* filename = NULL); - virtual ~RTPSendCompleteCallback(); - // Send Packet to receive side RTP module - virtual int SendPacket(int channel, const void *data, int len); - // Send RTCP Packet to receive side RTP module - virtual int SendRTCPPacket(int channel, const void *data, int len); - // Set percentage of channel loss in the network - void SetLossPct(double lossPct); - // Set average size of burst loss - void SetBurstLength(double burstLength); - // Set network delay in the network - void SetNetworkDelay(WebRtc_UWord32 networkDelayMs) - {_networkDelayMs = networkDelayMs;}; - // Set Packet jitter delay - void SetJitterVar(WebRtc_UWord32 jitterVar) - {_jitterVar = jitterVar;}; - // Return send count - int SendCount() {return _sendCount; } - // Return accumulated length in bytes of transmitted packets - WebRtc_UWord32 TotalSentLength() {return _totalSentLength;} -protected: - // Randomly decide whether to drop packets, based on the channel model - bool PacketLoss(); - // Random uniform loss model - bool UnifomLoss(double lossPct); - - WebRtc_UWord32 _sendCount; - webrtc::RtpRtcp* _rtp; - double _lossPct; - double _burstLength; - WebRtc_UWord32 _networkDelayMs; - double _jitterVar; - bool _prevLossState; - WebRtc_UWord32 _totalSentLength; - webrtc::ListWrapper _rtpPackets; - webrtc::RtpDump* _rtpDump; -}; - -class PacketRequester: public webrtc::VCMPacketRequestCallback -{ -public: - PacketRequester(webrtc::RtpRtcp& rtp) : - _rtp(rtp) {} - WebRtc_Word32 ResendPackets(const WebRtc_UWord16* sequenceNumbers, - WebRtc_UWord16 length); - -private: - webrtc::RtpRtcp& _rtp; -}; - // Codec type conversion webrtc::RTPVideoCodecTypes ConvertCodecType(const char* plname); -class SendStatsTest: public webrtc::VCMSendStatisticsCallback -{ -public: - SendStatsTest() : _frameRate(15) {} - WebRtc_Word32 SendStatistics(const WebRtc_UWord32 bitRate, - const WebRtc_UWord32 frameRate); - void SetTargetFrameRate(WebRtc_UWord32 frameRate) {_frameRate = frameRate;} -private: - WebRtc_UWord32 _frameRate; -}; - -class KeyFrameReqTest: public webrtc::VCMFrameTypeCallback -{ -public: - WebRtc_Word32 FrameTypeRequest(const webrtc::FrameType frameType); -}; - #endif