Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(378)

Unified Diff: remoting/host/video_scheduler.cc

Issue 292373002: More reliable keep-alive video packets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « remoting/host/video_scheduler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/video_scheduler.cc
diff --git a/remoting/host/video_scheduler.cc b/remoting/host/video_scheduler.cc
index 7fc1983128d8d0c36604e502b64e08fbd2a88135..a346d04c254898e7ff482099025d70efec8a5e13 100644
--- a/remoting/host/video_scheduler.cc
+++ b/remoting/host/video_scheduler.cc
@@ -30,6 +30,10 @@ namespace remoting {
// TODO(hclam): Move this value to CaptureScheduler.
static const int kMaxPendingFrames = 2;
+// Interval between empty keep-alive frames. These frames are sent only
+// when there are no real video frames being sent.
+static const int kKeepAlivePacketIntervalMs = 500;
+
VideoScheduler::VideoScheduler(
scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
@@ -68,16 +72,22 @@ void VideoScheduler::OnCaptureCompleted(webrtc::DesktopFrame* frame) {
capture_pending_ = false;
+ if (!frame) {
+ LOG(ERROR) << "Capture failed.";
+ return;
+ }
+
scoped_ptr<webrtc::DesktopFrame> owned_frame(frame);
- if (frame) {
- scheduler_.RecordCaptureTime(
- base::TimeDelta::FromMilliseconds(frame->capture_time_ms()));
- }
+ scheduler_.RecordCaptureTime(
+ base::TimeDelta::FromMilliseconds(frame->capture_time_ms()));
- encode_task_runner_->PostTask(
- FROM_HERE, base::Bind(&VideoScheduler::EncodeFrame, this,
- base::Passed(&owned_frame), sequence_number_));
+ // Encode and send only non-empty frames.
+ if (!frame->updated_region().is_empty()) {
+ encode_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VideoScheduler::EncodeFrame, this,
+ base::Passed(&owned_frame), sequence_number_));
+ }
// If a frame was skipped, try to capture it again.
if (did_skip_frame_) {
@@ -123,8 +133,10 @@ void VideoScheduler::Stop() {
cursor_stub_ = NULL;
video_stub_ = NULL;
- capture_task_runner_->PostTask(FROM_HERE,
- base::Bind(&VideoScheduler::StopOnCaptureThread, this));
+ keep_alive_timer_.reset();
+
+ capture_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VideoScheduler::StopOnCaptureThread, this));
}
void VideoScheduler::Pause(bool pause) {
@@ -172,6 +184,9 @@ void VideoScheduler::StartOnCaptureThread() {
capturer_->Start(this);
capture_timer_.reset(new base::OneShotTimer<VideoScheduler>());
+ keep_alive_timer_.reset(new base::DelayTimer<VideoScheduler>(
+ FROM_HERE, base::TimeDelta::FromMilliseconds(kKeepAlivePacketIntervalMs),
+ this, &VideoScheduler::SendKeepAlivePacket));
// Capture first frame immedately.
CaptureNextFrame();
@@ -249,19 +264,39 @@ void VideoScheduler::SendVideoPacket(scoped_ptr<VideoPacket> packet) {
return;
video_stub_->ProcessVideoPacket(
- packet.Pass(), base::Bind(&VideoScheduler::VideoFrameSentCallback, this));
+ packet.Pass(), base::Bind(&VideoScheduler::OnVideoPacketSent, this));
}
-void VideoScheduler::VideoFrameSentCallback() {
+void VideoScheduler::OnVideoPacketSent() {
DCHECK(network_task_runner_->BelongsToCurrentThread());
if (!video_stub_)
return;
+ keep_alive_timer_->Reset();
+
capture_task_runner_->PostTask(
FROM_HERE, base::Bind(&VideoScheduler::FrameCaptureCompleted, this));
}
+void VideoScheduler::SendKeepAlivePacket() {
+ DCHECK(network_task_runner_->BelongsToCurrentThread());
+
+ if (!video_stub_)
+ return;
+
+ video_stub_->ProcessVideoPacket(
+ scoped_ptr<VideoPacket>(new VideoPacket()),
+ base::Bind(&VideoScheduler::OnKeepAlivePacketSent, this));
+}
+
+void VideoScheduler::OnKeepAlivePacketSent() {
+ DCHECK(network_task_runner_->BelongsToCurrentThread());
+
+ if (keep_alive_timer_)
+ keep_alive_timer_->Reset();
+}
+
void VideoScheduler::SendCursorShape(
scoped_ptr<protocol::CursorShapeInfo> cursor_shape) {
DCHECK(network_task_runner_->BelongsToCurrentThread());
@@ -278,17 +313,7 @@ void VideoScheduler::EncodeFrame(
scoped_ptr<webrtc::DesktopFrame> frame,
int64 sequence_number) {
DCHECK(encode_task_runner_->BelongsToCurrentThread());
-
- // If there is nothing to encode then send an empty keep-alive packet.
- if (!frame || frame->updated_region().is_empty()) {
- scoped_ptr<VideoPacket> packet(new VideoPacket());
- packet->set_client_sequence_number(sequence_number);
- network_task_runner_->PostTask(
- FROM_HERE, base::Bind(&VideoScheduler::SendVideoPacket, this,
- base::Passed(&packet)));
- capture_task_runner_->DeleteSoon(FROM_HERE, frame.release());
- return;
- }
+ DCHECK(!frame->updated_region().is_empty());
scoped_ptr<VideoPacket> packet = encoder_->Encode(*frame);
packet->set_client_sequence_number(sequence_number);
« no previous file with comments | « remoting/host/video_scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698