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

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

Issue 475863002: VideoRendererImpl: Delay report of BUFFERING_HAVE_NOTHING. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments Created 6 years, 4 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 21 matching lines...) Expand all
32 received_end_of_stream_(false), 32 received_end_of_stream_(false),
33 rendered_end_of_stream_(false), 33 rendered_end_of_stream_(false),
34 frame_available_(&lock_), 34 frame_available_(&lock_),
35 state_(kUninitialized), 35 state_(kUninitialized),
36 thread_(), 36 thread_(),
37 pending_read_(false), 37 pending_read_(false),
38 drop_frames_(drop_frames), 38 drop_frames_(drop_frames),
39 buffering_state_(BUFFERING_HAVE_NOTHING), 39 buffering_state_(BUFFERING_HAVE_NOTHING),
40 paint_cb_(paint_cb), 40 paint_cb_(paint_cb),
41 last_timestamp_(kNoTimestamp()), 41 last_timestamp_(kNoTimestamp()),
42 last_painted_timestamp_(kNoTimestamp()),
42 frames_decoded_(0), 43 frames_decoded_(0),
43 frames_dropped_(0), 44 frames_dropped_(0),
44 is_shutting_down_(false), 45 is_shutting_down_(false),
45 weak_factory_(this) { 46 weak_factory_(this) {
46 DCHECK(!paint_cb_.is_null()); 47 DCHECK(!paint_cb_.is_null());
47 } 48 }
48 49
49 VideoRendererImpl::~VideoRendererImpl() { 50 VideoRendererImpl::~VideoRendererImpl() {
50 DCHECK(task_runner_->BelongsToCurrentThread()); 51 DCHECK(task_runner_->BelongsToCurrentThread());
51 52
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 178
178 // The number of milliseconds to idle when we do not have anything to do. 179 // The number of milliseconds to idle when we do not have anything to do.
179 // Nothing special about the value, other than we're being more OS-friendly 180 // Nothing special about the value, other than we're being more OS-friendly
180 // than sleeping for 1 millisecond. 181 // than sleeping for 1 millisecond.
181 // 182 //
182 // TODO(scherkus): switch to pure event-driven frame timing instead of this 183 // TODO(scherkus): switch to pure event-driven frame timing instead of this
183 // kIdleTimeDelta business http://crbug.com/106874 184 // kIdleTimeDelta business http://crbug.com/106874
184 const base::TimeDelta kIdleTimeDelta = 185 const base::TimeDelta kIdleTimeDelta =
185 base::TimeDelta::FromMilliseconds(10); 186 base::TimeDelta::FromMilliseconds(10);
186 187
188 // If we have no frames and haven't painted any frame for certain amount of
189 // time, declare BUFFERING_HAVE_NOTHING.
190 const base::TimeDelta kTimeToDeclareHaveNothing =
191 base::TimeDelta::FromSeconds(3);
192
187 for (;;) { 193 for (;;) {
188 base::AutoLock auto_lock(lock_); 194 base::AutoLock auto_lock(lock_);
189 195
190 // Thread exit condition. 196 // Thread exit condition.
191 if (is_shutting_down_) 197 if (is_shutting_down_)
192 return; 198 return;
193 199
194 // Remain idle as long as we're not playing. 200 // Remain idle as long as we're not playing.
195 if (state_ != kPlaying || buffering_state_ != BUFFERING_HAVE_ENOUGH) { 201 if (state_ != kPlaying || buffering_state_ != BUFFERING_HAVE_ENOUGH) {
196 UpdateStatsAndWait_Locked(kIdleTimeDelta); 202 UpdateStatsAndWait_Locked(kIdleTimeDelta);
197 continue; 203 continue;
198 } 204 }
199 205
206 base::TimeDelta now = get_time_cb_.Run();
scherkus (not reviewing) 2014/08/22 01:40:59 did we mean to use *media* time instead of wall cl
207
200 // Remain idle until we have the next frame ready for rendering. 208 // Remain idle until we have the next frame ready for rendering.
201 if (ready_frames_.empty()) { 209 if (ready_frames_.empty()) {
202 if (received_end_of_stream_) { 210 if (received_end_of_stream_) {
203 if (!rendered_end_of_stream_) { 211 if (!rendered_end_of_stream_) {
204 rendered_end_of_stream_ = true; 212 rendered_end_of_stream_ = true;
205 task_runner_->PostTask(FROM_HERE, ended_cb_); 213 task_runner_->PostTask(FROM_HERE, ended_cb_);
206 } 214 }
207 } else { 215 } else if (last_painted_timestamp_ != kNoTimestamp() &&
216 now - last_painted_timestamp_ >= kTimeToDeclareHaveNothing) {
208 buffering_state_ = BUFFERING_HAVE_NOTHING; 217 buffering_state_ = BUFFERING_HAVE_NOTHING;
209 task_runner_->PostTask( 218 task_runner_->PostTask(
210 FROM_HERE, base::Bind(buffering_state_cb_, BUFFERING_HAVE_NOTHING)); 219 FROM_HERE, base::Bind(buffering_state_cb_, BUFFERING_HAVE_NOTHING));
211 } 220 }
212 221
213 UpdateStatsAndWait_Locked(kIdleTimeDelta); 222 UpdateStatsAndWait_Locked(kIdleTimeDelta);
214 continue; 223 continue;
215 } 224 }
216 225
217 base::TimeDelta now = get_time_cb_.Run();
218 base::TimeDelta target_paint_timestamp = ready_frames_.front()->timestamp(); 226 base::TimeDelta target_paint_timestamp = ready_frames_.front()->timestamp();
219 base::TimeDelta latest_paint_timestamp; 227 base::TimeDelta latest_paint_timestamp;
220 228
221 // Deadline is defined as the duration between this frame and the next 229 // Deadline is defined as the duration between this frame and the next
222 // frame, using the delta between this frame and the previous frame as the 230 // frame, using the delta between this frame and the previous frame as the
223 // assumption for frame duration. 231 // assumption for frame duration.
224 // 232 //
225 // TODO(scherkus): This can be vastly improved. Use a histogram to measure 233 // TODO(scherkus): This can be vastly improved. Use a histogram to measure
226 // the accuracy of our frame timing code. http://crbug.com/149829 234 // the accuracy of our frame timing code. http://crbug.com/149829
227 if (last_timestamp_ == kNoTimestamp()) { 235 if (last_timestamp_ == kNoTimestamp()) {
(...skipping 23 matching lines...) Expand all
251 } 259 }
252 260
253 void VideoRendererImpl::PaintNextReadyFrame_Locked() { 261 void VideoRendererImpl::PaintNextReadyFrame_Locked() {
254 lock_.AssertAcquired(); 262 lock_.AssertAcquired();
255 263
256 scoped_refptr<VideoFrame> next_frame = ready_frames_.front(); 264 scoped_refptr<VideoFrame> next_frame = ready_frames_.front();
257 ready_frames_.pop_front(); 265 ready_frames_.pop_front();
258 frames_decoded_++; 266 frames_decoded_++;
259 267
260 last_timestamp_ = next_frame->timestamp(); 268 last_timestamp_ = next_frame->timestamp();
269 last_painted_timestamp_ = next_frame->timestamp();
261 270
262 paint_cb_.Run(next_frame); 271 paint_cb_.Run(next_frame);
263 272
264 task_runner_->PostTask( 273 task_runner_->PostTask(
265 FROM_HERE, 274 FROM_HERE,
266 base::Bind(&VideoRendererImpl::AttemptRead, weak_factory_.GetWeakPtr())); 275 base::Bind(&VideoRendererImpl::AttemptRead, weak_factory_.GetWeakPtr()));
267 } 276 }
268 277
269 void VideoRendererImpl::DropNextReadyFrame_Locked() { 278 void VideoRendererImpl::DropNextReadyFrame_Locked() {
270 TRACE_EVENT0("media", "VideoRendererImpl:frameDropped"); 279 TRACE_EVENT0("media", "VideoRendererImpl:frameDropped");
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 base::AutoLock auto_lock(lock_); 445 base::AutoLock auto_lock(lock_);
437 DCHECK_EQ(kFlushing, state_); 446 DCHECK_EQ(kFlushing, state_);
438 DCHECK(!pending_read_); 447 DCHECK(!pending_read_);
439 DCHECK(ready_frames_.empty()); 448 DCHECK(ready_frames_.empty());
440 DCHECK(!received_end_of_stream_); 449 DCHECK(!received_end_of_stream_);
441 DCHECK(!rendered_end_of_stream_); 450 DCHECK(!rendered_end_of_stream_);
442 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 451 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
443 452
444 state_ = kFlushed; 453 state_ = kFlushed;
445 last_timestamp_ = kNoTimestamp(); 454 last_timestamp_ = kNoTimestamp();
455 last_painted_timestamp_ = kNoTimestamp();
446 base::ResetAndReturn(&flush_cb_).Run(); 456 base::ResetAndReturn(&flush_cb_).Run();
447 } 457 }
448 458
449 void VideoRendererImpl::UpdateStatsAndWait_Locked( 459 void VideoRendererImpl::UpdateStatsAndWait_Locked(
450 base::TimeDelta wait_duration) { 460 base::TimeDelta wait_duration) {
451 lock_.AssertAcquired(); 461 lock_.AssertAcquired();
452 DCHECK_GE(frames_decoded_, 0); 462 DCHECK_GE(frames_decoded_, 0);
453 DCHECK_LE(frames_dropped_, frames_decoded_); 463 DCHECK_LE(frames_dropped_, frames_decoded_);
454 464
455 if (frames_decoded_) { 465 if (frames_decoded_) {
456 PipelineStatistics statistics; 466 PipelineStatistics statistics;
457 statistics.video_frames_decoded = frames_decoded_; 467 statistics.video_frames_decoded = frames_decoded_;
458 statistics.video_frames_dropped = frames_dropped_; 468 statistics.video_frames_dropped = frames_dropped_;
459 task_runner_->PostTask(FROM_HERE, base::Bind(statistics_cb_, statistics)); 469 task_runner_->PostTask(FROM_HERE, base::Bind(statistics_cb_, statistics));
460 470
461 frames_decoded_ = 0; 471 frames_decoded_ = 0;
462 frames_dropped_ = 0; 472 frames_dropped_ = 0;
463 } 473 }
464 474
465 frame_available_.TimedWait(wait_duration); 475 frame_available_.TimedWait(wait_duration);
466 } 476 }
467 477
468 } // namespace media 478 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698