Wire up BitrateAllocation to be sent as RTCP TargetBitrate
This is the video parts of https://codereview.webrtc.org/2531383002/
Wire up BitrateAllocation to be sent as RTCP TargetBitrate
BUG=webrtc:6301
Review-Url: https://codereview.webrtc.org/2541303003
Cr-Commit-Position: refs/heads/master@{#15359}
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 86c181b..4de6db4 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -125,7 +125,6 @@
void DecodesRetransmittedFrame(bool enable_rtx, bool enable_red);
void ReceivesPliAndRecovers(int rtp_history_ms);
void RespectsRtcpMode(RtcpMode rtcp_mode);
- void TestXrReceiverReferenceTimeReport(bool enable_rrtr);
void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first);
void TestRtpStatePreservation(bool use_rtx, bool provoke_rtcpsr_before_rtp);
void VerifyHistogramStats(bool use_rtx, bool use_red, bool screenshare);
@@ -2435,89 +2434,6 @@
VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
}
-void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
- static const int kNumRtcpReportPacketsToObserve = 5;
- class RtcpXrObserver : public test::EndToEndTest {
- public:
- explicit RtcpXrObserver(bool enable_rrtr)
- : EndToEndTest(kDefaultTimeoutMs),
- enable_rrtr_(enable_rrtr),
- sent_rtcp_sr_(0),
- sent_rtcp_rr_(0),
- sent_rtcp_rrtr_(0),
- sent_rtcp_dlrr_(0) {}
-
- private:
- // Receive stream should send RR packets (and RRTR packets if enabled).
- Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
- rtc::CritScope lock(&crit_);
- test::RtcpPacketParser parser;
- EXPECT_TRUE(parser.Parse(packet, length));
-
- sent_rtcp_rr_ += parser.receiver_report()->num_packets();
- EXPECT_EQ(0, parser.sender_report()->num_packets());
- EXPECT_GE(1, parser.xr()->num_packets());
- if (parser.xr()->num_packets() > 0) {
- if (parser.xr()->rrtr())
- ++sent_rtcp_rrtr_;
- EXPECT_FALSE(parser.xr()->dlrr());
- }
-
- return SEND_PACKET;
- }
- // Send stream should send SR packets (and DLRR packets if enabled).
- Action OnSendRtcp(const uint8_t* packet, size_t length) override {
- rtc::CritScope lock(&crit_);
- test::RtcpPacketParser parser;
- EXPECT_TRUE(parser.Parse(packet, length));
-
- sent_rtcp_sr_ += parser.sender_report()->num_packets();
- EXPECT_GE(1, parser.xr()->num_packets());
- if (parser.xr()->num_packets() > 0) {
- EXPECT_FALSE(parser.xr()->rrtr());
- if (parser.xr()->dlrr())
- ++sent_rtcp_dlrr_;
- }
-
- if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
- sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) {
- if (enable_rrtr_) {
- EXPECT_LT(0, sent_rtcp_rrtr_);
- EXPECT_LT(0, sent_rtcp_dlrr_);
- } else {
- EXPECT_EQ(0, sent_rtcp_rrtr_);
- EXPECT_EQ(0, sent_rtcp_dlrr_);
- }
- observation_complete_.Set();
- }
- return SEND_PACKET;
- }
-
- void ModifyVideoConfigs(
- VideoSendStream::Config* send_config,
- std::vector<VideoReceiveStream::Config>* receive_configs,
- VideoEncoderConfig* encoder_config) override {
- (*receive_configs)[0].rtp.rtcp_mode = RtcpMode::kReducedSize;
- (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
- enable_rrtr_;
- }
-
- void PerformTest() override {
- EXPECT_TRUE(Wait())
- << "Timed out while waiting for RTCP SR/RR packets to be sent.";
- }
-
- rtc::CriticalSection crit_;
- bool enable_rrtr_;
- int sent_rtcp_sr_;
- int sent_rtcp_rr_ GUARDED_BY(&crit_);
- int sent_rtcp_rrtr_ GUARDED_BY(&crit_);
- int sent_rtcp_dlrr_;
- } test(enable_rrtr);
-
- RunBaseTest(&test);
-}
-
void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
bool send_single_ssrc_first) {
class SendsSetSsrcs : public test::EndToEndTest {
@@ -3064,12 +2980,99 @@
RunBaseTest(&test);
}
-TEST_P(EndToEndTest, ReceiverReferenceTimeReportEnabled) {
- TestXrReceiverReferenceTimeReport(true);
+class RtcpXrObserver : public test::EndToEndTest {
+ public:
+ explicit RtcpXrObserver(bool enable_rrtr)
+ : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
+ enable_rrtr_(enable_rrtr),
+ sent_rtcp_sr_(0),
+ sent_rtcp_rr_(0),
+ sent_rtcp_rrtr_(0),
+ sent_rtcp_target_bitrate_(false),
+ sent_rtcp_dlrr_(0) {}
+
+ private:
+ // Receive stream should send RR packets (and RRTR packets if enabled).
+ Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
+ rtc::CritScope lock(&crit_);
+ test::RtcpPacketParser parser;
+ EXPECT_TRUE(parser.Parse(packet, length));
+
+ sent_rtcp_rr_ += parser.receiver_report()->num_packets();
+ EXPECT_EQ(0, parser.sender_report()->num_packets());
+ EXPECT_GE(1, parser.xr()->num_packets());
+ if (parser.xr()->num_packets() > 0) {
+ if (parser.xr()->rrtr())
+ ++sent_rtcp_rrtr_;
+ EXPECT_FALSE(parser.xr()->dlrr());
+ }
+
+ return SEND_PACKET;
+ }
+ // Send stream should send SR packets (and DLRR packets if enabled).
+ Action OnSendRtcp(const uint8_t* packet, size_t length) override {
+ rtc::CritScope lock(&crit_);
+ test::RtcpPacketParser parser;
+ EXPECT_TRUE(parser.Parse(packet, length));
+
+ sent_rtcp_sr_ += parser.sender_report()->num_packets();
+ EXPECT_LE(parser.xr()->num_packets(), 1);
+ if (parser.xr()->num_packets() > 0) {
+ EXPECT_FALSE(parser.xr()->rrtr());
+ if (parser.xr()->dlrr())
+ ++sent_rtcp_dlrr_;
+ if (parser.xr()->target_bitrate())
+ sent_rtcp_target_bitrate_ = true;
+ }
+
+ if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
+ sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve &&
+ sent_rtcp_target_bitrate_) {
+ if (enable_rrtr_) {
+ EXPECT_GT(sent_rtcp_rrtr_, 0);
+ EXPECT_GT(sent_rtcp_dlrr_, 0);
+ } else {
+ EXPECT_EQ(sent_rtcp_rrtr_, 0);
+ EXPECT_EQ(sent_rtcp_dlrr_, 0);
+ }
+ observation_complete_.Set();
+ }
+ return SEND_PACKET;
+ }
+
+ void ModifyVideoConfigs(
+ VideoSendStream::Config* send_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ VideoEncoderConfig* encoder_config) override {
+ (*receive_configs)[0].rtp.rtcp_mode = RtcpMode::kReducedSize;
+ (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
+ enable_rrtr_;
+ }
+
+ void PerformTest() override {
+ EXPECT_TRUE(Wait())
+ << "Timed out while waiting for RTCP SR/RR packets to be sent.";
+ }
+
+ static const int kNumRtcpReportPacketsToObserve = 5;
+
+ rtc::CriticalSection crit_;
+ bool enable_rrtr_;
+ int sent_rtcp_sr_;
+ int sent_rtcp_rr_ GUARDED_BY(&crit_);
+ int sent_rtcp_rrtr_ GUARDED_BY(&crit_);
+ bool sent_rtcp_target_bitrate_ GUARDED_BY(&crit_);
+ int sent_rtcp_dlrr_;
+};
+
+TEST_P(EndToEndTest, TestExtendedReportsWithRrtr) {
+ RtcpXrObserver test(true);
+ RunBaseTest(&test);
}
-TEST_P(EndToEndTest, ReceiverReferenceTimeReportDisabled) {
- TestXrReceiverReferenceTimeReport(false);
+TEST_P(EndToEndTest, TestExtendedReportsWithoutRrtr) {
+ RtcpXrObserver test(false);
+ RunBaseTest(&test);
}
TEST_P(EndToEndTest, TestReceivedRtpPacketStats) {
diff --git a/webrtc/video/payload_router.cc b/webrtc/video/payload_router.cc
index 33d8f76..6c8e36f 100644
--- a/webrtc/video/payload_router.cc
+++ b/webrtc/video/payload_router.cc
@@ -101,7 +101,7 @@
return IP_PACKET_SIZE - kIpUdpSrtpLength;
}
-void PayloadRouter::set_active(bool active) {
+void PayloadRouter::SetActive(bool active) {
rtc::CritScope lock(&crit_);
if (active_ == active)
return;
@@ -113,7 +113,7 @@
}
}
-bool PayloadRouter::active() {
+bool PayloadRouter::IsActive() {
rtc::CritScope lock(&crit_);
return active_ && !rtp_modules_.empty();
}
@@ -158,4 +158,24 @@
return min_payload_length;
}
+void PayloadRouter::OnBitrateAllocationUpdated(
+ const BitrateAllocation& bitrate) {
+ rtc::CritScope lock(&crit_);
+ if (IsActive()) {
+ if (rtp_modules_.size() == 1) {
+ // If spatial scalability is enabled, it is covered by a single stream.
+ rtp_modules_[0]->SetVideoBitrateAllocation(bitrate);
+ } else {
+ // Simulcast is in use, split the BitrateAllocation into one struct per
+ // rtp stream, moving over the temporal layer allocation.
+ for (size_t si = 0; si < rtp_modules_.size(); ++si) {
+ BitrateAllocation layer_bitrate;
+ for (int tl = 0; tl < kMaxTemporalStreams; ++tl)
+ layer_bitrate.SetBitrate(0, tl, bitrate.GetBitrate(si, tl));
+ rtp_modules_[si]->SetVideoBitrateAllocation(layer_bitrate);
+ }
+ }
+ }
+}
+
} // namespace webrtc
diff --git a/webrtc/video/payload_router.h b/webrtc/video/payload_router.h
index 6426b00..3b60ce2 100644
--- a/webrtc/video/payload_router.h
+++ b/webrtc/video/payload_router.h
@@ -40,8 +40,8 @@
// PayloadRouter will only route packets if being active, all packets will be
// dropped otherwise.
- void set_active(bool active);
- bool active();
+ void SetActive(bool active);
+ bool IsActive();
// Implements EncodedImageCallback.
// Returns 0 if the packet was routed / sent, -1 otherwise.
@@ -54,6 +54,8 @@
// and RTP headers.
size_t MaxPayloadLength() const;
+ void OnBitrateAllocationUpdated(const BitrateAllocation& bitrate);
+
private:
void UpdateModuleSendingState() EXCLUSIVE_LOCKS_REQUIRED(crit_);
diff --git a/webrtc/video/payload_router_unittest.cc b/webrtc/video/payload_router_unittest.cc
index adddefe..935de5f 100644
--- a/webrtc/video/payload_router_unittest.cc
+++ b/webrtc/video/payload_router_unittest.cc
@@ -49,7 +49,7 @@
EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
- payload_router.set_active(true);
+ payload_router.SetActive(true);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
@@ -60,7 +60,7 @@
EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
- payload_router.set_active(false);
+ payload_router.SetActive(false);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
@@ -70,7 +70,7 @@
EncodedImageCallback::Result::OK,
payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
- payload_router.set_active(true);
+ payload_router.SetActive(true);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
@@ -106,7 +106,7 @@
codec_info_1.codecType = kVideoCodecVP8;
codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
- payload_router.set_active(true);
+ payload_router.SetActive(true);
EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
@@ -136,7 +136,7 @@
.error);
// Inactive.
- payload_router.set_active(false);
+ payload_router.SetActive(false);
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _))
.Times(0);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _))
@@ -182,4 +182,52 @@
.WillOnce(Return(kTestMinPayloadLength));
EXPECT_EQ(kTestMinPayloadLength, payload_router.MaxPayloadLength());
}
+
+TEST(PayloadRouterTest, SimulcastTargetBitrate) {
+ NiceMock<MockRtpRtcp> rtp_1;
+ NiceMock<MockRtpRtcp> rtp_2;
+ std::vector<RtpRtcp*> modules;
+ modules.push_back(&rtp_1);
+ modules.push_back(&rtp_2);
+ PayloadRouter payload_router(modules, 42);
+ payload_router.SetActive(true);
+
+ BitrateAllocation bitrate;
+ bitrate.SetBitrate(0, 0, 10000);
+ bitrate.SetBitrate(0, 1, 20000);
+ bitrate.SetBitrate(1, 0, 40000);
+ bitrate.SetBitrate(1, 1, 80000);
+
+ BitrateAllocation layer0_bitrate;
+ layer0_bitrate.SetBitrate(0, 0, 10000);
+ layer0_bitrate.SetBitrate(0, 1, 20000);
+
+ BitrateAllocation layer1_bitrate;
+ layer1_bitrate.SetBitrate(0, 0, 40000);
+ layer1_bitrate.SetBitrate(0, 1, 80000);
+
+ EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(layer0_bitrate)).Times(1);
+ EXPECT_CALL(rtp_2, SetVideoBitrateAllocation(layer1_bitrate)).Times(1);
+
+ payload_router.OnBitrateAllocationUpdated(bitrate);
+}
+
+TEST(PayloadRouterTest, SvcTargetBitrate) {
+ NiceMock<MockRtpRtcp> rtp_1;
+ std::vector<RtpRtcp*> modules;
+ modules.push_back(&rtp_1);
+ PayloadRouter payload_router(modules, 42);
+ payload_router.SetActive(true);
+
+ BitrateAllocation bitrate;
+ bitrate.SetBitrate(0, 0, 10000);
+ bitrate.SetBitrate(0, 1, 20000);
+ bitrate.SetBitrate(1, 0, 40000);
+ bitrate.SetBitrate(1, 1, 80000);
+
+ EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(bitrate)).Times(1);
+
+ payload_router.OnBitrateAllocationUpdated(bitrate);
+}
+
} // namespace webrtc
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index a1c1a0b..188854a 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -17,6 +17,7 @@
#include <vector>
#include "webrtc/common_types.h"
+#include "webrtc/common_video/include/video_bitrate_allocator.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/file.h"
#include "webrtc/base/logging.h"
@@ -289,7 +290,8 @@
class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
public webrtc::OverheadObserver,
public webrtc::VCMProtectionCallback,
- public ViEEncoder::EncoderSink {
+ public ViEEncoder::EncoderSink,
+ public VideoBitrateAllocationObserver {
public:
VideoSendStreamImpl(SendStatisticsProxy* stats_proxy,
rtc::TaskQueue* worker_queue,
@@ -357,6 +359,9 @@
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) override;
+ // Implements VideoBitrateAllocationObserver.
+ void OnBitrateAllocationUpdated(const BitrateAllocation& allocation) override;
+
void ConfigureProtection();
void ConfigureSsrcs();
void SignalEncoderTimedOut();
@@ -598,7 +603,6 @@
vie_encoder_.reset(new ViEEncoder(
num_cpu_cores, &stats_proxy_, config_.encoder_settings,
config_.pre_encode_callback, config_.post_encode_callback));
-
worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(new ConstructionTask(
&send_stream_, &thread_sync_event_, &stats_proxy_, vie_encoder_.get(),
module_process_thread, call_stats, congestion_controller, packet_router,
@@ -610,7 +614,7 @@
// it was created on.
thread_sync_event_.Wait(rtc::Event::kForever);
send_stream_->RegisterProcessThread(module_process_thread);
-
+ vie_encoder_->SetBitrateObserver(send_stream_.get());
vie_encoder_->RegisterProcessThread(module_process_thread);
ReconfigureVideoEncoder(std::move(encoder_config));
@@ -849,7 +853,7 @@
VideoSendStreamImpl::~VideoSendStreamImpl() {
RTC_DCHECK_RUN_ON(worker_queue_);
- RTC_DCHECK(!payload_router_.active())
+ RTC_DCHECK(!payload_router_.IsActive())
<< "VideoSendStreamImpl::Stop not called";
LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
@@ -873,10 +877,10 @@
void VideoSendStreamImpl::Start() {
RTC_DCHECK_RUN_ON(worker_queue_);
LOG(LS_INFO) << "VideoSendStream::Start";
- if (payload_router_.active())
+ if (payload_router_.IsActive())
return;
TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
- payload_router_.set_active(true);
+ payload_router_.SetActive(true);
bitrate_allocator_->AddObserver(
this, encoder_min_bitrate_bps_, encoder_max_bitrate_bps_,
@@ -898,10 +902,10 @@
void VideoSendStreamImpl::Stop() {
RTC_DCHECK_RUN_ON(worker_queue_);
LOG(LS_INFO) << "VideoSendStream::Stop";
- if (!payload_router_.active())
+ if (!payload_router_.IsActive())
return;
TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
- payload_router_.set_active(false);
+ payload_router_.SetActive(false);
bitrate_allocator_->RemoveObserver(this);
{
rtc::CritScope lock(&encoder_activity_crit_sect_);
@@ -923,6 +927,11 @@
}
}
+void VideoSendStreamImpl::OnBitrateAllocationUpdated(
+ const BitrateAllocation& allocation) {
+ payload_router_.OnBitrateAllocationUpdated(allocation);
+}
+
void VideoSendStreamImpl::SignalEncoderActive() {
RTC_DCHECK_RUN_ON(worker_queue_);
LOG(LS_INFO) << "SignalEncoderActive, Encoder is active.";
@@ -965,7 +974,7 @@
streams[0].width, streams[0].height, number_of_temporal_layers,
config_->rtp.max_packet_size);
- if (payload_router_.active()) {
+ if (payload_router_.IsActive()) {
// The send stream is started already. Update the allocator with new bitrate
// limits.
bitrate_allocator_->AddObserver(
@@ -1174,7 +1183,7 @@
int64_t rtt,
int64_t probing_interval_ms) {
RTC_DCHECK_RUN_ON(worker_queue_);
- RTC_DCHECK(payload_router_.active())
+ RTC_DCHECK(payload_router_.IsActive())
<< "VideoSendStream::Start has not been called.";
if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe-WithOverhead") ==
diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc
index 343cd4c..de6b9a8 100644
--- a/webrtc/video/vie_encoder.cc
+++ b/webrtc/video/vie_encoder.cc
@@ -19,6 +19,7 @@
#include "webrtc/base/logging.h"
#include "webrtc/base/trace_event.h"
#include "webrtc/base/timeutils.h"
+#include "webrtc/common_video/include/video_bitrate_allocator.h"
#include "webrtc/modules/pacing/paced_sender.h"
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
#include "webrtc/modules/video_coding/include/video_coding.h"
@@ -26,7 +27,6 @@
#include "webrtc/video/overuse_frame_detector.h"
#include "webrtc/video/send_statistics_proxy.h"
#include "webrtc/video_frame.h"
-
namespace webrtc {
namespace {
@@ -270,6 +270,7 @@
last_frame_log_ms_(clock_->TimeInMilliseconds()),
captured_frame_count_(0),
dropped_frame_count_(0),
+ bitrate_observer_(nullptr),
encoder_queue_("EncoderQueue") {
encoder_queue_.PostTask([this] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
@@ -292,6 +293,7 @@
RTC_DCHECK_RUN_ON(&encoder_queue_);
overuse_detector_.StopCheckForOveruse();
rate_allocator_.reset();
+ bitrate_observer_ = nullptr;
video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type,
false);
quality_scaler_ = nullptr;
@@ -314,6 +316,16 @@
module_process_thread_->DeRegisterModule(&video_sender_);
}
+void ViEEncoder::SetBitrateObserver(
+ VideoBitrateAllocationObserver* bitrate_observer) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ encoder_queue_.PostTask([this, bitrate_observer] {
+ RTC_DCHECK_RUN_ON(&encoder_queue_);
+ RTC_DCHECK(!bitrate_observer_);
+ bitrate_observer_ = bitrate_observer;
+ });
+}
+
void ViEEncoder::SetSource(
rtc::VideoSourceInterface<VideoFrame>* source,
const VideoSendStream::DegradationPreference& degradation_preference) {
@@ -405,7 +417,9 @@
RTC_DCHECK(success);
}
- video_sender_.UpdateChannelParemeters(rate_allocator_.get());
+ video_sender_.UpdateChannelParemeters(rate_allocator_.get(),
+ bitrate_observer_);
+
if (stats_proxy_) {
int framerate = stats_proxy_->GetSendFrameRate();
if (framerate == 0)
@@ -660,7 +674,8 @@
<< " rtt " << round_trip_time_ms;
video_sender_.SetChannelParameters(bitrate_bps, fraction_lost,
- round_trip_time_ms, rate_allocator_.get());
+ round_trip_time_ms, rate_allocator_.get(),
+ bitrate_observer_);
encoder_start_bitrate_bps_ =
bitrate_bps != 0 ? bitrate_bps : encoder_start_bitrate_bps_;
diff --git a/webrtc/video/vie_encoder.h b/webrtc/video/vie_encoder.h
index 7884bbe..5ad1ff7 100644
--- a/webrtc/video/vie_encoder.h
+++ b/webrtc/video/vie_encoder.h
@@ -37,6 +37,7 @@
class ProcessThread;
class SendStatisticsProxy;
+class VideoBitrateAllocationObserver;
// VieEncoder represent a video encoder that accepts raw video frames as input
// and produces an encoded bit stream.
@@ -91,6 +92,8 @@
// TODO(perkj): Can we remove VideoCodec.startBitrate ?
void SetStartBitrate(int start_bitrate_bps);
+ void SetBitrateObserver(VideoBitrateAllocationObserver* bitrate_observer);
+
void ConfigureEncoder(VideoEncoderConfig config,
size_t max_data_payload_length,
bool nack_enabled);
@@ -231,6 +234,8 @@
int captured_frame_count_ ACCESS_ON(&encoder_queue_);
int dropped_frame_count_ ACCESS_ON(&encoder_queue_);
+ VideoBitrateAllocationObserver* bitrate_observer_ ACCESS_ON(&encoder_queue_);
+
// All public methods are proxied to |encoder_queue_|. It must must be
// destroyed first to make sure no tasks are run that use other members.
rtc::TaskQueue encoder_queue_;