[remoting host] Allow WebrtcVideoStream to receive encode-events.
WebrtcVideoStream currently manages the encode/send pipeline by directly
calling the encoder, passing in a private method as a callback. With
has_internal_source==false, it can no longer call the encoder itself,
so another means of receiving OnFrameEncoded event is needed.
With this CL, WebrtcVideoStream receives the notifications (via
VideoChannelStateObserver interface) and passes them directly to the
video-scheduler. In followup CLs, the observer interface will be
expanded to include frame-encoded and frame-sent events (and other
encode events as needed).
This CL also removes OnChannelParameters(), which was unused because
the corresponding method had been removed from
webrtc::VideoEncoder interface - see
http://crrev.com/4b097cc4cc8f26329fa90ef568fef23749a50e11
Bug: 1192865
Change-Id: If01c26f9dae4b9a548b5fdbf75b0735de3050457
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2830128
Reviewed-by: Joe Downing <[email protected]>
Commit-Queue: Lambros Lambrou <[email protected]>
Cr-Commit-Position: refs/heads/master@{#874007}
diff --git a/remoting/protocol/video_channel_state_observer.h b/remoting/protocol/video_channel_state_observer.h
index d5efdef1..1c8d6ab 100644
--- a/remoting/protocol/video_channel_state_observer.h
+++ b/remoting/protocol/video_channel_state_observer.h
@@ -13,11 +13,10 @@
class VideoChannelStateObserver {
public:
virtual void OnKeyFrameRequested() = 0;
- virtual void OnChannelParameters(int packet_loss, base::TimeDelta rtt) = 0;
virtual void OnTargetBitrateChanged(int bitrate_kbps) = 0;
protected:
- virtual ~VideoChannelStateObserver() {}
+ virtual ~VideoChannelStateObserver() = default;
};
} // namespace protocol
diff --git a/remoting/protocol/webrtc_dummy_video_encoder.h b/remoting/protocol/webrtc_dummy_video_encoder.h
index 30d4fba..022495f 100644
--- a/remoting/protocol/webrtc_dummy_video_encoder.h
+++ b/remoting/protocol/webrtc_dummy_video_encoder.h
@@ -98,10 +98,6 @@
void SetVideoChannelStateObserver(
base::WeakPtr<VideoChannelStateObserver> video_channel_state_observer);
- base::WeakPtr<VideoChannelStateObserver>
- get_video_channel_state_observer_for_tests() {
- return video_channel_state_observer_;
- }
void EncoderDestroyed(WebrtcDummyVideoEncoder* encoder);
diff --git a/remoting/protocol/webrtc_frame_scheduler.h b/remoting/protocol/webrtc_frame_scheduler.h
index b7e2016..4cd9fa00 100644
--- a/remoting/protocol/webrtc_frame_scheduler.h
+++ b/remoting/protocol/webrtc_frame_scheduler.h
@@ -8,25 +8,24 @@
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "remoting/codec/webrtc_video_encoder.h"
+#include "remoting/protocol/video_channel_state_observer.h"
namespace remoting {
namespace protocol {
struct HostFrameStats;
-class WebrtcDummyVideoEncoderFactory;
// An abstract interface for frame schedulers, which are responsible for
// scheduling when video frames are captured and for defining encoding
// parameters for each frame.
-class WebrtcFrameScheduler {
+class WebrtcFrameScheduler : public VideoChannelStateObserver {
public:
- WebrtcFrameScheduler() {}
- virtual ~WebrtcFrameScheduler() {}
+ WebrtcFrameScheduler() = default;
+ ~WebrtcFrameScheduler() override = default;
// Starts the scheduler. |capture_callback| will be called whenever a new
// frame should be captured.
- virtual void Start(WebrtcDummyVideoEncoderFactory* video_encoder_factory,
- const base::RepeatingClosure& capture_callback) = 0;
+ virtual void Start(const base::RepeatingClosure& capture_callback) = 0;
// Pause and resumes the scheduler.
virtual void Pause(bool pause) = 0;
diff --git a/remoting/protocol/webrtc_frame_scheduler_simple.cc b/remoting/protocol/webrtc_frame_scheduler_simple.cc
index 7977427..ffd47401 100644
--- a/remoting/protocol/webrtc_frame_scheduler_simple.cc
+++ b/remoting/protocol/webrtc_frame_scheduler_simple.cc
@@ -89,14 +89,6 @@
ScheduleNextFrame();
}
-void WebrtcFrameSchedulerSimple::OnChannelParameters(int packet_loss,
- base::TimeDelta rtt) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- bandwidth_estimator_->UpdateRtt(rtt);
- rtt_estimate_ = rtt;
-}
-
void WebrtcFrameSchedulerSimple::OnTargetBitrateChanged(int bandwidth_kbps) {
DCHECK(thread_checker_.CalledOnValidThread());
bandwidth_estimator_->OnReceivedAck();
@@ -109,12 +101,9 @@
}
void WebrtcFrameSchedulerSimple::Start(
- WebrtcDummyVideoEncoderFactory* video_encoder_factory,
const base::RepeatingClosure& capture_callback) {
DCHECK(thread_checker_.CalledOnValidThread());
capture_callback_ = capture_callback;
- video_encoder_factory->SetVideoChannelStateObserver(
- weak_factory_.GetWeakPtr());
}
void WebrtcFrameSchedulerSimple::Pause(bool pause) {
diff --git a/remoting/protocol/webrtc_frame_scheduler_simple.h b/remoting/protocol/webrtc_frame_scheduler_simple.h
index 280c324..97b73b2f 100644
--- a/remoting/protocol/webrtc_frame_scheduler_simple.h
+++ b/remoting/protocol/webrtc_frame_scheduler_simple.h
@@ -17,7 +17,6 @@
#include "remoting/base/running_samples.h"
#include "remoting/base/session_options.h"
#include "remoting/codec/frame_processing_time_estimator.h"
-#include "remoting/protocol/video_channel_state_observer.h"
namespace remoting {
namespace protocol {
@@ -28,20 +27,17 @@
// that always keeps only one frame in the pipeline. It schedules each frame
// such that it is encoded and ready to be sent by the time previous one is
// expected to finish sending.
-class WebrtcFrameSchedulerSimple : public VideoChannelStateObserver,
- public WebrtcFrameScheduler {
+class WebrtcFrameSchedulerSimple : public WebrtcFrameScheduler {
public:
explicit WebrtcFrameSchedulerSimple(const SessionOptions& options);
~WebrtcFrameSchedulerSimple() override;
// VideoChannelStateObserver implementation.
void OnKeyFrameRequested() override;
- void OnChannelParameters(int packet_loss, base::TimeDelta rtt) override;
void OnTargetBitrateChanged(int bitrate_kbps) override;
// WebrtcFrameScheduler implementation.
- void Start(WebrtcDummyVideoEncoderFactory* video_encoder_factory,
- const base::RepeatingClosure& capture_callback) override;
+ void Start(const base::RepeatingClosure& capture_callback) override;
void Pause(bool pause) override;
bool OnFrameCaptured(const webrtc::DesktopFrame* frame,
WebrtcVideoEncoder::FrameParams* params_out) override;
@@ -98,7 +94,6 @@
const std::unique_ptr<BandwidthEstimator> bandwidth_estimator_;
base::ThreadChecker thread_checker_;
- base::WeakPtrFactory<WebrtcFrameSchedulerSimple> weak_factory_{this};
};
} // namespace protocol
diff --git a/remoting/protocol/webrtc_frame_scheduler_unittest.cc b/remoting/protocol/webrtc_frame_scheduler_unittest.cc
index 3f7db76..6c6758e 100644
--- a/remoting/protocol/webrtc_frame_scheduler_unittest.cc
+++ b/remoting/protocol/webrtc_frame_scheduler_unittest.cc
@@ -32,11 +32,9 @@
base::TimeTicks::Now())),
task_runner_handle_(task_runner_.get()),
frame_(DesktopSize(1, 1)) {
- video_encoder_factory_ = std::make_unique<WebrtcDummyVideoEncoderFactory>();
scheduler_ = std::make_unique<WebrtcFrameSchedulerSimple>(SessionOptions());
scheduler_->SetTickClockForTest(task_runner_->GetMockTickClock());
scheduler_->Start(
- video_encoder_factory_.get(),
base::BindRepeating(&WebrtcFrameSchedulerTest::CaptureCallback,
base::Unretained(this)));
}
@@ -60,7 +58,6 @@
scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
base::ThreadTaskRunnerHandle task_runner_handle_;
- std::unique_ptr<WebrtcDummyVideoEncoderFactory> video_encoder_factory_;
std::unique_ptr<WebrtcFrameSchedulerSimple> scheduler_;
int capture_callback_count_ = 0;
@@ -69,18 +66,15 @@
};
TEST_F(WebrtcFrameSchedulerTest, UpdateBitrateWhenPending) {
- auto video_channel_observer =
- video_encoder_factory_->get_video_channel_state_observer_for_tests();
-
- video_channel_observer->OnKeyFrameRequested();
- video_channel_observer->OnTargetBitrateChanged(100);
+ scheduler_->OnKeyFrameRequested();
+ scheduler_->OnTargetBitrateChanged(100);
EXPECT_TRUE(task_runner_->HasPendingTask());
task_runner_->FastForwardUntilNoTasksRemain();
EXPECT_EQ(1, capture_callback_count_);
- video_channel_observer->OnTargetBitrateChanged(1001);
+ scheduler_->OnTargetBitrateChanged(1001);
// |task_runner_| shouldn't have pending tasks as the scheduler should be
// waiting for the previous capture request to complete.
@@ -88,10 +82,8 @@
}
TEST_F(WebrtcFrameSchedulerTest, EmptyFrameUpdate_ShouldNotBeSentImmediately) {
- auto video_channel_observer =
- video_encoder_factory_->get_video_channel_state_observer_for_tests();
// Needed to avoid DCHECK in OnFrameCaptured().
- video_channel_observer->OnTargetBitrateChanged(100);
+ scheduler_->OnTargetBitrateChanged(100);
WebrtcVideoEncoder::FrameParams out_params;
@@ -109,9 +101,7 @@
TEST_F(WebrtcFrameSchedulerTest, EmptyFrameUpdate_ShouldBeSentAfter2000ms) {
// Identical to the previous test, except it waits a short amount of time
// before the empty frame update.
- auto video_channel_observer =
- video_encoder_factory_->get_video_channel_state_observer_for_tests();
- video_channel_observer->OnTargetBitrateChanged(100);
+ scheduler_->OnTargetBitrateChanged(100);
WebrtcVideoEncoder::FrameParams out_params;
@@ -131,16 +121,14 @@
TEST_F(WebrtcFrameSchedulerTest, Capturer_RunsAt30Fps) {
simulate_capture_ = true;
- auto video_channel_observer =
- video_encoder_factory_->get_video_channel_state_observer_for_tests();
- video_channel_observer->OnTargetBitrateChanged(100);
+ scheduler_->OnTargetBitrateChanged(100);
// Have the capturer return non-empty frames each time.
frame_.mutable_updated_region()->SetRect(DesktopRect::MakeWH(1, 1));
// Ensure the encoder is ready, otherwise the scheduler will not trigger
// repeated captures.
- video_channel_observer->OnKeyFrameRequested();
+ scheduler_->OnKeyFrameRequested();
task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc
index d2b6fd5..cfe1b37a 100644
--- a/remoting/protocol/webrtc_video_stream.cc
+++ b/remoting/protocol/webrtc_video_stream.cc
@@ -138,9 +138,10 @@
webrtc_transport_->OnVideoTransceiverCreated(transceiver);
+ webrtc_transport_->video_encoder_factory()->SetVideoChannelStateObserver(
+ weak_factory_.GetWeakPtr());
scheduler_ = std::make_unique<WebrtcFrameSchedulerSimple>(session_options_);
- scheduler_->Start(webrtc_transport_->video_encoder_factory(),
- base::BindRepeating(&WebrtcVideoStream::CaptureNextFrame,
+ scheduler_->Start(base::BindRepeating(&WebrtcVideoStream::CaptureNextFrame,
base::Unretained(this)));
video_stats_dispatcher_.Init(webrtc_transport_->CreateOutgoingChannel(
@@ -179,6 +180,16 @@
observer_ = observer;
}
+void WebrtcVideoStream::OnKeyFrameRequested() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ scheduler_->OnKeyFrameRequested();
+}
+
+void WebrtcVideoStream::OnTargetBitrateChanged(int bitrate_kbps) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ scheduler_->OnTargetBitrateChanged(bitrate_kbps);
+}
+
void WebrtcVideoStream::OnCaptureResult(
webrtc::DesktopCapturer::Result result,
std::unique_ptr<webrtc::DesktopFrame> frame) {
diff --git a/remoting/protocol/webrtc_video_stream.h b/remoting/protocol/webrtc_video_stream.h
index 06ceaa4..f0ed456 100644
--- a/remoting/protocol/webrtc_video_stream.h
+++ b/remoting/protocol/webrtc_video_stream.h
@@ -20,6 +20,7 @@
#include "remoting/codec/webrtc_video_encoder.h"
#include "remoting/codec/webrtc_video_encoder_selector.h"
#include "remoting/protocol/host_video_stats_dispatcher.h"
+#include "remoting/protocol/video_channel_state_observer.h"
#include "remoting/protocol/video_stream.h"
#include "third_party/webrtc/api/scoped_refptr.h"
#include "third_party/webrtc/api/video_codecs/sdp_video_format.h"
@@ -38,7 +39,8 @@
class WebrtcVideoStream : public VideoStream,
public webrtc::DesktopCapturer::Callback,
- public HostVideoStatsDispatcher::EventHandler {
+ public HostVideoStatsDispatcher::EventHandler,
+ public VideoChannelStateObserver {
public:
explicit WebrtcVideoStream(const SessionOptions& options);
~WebrtcVideoStream() override;
@@ -56,6 +58,10 @@
void SetObserver(Observer* observer) override;
void SelectSource(int id) override;
+ // VideoChannelStateObserver interface.
+ void OnKeyFrameRequested() override;
+ void OnTargetBitrateChanged(int bitrate_kbps) override;
+
private:
struct FrameStats;