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

Side by Side Diff: media/filters/video_renderer_impl.cc

Issue 379343005: Introduce media::TimeSource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/filters/video_renderer_impl.h" 5 #include "media/filters/video_renderer_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 callback.Run(); 78 callback.Run();
79 return; 79 return;
80 } 80 }
81 81
82 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing 82 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
83 // task-running guards that check |state_| with DCHECK(). 83 // task-running guards that check |state_| with DCHECK().
84 84
85 state_ = kStopped; 85 state_ = kStopped;
86 86
87 statistics_cb_.Reset(); 87 statistics_cb_.Reset();
88 max_time_cb_.Reset();
89 DoStopOrError_Locked(); 88 DoStopOrError_Locked();
90 89
91 // Clean up our thread if present. 90 // Clean up our thread if present.
92 base::PlatformThreadHandle thread_to_join = base::PlatformThreadHandle(); 91 base::PlatformThreadHandle thread_to_join = base::PlatformThreadHandle();
93 if (!thread_.is_null()) { 92 if (!thread_.is_null()) {
94 // Signal the thread since it's possible to get stopped with the video 93 // Signal the thread since it's possible to get stopped with the video
95 // thread waiting for a read to complete. 94 // thread waiting for a read to complete.
96 frame_available_.Signal(); 95 frame_available_.Signal();
97 std::swap(thread_, thread_to_join); 96 std::swap(thread_, thread_to_join);
98 } 97 }
99 98
100 if (!thread_to_join.is_null()) { 99 if (!thread_to_join.is_null()) {
101 base::AutoUnlock auto_unlock(lock_); 100 base::AutoUnlock auto_unlock(lock_);
102 base::PlatformThread::Join(thread_to_join); 101 base::PlatformThread::Join(thread_to_join);
103 } 102 }
104 103
105 video_frame_stream_.Stop(callback); 104 video_frame_stream_.Stop(callback);
106 } 105 }
107 106
108 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { 107 void VideoRendererImpl::StartPlaying() {
109 DCHECK(task_runner_->BelongsToCurrentThread()); 108 DCHECK(task_runner_->BelongsToCurrentThread());
110 base::AutoLock auto_lock(lock_); 109 base::AutoLock auto_lock(lock_);
111 DCHECK_EQ(state_, kFlushed); 110 DCHECK_EQ(state_, kFlushed);
112 DCHECK(!pending_read_); 111 DCHECK(!pending_read_);
113 DCHECK(ready_frames_.empty()); 112 DCHECK(ready_frames_.empty());
114 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 113 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
115 114
116 state_ = kPlaying; 115 state_ = kPlaying;
117 start_timestamp_ = timestamp; 116 start_timestamp_ = get_time_cb_.Run();
118 AttemptRead_Locked(); 117 AttemptRead_Locked();
119 } 118 }
120 119
121 void VideoRendererImpl::Initialize(DemuxerStream* stream, 120 void VideoRendererImpl::Initialize(DemuxerStream* stream,
122 bool low_delay, 121 bool low_delay,
123 const PipelineStatusCB& init_cb, 122 const PipelineStatusCB& init_cb,
124 const StatisticsCB& statistics_cb, 123 const StatisticsCB& statistics_cb,
125 const TimeCB& max_time_cb,
126 const BufferingStateCB& buffering_state_cb, 124 const BufferingStateCB& buffering_state_cb,
127 const base::Closure& ended_cb, 125 const base::Closure& ended_cb,
128 const PipelineStatusCB& error_cb, 126 const PipelineStatusCB& error_cb,
129 const TimeDeltaCB& get_time_cb, 127 const TimeDeltaCB& get_time_cb,
130 const TimeDeltaCB& get_duration_cb) { 128 const TimeDeltaCB& get_duration_cb) {
131 DCHECK(task_runner_->BelongsToCurrentThread()); 129 DCHECK(task_runner_->BelongsToCurrentThread());
132 base::AutoLock auto_lock(lock_); 130 base::AutoLock auto_lock(lock_);
133 DCHECK(stream); 131 DCHECK(stream);
134 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); 132 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO);
135 DCHECK(!init_cb.is_null()); 133 DCHECK(!init_cb.is_null());
136 DCHECK(!statistics_cb.is_null()); 134 DCHECK(!statistics_cb.is_null());
137 DCHECK(!max_time_cb.is_null());
138 DCHECK(!buffering_state_cb.is_null()); 135 DCHECK(!buffering_state_cb.is_null());
139 DCHECK(!ended_cb.is_null()); 136 DCHECK(!ended_cb.is_null());
140 DCHECK(!get_time_cb.is_null()); 137 DCHECK(!get_time_cb.is_null());
141 DCHECK(!get_duration_cb.is_null()); 138 DCHECK(!get_duration_cb.is_null());
142 DCHECK_EQ(kUninitialized, state_); 139 DCHECK_EQ(kUninitialized, state_);
143 140
144 low_delay_ = low_delay; 141 low_delay_ = low_delay;
145 142
146 init_cb_ = init_cb; 143 init_cb_ = init_cb;
147 statistics_cb_ = statistics_cb; 144 statistics_cb_ = statistics_cb;
148 max_time_cb_ = max_time_cb;
149 buffering_state_cb_ = buffering_state_cb; 145 buffering_state_cb_ = buffering_state_cb;
150 ended_cb_ = ended_cb; 146 ended_cb_ = ended_cb;
151 error_cb_ = error_cb; 147 error_cb_ = error_cb;
152 get_time_cb_ = get_time_cb; 148 get_time_cb_ = get_time_cb;
153 get_duration_cb_ = get_duration_cb; 149 get_duration_cb_ = get_duration_cb;
154 state_ = kInitializing; 150 state_ = kInitializing;
155 151
156 video_frame_stream_.Initialize( 152 video_frame_stream_.Initialize(
157 stream, 153 stream,
158 low_delay, 154 low_delay,
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 DCHECK_EQ(state_, kPlaying); 359 DCHECK_EQ(state_, kPlaying);
364 return received_end_of_stream_ || 360 return received_end_of_stream_ ||
365 !video_frame_stream_.CanReadWithoutStalling() || 361 !video_frame_stream_.CanReadWithoutStalling() ||
366 ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames) || 362 ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames) ||
367 (low_delay_ && ready_frames_.size() > 0); 363 (low_delay_ && ready_frames_.size() > 0);
368 } 364 }
369 365
370 void VideoRendererImpl::TransitionToHaveEnough_Locked() { 366 void VideoRendererImpl::TransitionToHaveEnough_Locked() {
371 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 367 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
372 368
373 if (received_end_of_stream_)
374 max_time_cb_.Run(get_duration_cb_.Run());
375
376 if (!ready_frames_.empty()) { 369 if (!ready_frames_.empty()) {
377 // Max time isn't reported while we're in a have nothing state as we could
378 // be discarding frames to find |start_timestamp_|.
379 if (!received_end_of_stream_) {
380 base::TimeDelta max_timestamp = ready_frames_[0]->timestamp();
381 for (size_t i = 1; i < ready_frames_.size(); ++i) {
382 if (ready_frames_[i]->timestamp() > max_timestamp)
383 max_timestamp = ready_frames_[i]->timestamp();
384 }
385 max_time_cb_.Run(max_timestamp);
386 }
387
388 // Because the clock might remain paused in for an undetermined amount 370 // Because the clock might remain paused in for an undetermined amount
389 // of time (e.g., seeking while paused), paint the first frame. 371 // of time (e.g., seeking while paused), paint the first frame.
390 PaintNextReadyFrame_Locked(); 372 PaintNextReadyFrame_Locked();
391 } 373 }
392 374
393 buffering_state_ = BUFFERING_HAVE_ENOUGH; 375 buffering_state_ = BUFFERING_HAVE_ENOUGH;
394 buffering_state_cb_.Run(BUFFERING_HAVE_ENOUGH); 376 buffering_state_cb_.Run(BUFFERING_HAVE_ENOUGH);
395 } 377 }
396 378
397 void VideoRendererImpl::AddReadyFrame_Locked( 379 void VideoRendererImpl::AddReadyFrame_Locked(
398 const scoped_refptr<VideoFrame>& frame) { 380 const scoped_refptr<VideoFrame>& frame) {
399 lock_.AssertAcquired(); 381 lock_.AssertAcquired();
400 DCHECK(!frame->end_of_stream()); 382 DCHECK(!frame->end_of_stream());
401 383
402 // Adjust the incoming frame if its rendering stop time is past the duration 384 // Adjust the incoming frame if its rendering stop time is past the duration
403 // of the video itself. This is typically the last frame of the video and 385 // of the video itself. This is typically the last frame of the video and
404 // occurs if the container specifies a duration that isn't a multiple of the 386 // occurs if the container specifies a duration that isn't a multiple of the
405 // frame rate. Another way for this to happen is for the container to state 387 // frame rate. Another way for this to happen is for the container to state
406 // a smaller duration than the largest packet timestamp. 388 // a smaller duration than the largest packet timestamp.
407 base::TimeDelta duration = get_duration_cb_.Run(); 389 base::TimeDelta duration = get_duration_cb_.Run();
408 if (frame->timestamp() > duration) { 390 if (frame->timestamp() > duration) {
409 frame->set_timestamp(duration); 391 frame->set_timestamp(duration);
410 } 392 }
411 393
412 ready_frames_.push_back(frame); 394 ready_frames_.push_back(frame);
413 DCHECK_LE(ready_frames_.size(), 395 DCHECK_LE(ready_frames_.size(),
414 static_cast<size_t>(limits::kMaxVideoFrames)); 396 static_cast<size_t>(limits::kMaxVideoFrames));
415 397
416 // FrameReady() may add frames but discard them when we're decoding frames to
417 // reach |start_timestamp_|. In this case we'll only want to update the max
418 // time when we know we've reached |start_timestamp_| and have buffered enough
419 // frames to being playback.
420 if (buffering_state_ == BUFFERING_HAVE_ENOUGH)
421 max_time_cb_.Run(frame->timestamp());
422
423 // Avoid needlessly waking up |thread_| unless playing. 398 // Avoid needlessly waking up |thread_| unless playing.
424 if (state_ == kPlaying) 399 if (state_ == kPlaying)
425 frame_available_.Signal(); 400 frame_available_.Signal();
426 } 401 }
427 402
428 void VideoRendererImpl::AttemptRead() { 403 void VideoRendererImpl::AttemptRead() {
429 base::AutoLock auto_lock(lock_); 404 base::AutoLock auto_lock(lock_);
430 AttemptRead_Locked(); 405 AttemptRead_Locked();
431 } 406 }
432 407
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 statistics_cb_.Run(statistics); 466 statistics_cb_.Run(statistics);
492 467
493 frames_decoded_ = 0; 468 frames_decoded_ = 0;
494 frames_dropped_ = 0; 469 frames_dropped_ = 0;
495 } 470 }
496 471
497 frame_available_.TimedWait(wait_duration); 472 frame_available_.TimedWait(wait_duration);
498 } 473 }
499 474
500 } // namespace media 475 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698