From abc9d5b6aaac0642afae71fd7a765c9cc1ee6e1a Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Mon, 18 Mar 2013 17:00:51 +0000 Subject: [PATCH] Change VCM interface to take target bitrate in bits per second. This also solves issue 1469. TESTS=trybots BUG=1469 Review URL: https://webrtc-codereview.appspot.com/1215004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3681 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../main/interface/video_coding.h | 4 +- .../main/source/generic_encoder.h | 7 ++-- .../main/source/media_optimization.cc | 41 ++++++++++--------- .../main/source/media_optimization.h | 7 ++-- .../main/source/video_coding_impl.cc | 10 ++--- .../main/source/video_coding_impl.h | 2 +- .../main/test/generic_codec_test.cc | 13 +++--- .../video_coding/main/test/media_opt_test.cc | 3 +- .../video_coding/main/test/mt_rx_tx_test.cc | 4 +- .../video_coding/main/test/normal_test.cc | 2 +- .../main/test/quality_modes_test.cc | 5 ++- webrtc/video_engine/vie_encoder.cc | 2 +- 12 files changed, 53 insertions(+), 47 deletions(-) diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h index a61aab1320..bf66748b04 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding.h +++ b/webrtc/modules/video_coding/main/interface/video_coding.h @@ -182,14 +182,14 @@ public: // encoder. Bit rate used by NACK should already be compensated for by the user. // // Input: - // - availableBandWidth : Band width available for the VCM in kbit/s. + // - target_bitrate : The target bitrate for VCM in bits/s. // - lossRate : Fractions of lost packets the past second. // (loss rate in percent = 100 * packetLoss / 255) // - rtt : Current round-trip time in ms. // // Return value : VCM_OK, on success. // < 0, on error. - virtual WebRtc_Word32 SetChannelParameters(WebRtc_UWord32 availableBandWidth, + virtual WebRtc_Word32 SetChannelParameters(WebRtc_UWord32 target_bitrate, WebRtc_UWord8 lossRate, WebRtc_UWord32 rtt) = 0; diff --git a/webrtc/modules/video_coding/main/source/generic_encoder.h b/webrtc/modules/video_coding/main/source/generic_encoder.h index 3768248942..a96ad9c9c4 100644 --- a/webrtc/modules/video_coding/main/source/generic_encoder.h +++ b/webrtc/modules/video_coding/main/source/generic_encoder.h @@ -105,10 +105,11 @@ public: const CodecSpecificInfo* codecSpecificInfo, const std::vector& frameTypes); /** - * Set new target bit rate and frame rate - * Return Value: new bit rate if OK, otherwise <0s + * Set new target bitrate (bits/s) and framerate. + * Return Value: new bit rate if OK, otherwise <0s. */ - WebRtc_Word32 SetRates(WebRtc_UWord32 newBitRate, WebRtc_UWord32 frameRate); + WebRtc_Word32 SetRates(WebRtc_UWord32 target_bitrate, + WebRtc_UWord32 frameRate); /** * Set a new packet loss rate and a new round-trip time in milliseconds. */ diff --git a/webrtc/modules/video_coding/main/source/media_optimization.cc b/webrtc/modules/video_coding/main/source/media_optimization.cc index 26a432fcc3..b5f35689e6 100644 --- a/webrtc/modules/video_coding/main/source/media_optimization.cc +++ b/webrtc/modules/video_coding/main/source/media_optimization.cc @@ -93,12 +93,13 @@ VCMMediaOptimization::Reset() } WebRtc_UWord32 -VCMMediaOptimization::SetTargetRates(WebRtc_UWord32 bitRate, +VCMMediaOptimization::SetTargetRates(WebRtc_UWord32 target_bitrate, WebRtc_UWord8 &fractionLost, WebRtc_UWord32 roundTripTimeMs) { VCMProtectionMethod *selectedMethod = _lossProtLogic->SelectedMethod(); - _lossProtLogic->UpdateBitRate(static_cast(bitRate)); + float target_bitrate_kbps = static_cast(target_bitrate) / 1000.0f; + _lossProtLogic->UpdateBitRate(target_bitrate_kbps); _lossProtLogic->UpdateRtt(roundTripTimeMs); _lossProtLogic->UpdateResidualPacketLoss(static_cast(fractionLost)); @@ -129,10 +130,10 @@ VCMMediaOptimization::SetTargetRates(WebRtc_UWord32 bitRate, _lossProtLogic->UpdateFilteredLossPr(packetLossEnc); // Rate cost of the protection methods - uint32_t protection_overhead_kbps = 0; + uint32_t protection_overhead_bps = 0; // Update protection settings, when applicable - float sent_video_rate = 0.0f; + float sent_video_rate_kbps = 0.0f; if (selectedMethod) { // Update protection method with content metrics @@ -159,32 +160,32 @@ VCMMediaOptimization::SetTargetRates(WebRtc_UWord32 bitRate, // Estimate the overhead costs of the next second as staying the same // wrt the source bitrate. if (sent_total_rate_bps > 0) { - protection_overhead_kbps = static_cast(bitRate * + protection_overhead_bps = static_cast(target_bitrate * static_cast(sent_nack_rate_bps + sent_fec_rate_bps) / sent_total_rate_bps + 0.5); } // Cap the overhead estimate to 50%. - if (protection_overhead_kbps > bitRate / 2) - protection_overhead_kbps = bitRate / 2; + if (protection_overhead_bps > target_bitrate / 2) + protection_overhead_bps = target_bitrate / 2; // Get the effective packet loss for encoder ER // when applicable, should be passed to encoder via fractionLost packetLossEnc = selectedMethod->RequiredPacketLossER(); - sent_video_rate = static_cast(sent_video_rate_bps / 1000.0); + sent_video_rate_kbps = + static_cast(sent_video_rate_bps) / 1000.0f; } // Source coding rate: total rate - protection overhead - _targetBitRate = bitRate - protection_overhead_kbps; + _targetBitRate = target_bitrate - protection_overhead_bps; // Update encoding rates following protection settings - _frameDropper->SetRates(static_cast(_targetBitRate), - _incomingFrameRate); + _frameDropper->SetRates(target_bitrate_kbps, _incomingFrameRate); if (_enableQm) { // Update QM with rates - _qmResolution->UpdateRates((float)_targetBitRate, sent_video_rate, - _incomingFrameRate, _fractionLost); + _qmResolution->UpdateRates(target_bitrate_kbps, sent_video_rate_kbps, + _incomingFrameRate, _fractionLost); // Check for QM selection bool selectQM = checkStatusForQMchange(); if (selectQM) @@ -266,7 +267,7 @@ WebRtc_Word32 VCMMediaOptimization::SetEncodingData(VideoCodecType sendCodecType, WebRtc_Word32 maxBitRate, WebRtc_UWord32 frameRate, - WebRtc_UWord32 bitRate, + WebRtc_UWord32 target_bitrate, WebRtc_UWord16 width, WebRtc_UWord16 height, int numLayers) @@ -281,20 +282,20 @@ VCMMediaOptimization::SetEncodingData(VideoCodecType sendCodecType, _maxBitRate = maxBitRate; _sendCodecType = sendCodecType; - _targetBitRate = bitRate; - _lossProtLogic->UpdateBitRate(static_cast(bitRate)); + _targetBitRate = target_bitrate; + float target_bitrate_kbps = static_cast(target_bitrate) / 1000.0f; + _lossProtLogic->UpdateBitRate(target_bitrate_kbps); _lossProtLogic->UpdateFrameRate(static_cast(frameRate)); _lossProtLogic->UpdateFrameSize(width, height); _lossProtLogic->UpdateNumLayers(numLayers); _frameDropper->Reset(); - _frameDropper->SetRates(static_cast(bitRate), - static_cast(frameRate)); + _frameDropper->SetRates(target_bitrate_kbps, static_cast(frameRate)); _userFrameRate = static_cast(frameRate); _codecWidth = width; _codecHeight = height; _numLayers = (numLayers <= 1) ? 1 : numLayers; // Can also be zero. WebRtc_Word32 ret = VCM_OK; - ret = _qmResolution->Initialize((float)_targetBitRate, _userFrameRate, + ret = _qmResolution->Initialize(target_bitrate_kbps, _userFrameRate, _codecWidth, _codecHeight, _numLayers); return ret; } @@ -361,7 +362,7 @@ float VCMMediaOptimization::SentBitRate() { UpdateBitRateEstimate(-1, _clock->TimeInMilliseconds()); - return _avgSentBitRateBps / 1000.0f; + return _avgSentBitRateBps; } WebRtc_Word32 diff --git a/webrtc/modules/video_coding/main/source/media_optimization.h b/webrtc/modules/video_coding/main/source/media_optimization.h index e273ed3bc5..39bd9af519 100644 --- a/webrtc/modules/video_coding/main/source/media_optimization.h +++ b/webrtc/modules/video_coding/main/source/media_optimization.h @@ -47,14 +47,13 @@ public: WebRtc_Word32 Reset(); /** * Set target Rates for the encoder given the channel parameters - * Inputs: bitRate - target bitRate, in the conference case this is the rate - * between the sending client and the server + * Inputs: target bitrate - the encoder target bitrate in bits/s. * fractionLost - packet loss in % in the network - * roundTripTimeMs - round trip time in miliseconds + * roundTripTimeMs - round trip time in milliseconds * minBitRate - the bit rate of the end-point with lowest rate * maxBitRate - the bit rate of the end-point with highest rate */ - WebRtc_UWord32 SetTargetRates(WebRtc_UWord32 bitRate, + WebRtc_UWord32 SetTargetRates(WebRtc_UWord32 target_bitrate, WebRtc_UWord8 &fractionLost, WebRtc_UWord32 roundTripTimeMs); diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc index ed9e7a130b..7c484fcb55 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -349,9 +349,9 @@ VideoCodingModuleImpl::RegisterSendCodec(const VideoCodec* sendCodec, kVideoFrameDelta); _mediaOpt.SetEncodingData(_sendCodecType, - sendCodec->maxBitrate, - sendCodec->maxFramerate, - sendCodec->startBitrate, + sendCodec->maxBitrate * 1000, + sendCodec->maxFramerate * 1000, + sendCodec->startBitrate * 1000, sendCodec->width, sendCodec->height, numLayers); @@ -447,14 +447,14 @@ int VideoCodingModuleImpl::FrameRate(unsigned int* framerate) const // Set channel parameters WebRtc_Word32 -VideoCodingModuleImpl::SetChannelParameters(WebRtc_UWord32 availableBandWidth, +VideoCodingModuleImpl::SetChannelParameters(WebRtc_UWord32 target_bitrate, WebRtc_UWord8 lossRate, WebRtc_UWord32 rtt) { WebRtc_Word32 ret = 0; { CriticalSectionScoped sendCs(_sendCritSect); - WebRtc_UWord32 targetRate = _mediaOpt.SetTargetRates(availableBandWidth, + WebRtc_UWord32 targetRate = _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt); if (_encoder != NULL) diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h index 22bf8d2b69..48cc452935 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.h +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h @@ -109,7 +109,7 @@ public: // Set channel parameters virtual WebRtc_Word32 SetChannelParameters( - WebRtc_UWord32 availableBandWidth, + WebRtc_UWord32 target_bitrate, // bits/s. WebRtc_UWord8 lossRate, WebRtc_UWord32 rtt); diff --git a/webrtc/modules/video_coding/main/test/generic_codec_test.cc b/webrtc/modules/video_coding/main/test/generic_codec_test.cc index e549b9aa1c..e4f06d9835 100644 --- a/webrtc/modules/video_coding/main/test/generic_codec_test.cc +++ b/webrtc/modules/video_coding/main/test/generic_codec_test.cc @@ -138,7 +138,8 @@ GenericCodecTest::Perform(CmdArgs& args) TEST(_vcm->RegisterSendCodec(&sendCodec, 1, 1440) < 0); // bad bit rate _vcm->Codec(kVideoCodecVP8, &sendCodec); _vcm->InitializeSender(); - TEST(_vcm->SetChannelParameters(100, 0, 0) < 0);// setting rate when encoder uninitialized + // Setting rate when encoder uninitialized. + TEST(_vcm->SetChannelParameters(100000, 0, 0) < 0); // register all availbale decoders -- need to have more for this test for (i=0; i< NumberOfCodecs; i++) { @@ -159,7 +160,8 @@ GenericCodecTest::Perform(CmdArgs& args) sourceFrame.set_timestamp(_timeStamp++); TEST(_vcm->AddVideoFrame(sourceFrame) < 0 ); // encoder uninitialized _vcm->InitializeReceiver(); - TEST(_vcm->SetChannelParameters(100, 0, 0) < 0);// setting rtt when receiver uninitialized + // Setting rtt when receiver uninitialized. + TEST(_vcm->SetChannelParameters(100000, 0, 0) < 0); /**************************************/ /* encoder/decoder individuality test */ @@ -310,7 +312,8 @@ GenericCodecTest::Perform(CmdArgs& args) _vcm->RegisterSendCodec(&_sendCodec, 1, 1440); _vcm->RegisterTransportCallback(_encodeCompleteCallback); // up to here - _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 20); + _vcm->SetChannelParameters(static_cast(1000 * _bitRate), + 0, 20); _frameCnt = 0; totalBytes = 0; _encodeCompleteCallback->Initialize(); @@ -428,10 +431,10 @@ GenericCodecTest::Perform(CmdArgs& args) _vcm->InitializeSender(); _sendCodec.maxFramerate = static_cast(_frameRate / 2.0 + 0.5f); _vcm->RegisterSendCodec(&_sendCodec, 4, 1440); - _vcm->SetChannelParameters(2000, 0, 0); + _vcm->SetChannelParameters(2000000, 0, 0); _vcm->RegisterTransportCallback(_encodeCompleteCallback); // up to here - _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 20); + _vcm->SetChannelParameters(static_cast(1000 * _bitRate), 0, 20); _encodeCompleteCallback->Initialize(); sendStats.SetTargetFrameRate(static_cast(_frameRate)); _vcm->RegisterSendStatisticsCallback(&sendStats); diff --git a/webrtc/modules/video_coding/main/test/media_opt_test.cc b/webrtc/modules/video_coding/main/test/media_opt_test.cc index 7d492c9a1f..59f3204200 100644 --- a/webrtc/modules/video_coding/main/test/media_opt_test.cc +++ b/webrtc/modules/video_coding/main/test/media_opt_test.cc @@ -290,7 +290,8 @@ MediaOptTest::Perform() // START TEST I420VideoFrame sourceFrame; WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame]; - _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, (WebRtc_UWord8)_lossRate, _rttMS); + _vcm->SetChannelParameters(static_cast(1000 * _bitRate), + (WebRtc_UWord8)_lossRate, _rttMS); _vcm->RegisterReceiveCallback(&receiveCallback); _frameCnt = 0; diff --git a/webrtc/modules/video_coding/main/test/mt_rx_tx_test.cc b/webrtc/modules/video_coding/main/test/mt_rx_tx_test.cc index f91f1a8e3b..b135169ff0 100644 --- a/webrtc/modules/video_coding/main/test/mt_rx_tx_test.cc +++ b/webrtc/modules/video_coding/main/test/mt_rx_tx_test.cc @@ -89,7 +89,7 @@ bool IntSenderThread(void* obj) { SendSharedState* state = static_cast(obj); - state->_vcm.SetChannelParameters(1000,30,0); + state->_vcm.SetChannelParameters(1000000,30,0); return true; } @@ -239,7 +239,7 @@ int MTRxTxTest(CmdArgs& args) rtp->SetFecParameters(&delta_params, &key_params); rtp->SetNACKStatus(nackEnabled ? kNackRtcp : kNackOff, kMaxPacketAgeToNack); - vcm->SetChannelParameters((WebRtc_UWord32) bitRate, + vcm->SetChannelParameters(static_cast(1000 * bitRate), (WebRtc_UWord8) lossRate, rttMS); SharedRTPState mtState(*vcm, *rtp); // receive side diff --git a/webrtc/modules/video_coding/main/test/normal_test.cc b/webrtc/modules/video_coding/main/test/normal_test.cc index 468946285c..853d13c647 100644 --- a/webrtc/modules/video_coding/main/test/normal_test.cc +++ b/webrtc/modules/video_coding/main/test/normal_test.cc @@ -278,7 +278,7 @@ NormalTest::Perform(const CmdArgs& args) _width, half_width, half_width); WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame]; double startTime = clock()/(double)CLOCKS_PER_SEC; - _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 0); + _vcm->SetChannelParameters(static_cast(1000 * _bitRate), 0, 0); SendStatsTest sendStats; sendStats.SetTargetFrameRate(static_cast(_frameRate)); diff --git a/webrtc/modules/video_coding/main/test/quality_modes_test.cc b/webrtc/modules/video_coding/main/test/quality_modes_test.cc index a382374388..3c9669c26c 100644 --- a/webrtc/modules/video_coding/main/test/quality_modes_test.cc +++ b/webrtc/modules/video_coding/main/test/quality_modes_test.cc @@ -239,7 +239,7 @@ QualityModesTest::Perform(const CmdArgs& args) I420VideoFrame *decimatedFrame = NULL; WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame]; double startTime = clock()/(double)CLOCKS_PER_SEC; - _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 0); + _vcm->SetChannelParameters(static_cast(1000 * _bitRate), 0, 0); SendStatsTest sendStats; sendStats.SetTargetFrameRate(static_cast(_frameRate)); @@ -334,7 +334,8 @@ QualityModesTest::Perform(const CmdArgs& args) // this will trigger QMSelect if (_frameCnt%((int)_frameRate) == 0) { - _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 1); + _vcm->SetChannelParameters(static_cast(1000 * _bitRate), 0, + 1); } // check for bit rate update diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index 3d40776c53..386f262947 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -920,8 +920,8 @@ void ViEEncoder::OnNetworkChanged(const uint32_t bitrate_bps, "%s(bitrate_bps: %u, fraction_lost: %u, rtt_ms: %u", __FUNCTION__, bitrate_bps, fraction_lost, round_trip_time_ms); + vcm_.SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); int bitrate_kbps = bitrate_bps / 1000; - vcm_.SetChannelParameters(bitrate_kbps, fraction_lost, round_trip_time_ms); paced_sender_->UpdateBitrate(bitrate_kbps); default_rtp_rtcp_->SetTargetSendBitrate(bitrate_bps); }