From eba9de379b84d05f780e25e6ce167fa1b2b0a4f5 Mon Sep 17 00:00:00 2001 From: "hubbe@chromium.org" Date: Fri, 22 Aug 2014 18:29:00 +0000 Subject: Implement adaptive target delay extension Adds new call on cast_sender: SetTargetPlayoutDelay Caller is responsible for negotiating with the receiver if the extension is actually supported or not. BUG=405339 Review URL: https://codereview.chromium.org/493823002 Cr-Commit-Position: refs/heads/master@{#291453} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291453 0039d316-1c4b-4281-b951-d872f2087c98 --- media/cast/receiver/frame_receiver.cc | 18 +++++++++++++----- media/cast/receiver/frame_receiver.h | 4 ++-- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'media/cast/receiver') diff --git a/media/cast/receiver/frame_receiver.cc b/media/cast/receiver/frame_receiver.cc index 1f6d75e..0e794cd 100644 --- a/media/cast/receiver/frame_receiver.cc +++ b/media/cast/receiver/frame_receiver.cc @@ -202,8 +202,7 @@ void FrameReceiver::EmitAvailableEncodedFrames() { } const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); - const base::TimeTicks playout_time = - GetPlayoutTime(encoded_frame->rtp_timestamp); + const base::TimeTicks playout_time = GetPlayoutTime(*encoded_frame); // If we have multiple decodable frames, and the current frame is // too old, then skip it and decode the next frame instead. @@ -251,6 +250,10 @@ void FrameReceiver::EmitAvailableEncodedFrames() { // At this point, we have a decrypted EncodedFrame ready to be emitted. encoded_frame->reference_time = playout_time; framer_.ReleaseFrame(encoded_frame->frame_id); + if (encoded_frame->new_playout_delay_ms) { + target_playout_delay_ = base::TimeDelta::FromMilliseconds( + encoded_frame->new_playout_delay_ms); + } cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, base::Bind(frame_request_queue_.front(), @@ -266,13 +269,18 @@ void FrameReceiver::EmitAvailableEncodedFramesAfterWaiting() { EmitAvailableEncodedFrames(); } -base::TimeTicks FrameReceiver::GetPlayoutTime(uint32 rtp_timestamp) const { +base::TimeTicks FrameReceiver::GetPlayoutTime(const EncodedFrame& frame) const { + base::TimeDelta target_playout_delay = target_playout_delay_; + if (frame.new_playout_delay_ms) { + target_playout_delay = base::TimeDelta::FromMilliseconds( + frame.new_playout_delay_ms); + } return lip_sync_reference_time_ + lip_sync_drift_.Current() + RtpDeltaToTimeDelta( - static_cast(rtp_timestamp - lip_sync_rtp_timestamp_), + static_cast(frame.rtp_timestamp - lip_sync_rtp_timestamp_), rtp_timebase_) + - target_playout_delay_; + target_playout_delay; } void FrameReceiver::ScheduleNextCastMessage() { diff --git a/media/cast/receiver/frame_receiver.h b/media/cast/receiver/frame_receiver.h index 2ddeeb9..695c8d0 100644 --- a/media/cast/receiver/frame_receiver.h +++ b/media/cast/receiver/frame_receiver.h @@ -92,7 +92,7 @@ class FrameReceiver : public RtpPayloadFeedback, // Computes the playout time for a frame with the given |rtp_timestamp|. // Because lip-sync info is refreshed regularly, calling this method with the // same argument may return different results. - base::TimeTicks GetPlayoutTime(uint32 rtp_timestamp) const; + base::TimeTicks GetPlayoutTime(const EncodedFrame& frame) const; // Schedule timing for the next cast message. void ScheduleNextCastMessage(); @@ -130,7 +130,7 @@ class FrameReceiver : public RtpPayloadFeedback, // transmit/retransmit, receive, decode, and render; given its run-time // environment (sender/receiver hardware performance, network conditions, // etc.). - const base::TimeDelta target_playout_delay_; + base::TimeDelta target_playout_delay_; // Hack: This is used in logic that determines whether to skip frames. // TODO(miu): Revisit this. Logic needs to also account for expected decode -- cgit v1.1