From 439be29445b63ea992fb430bc21cb83afb4581f9 Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Thu, 16 Feb 2012 14:45:37 +0000 Subject: [PATCH] Add APIs for getting receive-side estimated bandwidth and codec target rate. BUG= TEST= Review URL: https://webrtc-codereview.appspot.com/391012 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1704 4adac7df-926f-26a2-2b94-8c16560cd09d --- src/modules/rtp_rtcp/interface/rtp_rtcp.h | 8 ++- src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h | 4 +- .../rtp_rtcp/source/remote_rate_control.cc | 12 ++-- .../rtp_rtcp/source/remote_rate_control.h | 16 +++-- src/modules/rtp_rtcp/source/rtcp_sender.cc | 9 ++- src/modules/rtp_rtcp/source/rtcp_sender.h | 6 +- src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 12 +++- src/modules/rtp_rtcp/source/rtp_rtcp_impl.h | 6 +- .../main/interface/video_coding.h | 14 ++-- .../main/source/video_coding_impl.cc | 46 ++++++------ .../main/source/video_coding_impl.h | 4 +- src/video_engine/include/vie_codec.h | 6 +- src/video_engine/include/vie_rtp_rtcp.h | 9 ++- .../auto_test/source/vie_autotest_codec.cc | 7 +- .../auto_test/source/vie_autotest_rtp_rtcp.cc | 10 ++- src/video_engine/vie_channel.cc | 5 ++ src/video_engine/vie_channel.h | 1 + src/video_engine/vie_codec_impl.cc | 22 +++++- src/video_engine/vie_codec_impl.h | 4 +- src/video_engine/vie_encoder.cc | 72 ++++++++++++++----- src/video_engine/vie_encoder.h | 8 ++- src/video_engine/vie_rtp_rtcp_impl.cc | 24 ++++++- src/video_engine/vie_rtp_rtcp_impl.h | 5 +- 23 files changed, 227 insertions(+), 83 deletions(-) diff --git a/src/modules/rtp_rtcp/interface/rtp_rtcp.h b/src/modules/rtp_rtcp/interface/rtp_rtcp.h index 057d1ab93..ab67164ff 100644 --- a/src/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/src/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -569,7 +569,13 @@ public: /* * Get the send-side estimate of the available bandwidth. */ - virtual int EstimatedBandwidth( + virtual int EstimatedSendBandwidth( + WebRtc_UWord32* available_bandwidth) const = 0; + + /* + * Get the receive-side estimate of the available bandwidth. + */ + virtual int EstimatedReceiveBandwidth( WebRtc_UWord32* available_bandwidth) const = 0; /* diff --git a/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index 660fd4ab4..68d5d9b3d 100644 --- a/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/src/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -142,7 +142,9 @@ class MockRtpRtcp : public RtpRtcp { bool()); MOCK_CONST_METHOD4(BitrateSent, void(WebRtc_UWord32* totalRate, WebRtc_UWord32* videoRate, WebRtc_UWord32* fecRate, WebRtc_UWord32* nackRate)); - MOCK_CONST_METHOD1(EstimatedBandwidth, + MOCK_CONST_METHOD1(EstimatedSendBandwidth, + int(WebRtc_UWord32* available_bandwidth)); + MOCK_CONST_METHOD1(EstimatedReceiveBandwidth, int(WebRtc_UWord32* available_bandwidth)); MOCK_METHOD7(SendOutgoingData, WebRtc_Word32(const FrameType frameType, const WebRtc_Word8 payloadType, const WebRtc_UWord32 timeStamp, const WebRtc_UWord8* payloadData, const WebRtc_UWord32 payloadSize, const RTPFragmentationHeader* fragmentation, const RTPVideoHeader* rtpVideoHdr)); diff --git a/src/modules/rtp_rtcp/source/remote_rate_control.cc b/src/modules/rtp_rtcp/source/remote_rate_control.cc index dc3a49fe9..fe8477c6b 100644 --- a/src/modules/rtp_rtcp/source/remote_rate_control.cc +++ b/src/modules/rtp_rtcp/source/remote_rate_control.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -79,7 +79,7 @@ void RemoteRateControl::Reset() _initializedBitRate = false; } -bool RemoteRateControl::ValidEstimate() { +bool RemoteRateControl::ValidEstimate() const { return _initializedBitRate; } @@ -95,8 +95,12 @@ WebRtc_Word32 RemoteRateControl::SetConfiguredBitRates(WebRtc_UWord32 minBitRate return 0; } -WebRtc_UWord32 RemoteRateControl::TargetBitRate(WebRtc_UWord32 RTT, - WebRtc_Word64 nowMS) +WebRtc_UWord32 RemoteRateControl::LatestEstimate() const { + return _currentBitRate; +} + +WebRtc_UWord32 RemoteRateControl::UpdateBandwidthEstimate(WebRtc_UWord32 RTT, + WebRtc_Word64 nowMS) { _currentBitRate = ChangeBitRate(_currentBitRate, _currentInput._incomingBitRate, _currentInput._noiseVar, RTT, nowMS); diff --git a/src/modules/rtp_rtcp/source/remote_rate_control.h b/src/modules/rtp_rtcp/source/remote_rate_control.h index 973ca074c..197bf223c 100644 --- a/src/modules/rtp_rtcp/source/remote_rate_control.h +++ b/src/modules/rtp_rtcp/source/remote_rate_control.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -24,22 +24,28 @@ class RemoteRateControl public: RemoteRateControl(); ~RemoteRateControl(); - WebRtc_Word32 SetConfiguredBitRates(WebRtc_UWord32 minBitRate, WebRtc_UWord32 maxBitRate); - WebRtc_UWord32 TargetBitRate(WebRtc_UWord32 RTT, WebRtc_Word64 nowMS); + WebRtc_Word32 SetConfiguredBitRates(WebRtc_UWord32 minBitRate, + WebRtc_UWord32 maxBitRate); + WebRtc_UWord32 LatestEstimate() const; + WebRtc_UWord32 UpdateBandwidthEstimate(WebRtc_UWord32 RTT, + WebRtc_Word64 nowMS); RateControlRegion Update(const RateControlInput& input, bool& firstOverUse, WebRtc_Word64 nowMS); void Reset(); // Returns true if there is a valid estimate of the incoming bitrate, false // otherwise. - bool ValidEstimate(); + bool ValidEstimate() const; private: WebRtc_UWord32 ChangeBitRate(WebRtc_UWord32 currentBitRate, WebRtc_UWord32 incomingBitRate, double delayFactor, WebRtc_UWord32 RTT, WebRtc_Word64 nowMS); - double RateIncreaseFactor(WebRtc_Word64 nowMs, WebRtc_Word64 lastMs, WebRtc_UWord32 reactionTimeMs, double noiseVar) const; + double RateIncreaseFactor(WebRtc_Word64 nowMs, + WebRtc_Word64 lastMs, + WebRtc_UWord32 reactionTimeMs, + double noiseVar) const; void UpdateChangePeriod(WebRtc_Word64 nowMs); void UpdateMaxBitRateEstimate(float incomingBitRateKbps); void ChangeState(const RateControlInput& input, WebRtc_Word64 nowMs); diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.cc b/src/modules/rtp_rtcp/source/rtcp_sender.cc index 9f58259cb..88c8cee5e 100644 --- a/src/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/src/modules/rtp_rtcp/source/rtcp_sender.cc @@ -1107,13 +1107,18 @@ RTCPSender::CalculateNewTargetBitrate(WebRtc_UWord32 RTT) { CriticalSectionScoped lock(_criticalSectionRTCPSender); WebRtc_UWord32 target_bitrate = - _remoteRateControl.TargetBitRate(RTT, _clock.GetTimeInMS()); + _remoteRateControl.UpdateBandwidthEstimate(RTT, _clock.GetTimeInMS()); _tmmbr_Send = target_bitrate / 1000; return target_bitrate; } +WebRtc_UWord32 RTCPSender::LatestBandwidthEstimate() const { + CriticalSectionScoped lock(_criticalSectionRTCPSender); + return _remoteRateControl.LatestEstimate(); +} + bool -RTCPSender::ValidBitrateEstimate() { +RTCPSender::ValidBitrateEstimate() const { CriticalSectionScoped lock(_criticalSectionRTCPSender); return _remoteRateControl.ValidEstimate(); } diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.h b/src/modules/rtp_rtcp/source/rtcp_sender.h index 0684d224d..4c4f64a9f 100644 --- a/src/modules/rtp_rtcp/source/rtcp_sender.h +++ b/src/modules/rtp_rtcp/source/rtcp_sender.h @@ -135,13 +135,15 @@ public: WebRtc_UWord32 CalculateNewTargetBitrate(WebRtc_UWord32 RTT); + WebRtc_UWord32 LatestBandwidthEstimate() const; + // Returns true if there is a valid estimate of the incoming bitrate, false // otherwise. - bool ValidBitrateEstimate(); + bool ValidBitrateEstimate() const; private: WebRtc_Word32 SendToNetwork(const WebRtc_UWord8* dataBuffer, - const WebRtc_UWord16 length); + const WebRtc_UWord16 length); void UpdatePacketRate(); diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 280f5facb..3f771f09a 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -2326,11 +2326,19 @@ void ModuleRtpRtcpImpl::BitrateSent(WebRtc_UWord32* totalRate, *nackRate = _rtpSender.NackOverheadRate(); } -int ModuleRtpRtcpImpl::EstimatedBandwidth( - WebRtc_UWord32* available_bandwidth) const { +int ModuleRtpRtcpImpl::EstimatedSendBandwidth( + WebRtc_UWord32* available_bandwidth) const { return _bandwidthManagement.AvailableBandwidth(available_bandwidth); } +int ModuleRtpRtcpImpl::EstimatedReceiveBandwidth( + WebRtc_UWord32* available_bandwidth) const { + if (!_rtcpSender.ValidBitrateEstimate()) + return -1; + *available_bandwidth = _rtcpSender.LatestBandwidthEstimate(); + return 0; +} + // for lip sync void ModuleRtpRtcpImpl::OnReceivedNTP() { // don't do anything if we are the audio module diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h index eeba3376c..e7ea41a47 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -491,7 +491,11 @@ public: WebRtc_UWord32* fecRate, WebRtc_UWord32* nackRate) const; - virtual int EstimatedBandwidth(WebRtc_UWord32* available_bandwidth) const; + virtual int EstimatedSendBandwidth( + WebRtc_UWord32* available_bandwidth) const; + + virtual int EstimatedReceiveBandwidth( + WebRtc_UWord32* available_bandwidth) const; virtual void SetRemoteSSRC(const WebRtc_UWord32 SSRC); diff --git a/src/modules/video_coding/main/interface/video_coding.h b/src/modules/video_coding/main/interface/video_coding.h index 38d35f3a8..54e674207 100644 --- a/src/modules/video_coding/main/interface/video_coding.h +++ b/src/modules/video_coding/main/interface/video_coding.h @@ -146,17 +146,17 @@ public: // < 0, on error. virtual WebRtc_Word32 CodecConfigParameters(WebRtc_UWord8* buffer, WebRtc_Word32 size) = 0; - // API to get currently configured encoder target bit rate. + // API to get currently configured encoder target bitrate in kbit/s. // - // Return value : The encoder target bit rate, on success. - // < 0, on error. - virtual WebRtc_UWord32 Bitrate() const = 0; + // Return value : 0, on success. + // < 0, on error. + virtual int Bitrate(unsigned int* bitrate) const = 0; // API to get currently configured encoder target frame rate. // - // Return value : The encoder target frame rate, on success. - // < 0, on error. - virtual WebRtc_UWord32 FrameRate() const = 0; + // Return value : 0, on success. + // < 0, on error. + virtual int FrameRate(unsigned int* framerate) const = 0; // Sets the parameters describing the send channel. These parameters are inputs to the // Media Optimization inside the VCM and also specifies the target bit rate for the diff --git a/src/modules/video_coding/main/source/video_coding_impl.cc b/src/modules/video_coding/main/source/video_coding_impl.cc index 2dc43d672..3b5c25ca8 100644 --- a/src/modules/video_coding/main/source/video_coding_impl.cc +++ b/src/modules/video_coding/main/source/video_coding_impl.cc @@ -471,37 +471,35 @@ VideoCodingModuleImpl::CodecConfigParameters(WebRtc_UWord8* buffer, } // Get encode bitrate -WebRtc_UWord32 -VideoCodingModuleImpl::Bitrate() const +int VideoCodingModuleImpl::Bitrate(unsigned int* bitrate) const { - WEBRTC_TRACE(webrtc::kTraceModuleCall, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Bitrate()"); - CriticalSectionScoped cs(_sendCritSect); - // return the bit rate which the encoder is set to - if (_encoder != NULL) - { - return _encoder->BitRate(); - } + WEBRTC_TRACE(webrtc::kTraceModuleCall, + webrtc::kTraceVideoCoding, + VCMId(_id), + "Bitrate()"); + CriticalSectionScoped cs(_sendCritSect); + // return the bit rate which the encoder is set to + if (!_encoder) { return VCM_UNINITIALIZED; + } + *bitrate = _encoder->BitRate(); + return 0; } // Get encode frame rate -WebRtc_UWord32 -VideoCodingModuleImpl::FrameRate() const +int VideoCodingModuleImpl::FrameRate(unsigned int* framerate) const { - WEBRTC_TRACE(webrtc::kTraceModuleCall, - webrtc::kTraceVideoCoding, - VCMId(_id), - "FrameRate()"); - CriticalSectionScoped cs(_sendCritSect); - // input frame rate, not compensated - if (_encoder != NULL) - { - return _encoder->FrameRate(); - } + WEBRTC_TRACE(webrtc::kTraceModuleCall, + webrtc::kTraceVideoCoding, + VCMId(_id), + "FrameRate()"); + CriticalSectionScoped cs(_sendCritSect); + // input frame rate, not compensated + if (!_encoder) { return VCM_UNINITIALIZED; + } + *framerate = _encoder->FrameRate(); + return 0; } // Set channel parameters diff --git a/src/modules/video_coding/main/source/video_coding_impl.h b/src/modules/video_coding/main/source/video_coding_impl.h index 5ce95719f..490c84790 100644 --- a/src/modules/video_coding/main/source/video_coding_impl.h +++ b/src/modules/video_coding/main/source/video_coding_impl.h @@ -102,10 +102,10 @@ public: WebRtc_Word32 size); // Get encode bitrate - virtual WebRtc_UWord32 Bitrate() const; + virtual int Bitrate(unsigned int* bitrate) const; // Get encode frame rate - virtual WebRtc_UWord32 FrameRate() const; + virtual int FrameRate(unsigned int* framerate) const; // Set channel parameters virtual WebRtc_Word32 SetChannelParameters( diff --git a/src/video_engine/include/vie_codec.h b/src/video_engine/include/vie_codec.h index 08d1cc56b..0535038e6 100644 --- a/src/video_engine/include/vie_codec.h +++ b/src/video_engine/include/vie_codec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -124,6 +124,10 @@ class WEBRTC_DLLEXPORT ViECodec { unsigned int& key_frames, unsigned int& delta_frames) const = 0; + // Gets the bitrate targeted by the video codec rate control in kbit/s. + virtual int GetCodecTargetBitrate(const int video_channel, + unsigned int* bitrate) const = 0; + // Gets the number of packets discarded by the jitter buffer because they // arrived too late. virtual unsigned int GetDiscardedPackets(const int video_channel) const = 0; diff --git a/src/video_engine/include/vie_rtp_rtcp.h b/src/video_engine/include/vie_rtp_rtcp.h index edb307a6a..1397222a6 100644 --- a/src/video_engine/include/vie_rtp_rtcp.h +++ b/src/video_engine/include/vie_rtp_rtcp.h @@ -246,7 +246,14 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP { // This function gets the send-side estimated bandwidth available for video, // including overhead, in bits/s. - virtual int GetEstimatedBandwidth( + virtual int GetEstimatedSendBandwidth( + const int video_channel, + unsigned int* estimated_bandwidth) const = 0; + + // This function gets the receive-side estimated bandwidth available for + // video, including overhead, in bits/s. + // Returns -1 when no valid estimate is available. + virtual int GetEstimatedReceiveBandwidth( const int video_channel, unsigned int* estimated_bandwidth) const = 0; diff --git a/src/video_engine/test/auto_test/source/vie_autotest_codec.cc b/src/video_engine/test/auto_test/source/vie_autotest_codec.cc index 580d0a4da..6bbeb2b31 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_codec.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_codec.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -359,6 +359,11 @@ void ViEAutoTest::ViECodecAPITest() memset(&videoCodec, 0, sizeof(videoCodec)); EXPECT_EQ(0, ptrViECodec->GetSendCodec(videoChannel, videoCodec)); EXPECT_EQ(webrtc::kVideoCodecVP8, videoCodec.codecType); + // Verify that the target bit rate is equal to the start bitrate. + unsigned int target_bitrate = 0; + EXPECT_EQ(0, ptrViECodec->GetCodecTargetBitrate(videoChannel, + &target_bitrate)); + EXPECT_EQ(videoCodec.startBitrate, target_bitrate); SetSendCodec(webrtc::kVideoCodecI420, ptrViECodec, videoChannel, kDoNotForceResolution, kDoNotForceResolution); diff --git a/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc b/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc index 7a543c9f0..0059c7c6d 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc @@ -222,8 +222,14 @@ void ViEAutoTest::ViERtpRtcpStandardTest() EXPECT_GT(recRttMs, 0); unsigned int estimated_bandwidth = 0; - EXPECT_EQ(0, ViE.rtp_rtcp->GetEstimatedBandwidth(tbChannel.videoChannel, - &estimated_bandwidth)); + EXPECT_EQ(0, ViE.rtp_rtcp->GetEstimatedSendBandwidth( + tbChannel.videoChannel, + &estimated_bandwidth)); + EXPECT_GT(estimated_bandwidth, 0u); + + EXPECT_EQ(0, ViE.rtp_rtcp->GetEstimatedReceiveBandwidth( + tbChannel.videoChannel, + &estimated_bandwidth)); EXPECT_GT(estimated_bandwidth, 0u); // Check that rec stats extended max is greater than what we've sent. diff --git a/src/video_engine/vie_channel.cc b/src/video_engine/vie_channel.cc index 4d763b3ea..3c34786f5 100644 --- a/src/video_engine/vie_channel.cc +++ b/src/video_engine/vie_channel.cc @@ -1054,6 +1054,11 @@ void ViEChannel::GetBandwidthUsage(WebRtc_UWord32& total_bitrate_sent, } } +int ViEChannel::GetEstimatedReceiveBandwidth( + WebRtc_UWord32* estimated_bandwidth) const { + return rtp_rtcp_.EstimatedReceiveBandwidth(estimated_bandwidth); +} + WebRtc_Word32 ViEChannel::SetKeepAliveStatus( const bool enable, const WebRtc_Word8 unknown_payload_type, diff --git a/src/video_engine/vie_channel.h b/src/video_engine/vie_channel.h index b48ed1fda..dac268f5f 100644 --- a/src/video_engine/vie_channel.h +++ b/src/video_engine/vie_channel.h @@ -162,6 +162,7 @@ class ViEChannel WebRtc_UWord32& video_bitrate_sent, WebRtc_UWord32& fec_bitrate_sent, WebRtc_UWord32& nackBitrateSent) const; + int GetEstimatedReceiveBandwidth(WebRtc_UWord32* estimated_bandwidth) const; WebRtc_Word32 SetKeepAliveStatus(const bool enable, const WebRtc_Word8 unknown_payload_type, const WebRtc_UWord16 delta_transmit_timeMS); diff --git a/src/video_engine/vie_codec_impl.cc b/src/video_engine/vie_codec_impl.cc index da5c677b8..f99511790 100644 --- a/src/video_engine/vie_codec_impl.cc +++ b/src/video_engine/vie_codec_impl.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -459,6 +459,26 @@ int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel, return 0; } +int ViECodecImpl::GetCodecTargetBitrate(const int video_channel, + unsigned int* bitrate) const { + WEBRTC_TRACE(kTraceApiCall, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s(video_channel: %d, codec_type: %d)", __FUNCTION__, + video_channel); + + ViEChannelManagerScoped cs(*(shared_data_->channel_manager())); + ViEEncoder* vie_encoder = cs.Encoder(video_channel); + if (!vie_encoder) { + WEBRTC_TRACE(kTraceError, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s: No send codec for channel %d", __FUNCTION__, + video_channel); + shared_data_->SetLastError(kViECodecInvalidChannelId); + return -1; + } + return vie_encoder->CodecTargetBitrate(static_cast(bitrate)); +} + unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const { WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id(), video_channel), diff --git a/src/video_engine/vie_codec_impl.h b/src/video_engine/vie_codec_impl.h index af9d0dca1..e0e5e9489 100644 --- a/src/video_engine/vie_codec_impl.h +++ b/src/video_engine/vie_codec_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -49,6 +49,8 @@ class ViECodecImpl virtual int GetReceiveCodecStastistics(const int video_channel, unsigned int& key_frames, unsigned int& delta_frames) const; + virtual int GetCodecTargetBitrate(const int video_channel, + unsigned int* bitrate) const; virtual unsigned int GetDiscardedPackets(const int video_channel) const; virtual int SetKeyFrameRequestCallbackStatus(const int video_channel, const bool enable); diff --git a/src/video_engine/vie_encoder.cc b/src/video_engine/vie_encoder.cc index c80b5be74..cf3587b0d 100644 --- a/src/video_engine/vie_encoder.cc +++ b/src/video_engine/vie_encoder.cc @@ -26,13 +26,15 @@ namespace webrtc { -class QMTestVideoSettingsCallback : public VCMQMSettingsCallback { +class QMVideoSettingsCallback : public VCMQMSettingsCallback { public: - QMTestVideoSettingsCallback(VideoProcessingModule* vpm, - VideoCodingModule* vcm, - WebRtc_Word32 num_of_cores, - WebRtc_Word32 max_payload_length); - ~QMTestVideoSettingsCallback(); + QMVideoSettingsCallback(WebRtc_Word32 engine_id, + WebRtc_Word32 channel_id, + VideoProcessingModule* vpm, + VideoCodingModule* vcm, + WebRtc_Word32 num_of_cores, + WebRtc_Word32 max_payload_length); + ~QMVideoSettingsCallback(); // Update VPM with QM (quality modes: frame size & frame rate) settings. WebRtc_Word32 SetVideoQMSettings(const WebRtc_UWord32 frame_rate, @@ -42,6 +44,8 @@ class QMTestVideoSettingsCallback : public VCMQMSettingsCallback { void SetMaxPayloadLength(WebRtc_Word32 max_payload_length); private: + WebRtc_Word32 engine_id_; + WebRtc_Word32 channel_id_; VideoProcessingModule* vpm_; VideoCodingModule* vcm_; WebRtc_Word32 num_cores_; @@ -100,8 +104,13 @@ ViEEncoder::ViEEncoder(WebRtc_Word32 engine_id, WebRtc_Word32 channel_id, default_rtp_rtcp_.RegisterIncomingRTCPCallback(this); module_process_thread_.RegisterModule(&default_rtp_rtcp_); - qm_callback_ = new QMTestVideoSettingsCallback( - &vpm_, &vcm_, number_of_cores, default_rtp_rtcp_.MaxDataPayloadLength()); + qm_callback_ = new QMVideoSettingsCallback( + engine_id_, + channel_id_, + &vpm_, + &vcm_, + number_of_cores, + default_rtp_rtcp_.MaxDataPayloadLength()); #ifdef VIDEOCODEC_VP8 VideoCodec video_codec; @@ -240,7 +249,11 @@ WebRtc_Word32 ViEEncoder::DeRegisterExternalEncoder(WebRtc_UWord8 pl_type) { webrtc::VideoCodec current_send_codec; if (vcm_.SendCodec(¤t_send_codec) == VCM_OK) { - current_send_codec.startBitrate = vcm_.Bitrate(); + if (vcm_.Bitrate(¤t_send_codec.startBitrate) != 0) { + WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, + ViEId(engine_id_, channel_id_), + "Failed to get the current encoder target bitrate."); + } } if (vcm_.RegisterExternalEncoder(NULL, pl_type) != VCM_OK) { @@ -560,11 +573,19 @@ WebRtc_Word32 ViEEncoder::SendCodecStatistics( return 0; } -WebRtc_Word32 ViEEncoder::EstimatedBandwidth( +WebRtc_Word32 ViEEncoder::EstimatedSendBandwidth( WebRtc_UWord32* available_bandwidth) const { WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s", __FUNCTION__); - return default_rtp_rtcp_.EstimatedBandwidth(available_bandwidth); + return default_rtp_rtcp_.EstimatedSendBandwidth(available_bandwidth); +} + +int ViEEncoder::CodecTargetBitrate(WebRtc_UWord32* bitrate) const { + WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s", + __FUNCTION__); + if (vcm_.Bitrate(bitrate) != 0) + return -1; + return 0; } WebRtc_Word32 ViEEncoder::UpdateProtectionMethod() { @@ -607,7 +628,11 @@ WebRtc_Word32 ViEEncoder::UpdateProtectionMethod() { webrtc::VideoCodec codec; if (vcm_.SendCodec(&codec) == 0) { WebRtc_UWord16 max_pay_load = default_rtp_rtcp_.MaxDataPayloadLength(); - codec.startBitrate = vcm_.Bitrate(); + if (vcm_.Bitrate(&codec.startBitrate) != 0) { + WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, + ViEId(engine_id_, channel_id_), + "Failed to get the current encoder target bitrate."); + } if (vcm_.RegisterSendCodec(&codec, number_of_cores_, max_pay_load) != 0) { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_, channel_id_), @@ -805,21 +830,25 @@ ViEFileRecorder& ViEEncoder::GetOutgoingFileRecorder() { return file_recorder_; } -QMTestVideoSettingsCallback::QMTestVideoSettingsCallback( +QMVideoSettingsCallback::QMVideoSettingsCallback( + WebRtc_Word32 engine_id, + WebRtc_Word32 channel_id, VideoProcessingModule* vpm, VideoCodingModule* vcm, WebRtc_Word32 num_cores, WebRtc_Word32 max_payload_length) - : vpm_(vpm), + : engine_id_(engine_id), + channel_id_(channel_id), + vpm_(vpm), vcm_(vcm), num_cores_(num_cores), max_payload_length_(max_payload_length) { } -QMTestVideoSettingsCallback::~QMTestVideoSettingsCallback() { +QMVideoSettingsCallback::~QMVideoSettingsCallback() { } -WebRtc_Word32 QMTestVideoSettingsCallback::SetVideoQMSettings( +WebRtc_Word32 QMVideoSettingsCallback::SetVideoQMSettings( const WebRtc_UWord32 frame_rate, const WebRtc_UWord32 width, const WebRtc_UWord32 height) { @@ -830,9 +859,14 @@ WebRtc_Word32 QMTestVideoSettingsCallback::SetVideoQMSettings( // Get current settings. VideoCodec current_codec; vcm_->SendCodec(¤t_codec); - WebRtc_UWord32 current_bit_rate = vcm_->Bitrate(); + WebRtc_UWord32 current_bit_rate; + if (vcm_->Bitrate(¤t_bit_rate) != 0) { + WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, + ViEId(engine_id_, channel_id_), + "Failed to get the current encoder target bitrate."); + } - // Set the new calues. + // Set the new values. current_codec.height = static_cast(height); current_codec.width = static_cast(width); current_codec.maxFramerate = static_cast(frame_rate); @@ -845,7 +879,7 @@ WebRtc_Word32 QMTestVideoSettingsCallback::SetVideoQMSettings( return ret_val; } -void QMTestVideoSettingsCallback::SetMaxPayloadLength( +void QMVideoSettingsCallback::SetMaxPayloadLength( WebRtc_Word32 max_payload_length) { max_payload_length_ = max_payload_length; } diff --git a/src/video_engine/vie_encoder.h b/src/video_engine/vie_encoder.h index 9afdaac6e..1b204911f 100644 --- a/src/video_engine/vie_encoder.h +++ b/src/video_engine/vie_encoder.h @@ -25,7 +25,7 @@ namespace webrtc { class CriticalSectionWrapper; class ProcessThread; -class QMTestVideoSettingsCallback; +class QMVideoSettingsCallback; class RtpRtcp; class VideoCodingModule; class ViEEffectFilter; @@ -88,7 +88,9 @@ class ViEEncoder WebRtc_Word32 SendKeyFrame(); WebRtc_Word32 SendCodecStatistics(WebRtc_UWord32& num_key_frames, WebRtc_UWord32& num_delta_frames); - WebRtc_Word32 EstimatedBandwidth(WebRtc_UWord32* available_bandwidth) const; + WebRtc_Word32 EstimatedSendBandwidth( + WebRtc_UWord32* available_bandwidth) const; + int CodecTargetBitrate(WebRtc_UWord32* bitrate) const; // Loss protection. WebRtc_Word32 UpdateProtectionMethod(); @@ -172,7 +174,7 @@ class ViEEncoder ViEFileRecorder file_recorder_; // Quality modes callback - QMTestVideoSettingsCallback* qm_callback_; + QMVideoSettingsCallback* qm_callback_; }; } // namespace webrtc diff --git a/src/video_engine/vie_rtp_rtcp_impl.cc b/src/video_engine/vie_rtp_rtcp_impl.cc index a539a8e2f..497481c68 100644 --- a/src/video_engine/vie_rtp_rtcp_impl.cc +++ b/src/video_engine/vie_rtp_rtcp_impl.cc @@ -727,7 +727,7 @@ int ViERTP_RTCPImpl::GetBandwidthUsage(const int video_channel, return 0; } -int ViERTP_RTCPImpl::GetEstimatedBandwidth( +int ViERTP_RTCPImpl::GetEstimatedSendBandwidth( const int video_channel, unsigned int* estimated_bandwidth) const { WEBRTC_TRACE(kTraceApiCall, kTraceVideo, @@ -743,7 +743,27 @@ int ViERTP_RTCPImpl::GetEstimatedBandwidth( shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); return -1; } - return vie_encoder->EstimatedBandwidth( + return vie_encoder->EstimatedSendBandwidth( + static_cast(estimated_bandwidth)); +} + +int ViERTP_RTCPImpl::GetEstimatedReceiveBandwidth( + const int video_channel, + unsigned int* estimated_bandwidth) const { + WEBRTC_TRACE(kTraceApiCall, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s(channel: %d)", __FUNCTION__, video_channel); + ViEChannelManagerScoped cs(*(shared_data_->channel_manager())); + ViEChannel* vie_channel = cs.Channel(video_channel); + if (!vie_channel) { + WEBRTC_TRACE(kTraceError, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s: Could not get channel %d", __FUNCTION__, + video_channel); + shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); + return -1; + } + return vie_channel->GetEstimatedReceiveBandwidth( static_cast(estimated_bandwidth)); } diff --git a/src/video_engine/vie_rtp_rtcp_impl.h b/src/video_engine/vie_rtp_rtcp_impl.h index 89ea16c48..72e813159 100644 --- a/src/video_engine/vie_rtp_rtcp_impl.h +++ b/src/video_engine/vie_rtp_rtcp_impl.h @@ -87,7 +87,10 @@ class ViERTP_RTCPImpl unsigned int& video_bitrate_sent, unsigned int& fec_bitrate_sent, unsigned int& nackBitrateSent) const; - virtual int GetEstimatedBandwidth( + virtual int GetEstimatedSendBandwidth( + const int video_channel, + unsigned int* estimated_bandwidth) const; + virtual int GetEstimatedReceiveBandwidth( const int video_channel, unsigned int* estimated_bandwidth) const; virtual int SetRTPKeepAliveStatus(