OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/receiver/frame_receiver.h" | 5 #include "media/cast/receiver/frame_receiver.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/big_endian.h" | 9 #include "base/big_endian.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 bool is_consecutively_next_frame = false; | 195 bool is_consecutively_next_frame = false; |
196 bool have_multiple_complete_frames = false; | 196 bool have_multiple_complete_frames = false; |
197 if (!framer_.GetEncodedFrame(encoded_frame.get(), | 197 if (!framer_.GetEncodedFrame(encoded_frame.get(), |
198 &is_consecutively_next_frame, | 198 &is_consecutively_next_frame, |
199 &have_multiple_complete_frames)) { | 199 &have_multiple_complete_frames)) { |
200 VLOG(1) << "Wait for more packets to produce a completed frame."; | 200 VLOG(1) << "Wait for more packets to produce a completed frame."; |
201 return; // ProcessParsedPacket() will invoke this method in the future. | 201 return; // ProcessParsedPacket() will invoke this method in the future. |
202 } | 202 } |
203 | 203 |
204 const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 204 const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
205 const base::TimeTicks playout_time = | 205 const base::TimeTicks playout_time = GetPlayoutTime(*encoded_frame); |
206 GetPlayoutTime(encoded_frame->rtp_timestamp); | |
207 | 206 |
208 // If we have multiple decodable frames, and the current frame is | 207 // If we have multiple decodable frames, and the current frame is |
209 // too old, then skip it and decode the next frame instead. | 208 // too old, then skip it and decode the next frame instead. |
210 if (have_multiple_complete_frames && now > playout_time) { | 209 if (have_multiple_complete_frames && now > playout_time) { |
211 framer_.ReleaseFrame(encoded_frame->frame_id); | 210 framer_.ReleaseFrame(encoded_frame->frame_id); |
212 continue; | 211 continue; |
213 } | 212 } |
214 | 213 |
215 // If |framer_| has a frame ready that is out of sequence, examine the | 214 // If |framer_| has a frame ready that is out of sequence, examine the |
216 // playout time to determine whether it's acceptable to continue, thereby | 215 // playout time to determine whether it's acceptable to continue, thereby |
(...skipping 27 matching lines...) Expand all Loading... |
244 // Decryption failed. Give up on this frame. | 243 // Decryption failed. Give up on this frame. |
245 framer_.ReleaseFrame(encoded_frame->frame_id); | 244 framer_.ReleaseFrame(encoded_frame->frame_id); |
246 continue; | 245 continue; |
247 } | 246 } |
248 encoded_frame->data.swap(decrypted_data); | 247 encoded_frame->data.swap(decrypted_data); |
249 } | 248 } |
250 | 249 |
251 // At this point, we have a decrypted EncodedFrame ready to be emitted. | 250 // At this point, we have a decrypted EncodedFrame ready to be emitted. |
252 encoded_frame->reference_time = playout_time; | 251 encoded_frame->reference_time = playout_time; |
253 framer_.ReleaseFrame(encoded_frame->frame_id); | 252 framer_.ReleaseFrame(encoded_frame->frame_id); |
| 253 if (encoded_frame->new_playout_delay_ms) { |
| 254 target_playout_delay_ = base::TimeDelta::FromMilliseconds( |
| 255 encoded_frame->new_playout_delay_ms); |
| 256 } |
254 cast_environment_->PostTask(CastEnvironment::MAIN, | 257 cast_environment_->PostTask(CastEnvironment::MAIN, |
255 FROM_HERE, | 258 FROM_HERE, |
256 base::Bind(frame_request_queue_.front(), | 259 base::Bind(frame_request_queue_.front(), |
257 base::Passed(&encoded_frame))); | 260 base::Passed(&encoded_frame))); |
258 frame_request_queue_.pop_front(); | 261 frame_request_queue_.pop_front(); |
259 } | 262 } |
260 } | 263 } |
261 | 264 |
262 void FrameReceiver::EmitAvailableEncodedFramesAfterWaiting() { | 265 void FrameReceiver::EmitAvailableEncodedFramesAfterWaiting() { |
263 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 266 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
264 DCHECK(is_waiting_for_consecutive_frame_); | 267 DCHECK(is_waiting_for_consecutive_frame_); |
265 is_waiting_for_consecutive_frame_ = false; | 268 is_waiting_for_consecutive_frame_ = false; |
266 EmitAvailableEncodedFrames(); | 269 EmitAvailableEncodedFrames(); |
267 } | 270 } |
268 | 271 |
269 base::TimeTicks FrameReceiver::GetPlayoutTime(uint32 rtp_timestamp) const { | 272 base::TimeTicks FrameReceiver::GetPlayoutTime(const EncodedFrame& frame) const { |
| 273 base::TimeDelta target_playout_delay = target_playout_delay_; |
| 274 if (frame.new_playout_delay_ms) { |
| 275 target_playout_delay = base::TimeDelta::FromMilliseconds( |
| 276 frame.new_playout_delay_ms); |
| 277 } |
270 return lip_sync_reference_time_ + | 278 return lip_sync_reference_time_ + |
271 lip_sync_drift_.Current() + | 279 lip_sync_drift_.Current() + |
272 RtpDeltaToTimeDelta( | 280 RtpDeltaToTimeDelta( |
273 static_cast<int32>(rtp_timestamp - lip_sync_rtp_timestamp_), | 281 static_cast<int32>(frame.rtp_timestamp - lip_sync_rtp_timestamp_), |
274 rtp_timebase_) + | 282 rtp_timebase_) + |
275 target_playout_delay_; | 283 target_playout_delay; |
276 } | 284 } |
277 | 285 |
278 void FrameReceiver::ScheduleNextCastMessage() { | 286 void FrameReceiver::ScheduleNextCastMessage() { |
279 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 287 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
280 base::TimeTicks send_time; | 288 base::TimeTicks send_time; |
281 framer_.TimeToSendNextCastMessage(&send_time); | 289 framer_.TimeToSendNextCastMessage(&send_time); |
282 base::TimeDelta time_to_send = | 290 base::TimeDelta time_to_send = |
283 send_time - cast_environment_->Clock()->NowTicks(); | 291 send_time - cast_environment_->Clock()->NowTicks(); |
284 time_to_send = std::max( | 292 time_to_send = std::max( |
285 time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); | 293 time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); |
(...skipping 26 matching lines...) Expand all Loading... |
312 } | 320 } |
313 | 321 |
314 void FrameReceiver::SendNextRtcpReport() { | 322 void FrameReceiver::SendNextRtcpReport() { |
315 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 323 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
316 rtcp_.SendRtcpFromRtpReceiver(NULL, base::TimeDelta(), NULL, &stats_); | 324 rtcp_.SendRtcpFromRtpReceiver(NULL, base::TimeDelta(), NULL, &stats_); |
317 ScheduleNextRtcpReport(); | 325 ScheduleNextRtcpReport(); |
318 } | 326 } |
319 | 327 |
320 } // namespace cast | 328 } // namespace cast |
321 } // namespace media | 329 } // namespace media |
OLD | NEW |