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

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

Issue 7726002: Completely random typo fixes and style corrections cleanup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/callback.h" 6 #include "base/callback.h"
7 #include "base/threading/platform_thread.h" 7 #include "base/threading/platform_thread.h"
8 #include "media/base/buffers.h" 8 #include "media/base/buffers.h"
9 #include "media/base/callback.h" 9 #include "media/base/callback.h"
10 #include "media/base/filter_host.h" 10 #include "media/base/filter_host.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 } 51 }
52 52
53 void VideoRendererBase::Pause(FilterCallback* callback) { 53 void VideoRendererBase::Pause(FilterCallback* callback) {
54 base::AutoLock auto_lock(lock_); 54 base::AutoLock auto_lock(lock_);
55 DCHECK(state_ != kUninitialized || state_ == kError); 55 DCHECK(state_ != kUninitialized || state_ == kError);
56 AutoCallbackRunner done_runner(callback); 56 AutoCallbackRunner done_runner(callback);
57 state_ = kPaused; 57 state_ = kPaused;
58 } 58 }
59 59
60 void VideoRendererBase::Flush(FilterCallback* callback) { 60 void VideoRendererBase::Flush(FilterCallback* callback) {
61 base::AutoLock auto_lock(lock_);
61 DCHECK_EQ(state_, kPaused); 62 DCHECK_EQ(state_, kPaused);
62
63 base::AutoLock auto_lock(lock_);
64 flush_callback_.reset(callback); 63 flush_callback_.reset(callback);
65 state_ = kFlushing; 64 state_ = kFlushing;
66 65
67 if (pending_paint_ == false) 66 if (!pending_paint_)
68 FlushBuffers(); 67 FlushBuffers_Locked();
69 } 68 }
70 69
71 void VideoRendererBase::Stop(FilterCallback* callback) { 70 void VideoRendererBase::Stop(FilterCallback* callback) {
72 base::PlatformThreadHandle old_thread_handle = base::kNullThreadHandle; 71 base::PlatformThreadHandle old_thread_handle = base::kNullThreadHandle;
73 { 72 {
74 base::AutoLock auto_lock(lock_); 73 base::AutoLock auto_lock(lock_);
75 state_ = kStopped; 74 state_ = kStopped;
76 75
77 if (!pending_paint_ && !pending_paint_with_last_available_) 76 if (!pending_paint_ && !pending_paint_with_last_available_)
78 DoStopOrErrorFlush_Locked(); 77 DoStopOrErrorFlush_Locked();
(...skipping 22 matching lines...) Expand all
101 void VideoRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) { 100 void VideoRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) {
102 bool run_callback = false; 101 bool run_callback = false;
103 102
104 { 103 {
105 base::AutoLock auto_lock(lock_); 104 base::AutoLock auto_lock(lock_);
106 // There is a race condition between filters to receive SeekTask(). 105 // There is a race condition between filters to receive SeekTask().
107 // It turns out we could receive buffer from decoder before seek() 106 // It turns out we could receive buffer from decoder before seek()
108 // is called on us. so we do the following: 107 // is called on us. so we do the following:
109 // kFlushed => ( Receive first buffer or Seek() ) => kSeeking and 108 // kFlushed => ( Receive first buffer or Seek() ) => kSeeking and
110 // kSeeking => ( Receive enough buffers) => kPrerolled. ) 109 // kSeeking => ( Receive enough buffers) => kPrerolled. )
111 DCHECK(kPrerolled == state_ || kFlushed == state_ || kSeeking == state_); 110 DCHECK(state_ == kPrerolled || state_ == kFlushed || state_ == kSeeking);
112 DCHECK(!cb.is_null()); 111 DCHECK(!cb.is_null());
113 DCHECK(seek_cb_.is_null()); 112 DCHECK(seek_cb_.is_null());
114 113
115 if (state_ == kPrerolled) { 114 if (state_ == kPrerolled) {
116 // Already get enough buffers from decoder. 115 // Already get enough buffers from decoder.
117 run_callback = true; 116 run_callback = true;
118 117
119 } else { 118 } else {
120 // Otherwise we are either kFlushed or kSeeking, but without enough 119 // Otherwise we are either kFlushed or kSeeking, but without enough
121 // buffers we should save the callback function and call it later. 120 // buffers we should save the callback function and call it later.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 continue; 253 continue;
255 254
256 scoped_refptr<VideoFrame> next_frame = frames_queue_ready_.front(); 255 scoped_refptr<VideoFrame> next_frame = frames_queue_ready_.front();
257 if (next_frame->IsEndOfStream()) { 256 if (next_frame->IsEndOfStream()) {
258 state_ = kEnded; 257 state_ = kEnded;
259 DVLOG(1) << "Video render gets EOS"; 258 DVLOG(1) << "Video render gets EOS";
260 host()->NotifyEnded(); 259 host()->NotifyEnded();
261 continue; 260 continue;
262 } 261 }
263 262
264 if (next_frame->GetTimestamp() <= host()->GetTime() + kIdleTimeDelta || 263 // Normally we're ready to loop again at this point, but there are
265 current_frame_.get() == NULL || 264 // exceptions that cause us to drop a frame and/or consider painting a
266 current_frame_->GetTimestamp() > host()->GetDuration()) { 265 // "next" frame.
267 // 1. either next frame's time-stamp is already current. 266 if (next_frame->GetTimestamp() > host()->GetTime() + kIdleTimeDelta &&
268 // 2. or we do not have any current frame yet anyway. 267 current_frame_ &&
269 // 3. or a special case when the stream is badly formatted that 268 current_frame_->GetTimestamp() <= host()->GetDuration()) {
270 // we get video frame with time-stamp greater than the duration. 269 continue;
scherkus (not reviewing) 2011/08/24 20:46:37 I love continues
271 // In this case we should proceed anyway and try to obtain the 270 }
272 // end-of-stream packet. 271
273 scoped_refptr<VideoFrame> timeout_frame; 272 // If we got here then:
scherkus (not reviewing) 2011/08/24 20:46:37 nit: I'd put the "either" here and nix the "or"s i
274 bool new_frame_available = false; 273 // 1. either next frame's time-stamp is already current.
scherkus (not reviewing) 2011/08/24 20:46:37 nit: s/time-stamp/timestamp/g
275 if (!pending_paint_) { 274 // 2. or we do not have any current frame yet anyway.
276 // In this case, current frame could be recycled. 275 // 3. or a special case when the stream is badly formatted that
277 timeout_frame = current_frame_; 276 // we get video frame with time-stamp greater than the duration.
278 current_frame_ = frames_queue_ready_.front(); 277 // In this case we should proceed anyway and try to obtain the
278 // end-of-stream packet.
279 scoped_refptr<VideoFrame> timeout_frame;
280 bool new_frame_available = false;
281 if (!pending_paint_) {
282 // In this case, current frame could be recycled.
283 timeout_frame = current_frame_;
284 current_frame_ = frames_queue_ready_.front();
285 frames_queue_ready_.pop_front();
286 new_frame_available = true;
287 } else if (pending_paint_ && frames_queue_ready_.size() >= 2 &&
288 !frames_queue_ready_[1]->IsEndOfStream()) {
289 // Painter could be really slow, therefore we had to skip frames if
290 // 1. We had not reached end of stream.
291 // 2. The next frame of current frame is also out-dated.
292 base::TimeDelta next_remaining_time =
293 frames_queue_ready_[1]->GetTimestamp() - host()->GetTime();
294 if (next_remaining_time.InMicroseconds() <= 0) {
295 // Since the current frame is still hold by painter/compositor, and
296 // the next frame is already timed-out, we should skip the next frame
297 // which is the first frame in the queue.
298 timeout_frame = frames_queue_ready_.front();
279 frames_queue_ready_.pop_front(); 299 frames_queue_ready_.pop_front();
280 new_frame_available = true; 300 ++frames_dropped;
281 } else if (pending_paint_ && frames_queue_ready_.size() >= 2 &&
282 !frames_queue_ready_[1]->IsEndOfStream()) {
283 // Painter could be really slow, therefore we had to skip frames if
284 // 1. We had not reached end of stream.
285 // 2. The next frame of current frame is also out-dated.
286 base::TimeDelta next_remaining_time =
287 frames_queue_ready_[1]->GetTimestamp() - host()->GetTime();
288 if (next_remaining_time.InMicroseconds() <= 0) {
289 // Since the current frame is still hold by painter/compositor, and
290 // the next frame is already timed-out, we should skip the next frame
291 // which is the first frame in the queue.
292 timeout_frame = frames_queue_ready_.front();
293 frames_queue_ready_.pop_front();
294 ++frames_dropped;
295 }
296 } 301 }
297 if (timeout_frame.get()) { 302 }
298 frames_queue_done_.push_back(timeout_frame); 303 if (timeout_frame.get()) {
299 ScheduleRead_Locked(); 304 frames_queue_done_.push_back(timeout_frame);
300 } 305 ScheduleRead_Locked();
301 if (new_frame_available) { 306 }
302 base::AutoUnlock auto_unlock(lock_); 307 if (new_frame_available) {
303 OnFrameAvailable(); 308 base::AutoUnlock auto_unlock(lock_);
304 } 309 OnFrameAvailable();
305 } 310 }
306 } 311 }
307 } 312 }
308 313
309 void VideoRendererBase::GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out) { 314 void VideoRendererBase::GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out) {
310 base::AutoLock auto_lock(lock_); 315 base::AutoLock auto_lock(lock_);
311 DCHECK(!pending_paint_ && !pending_paint_with_last_available_); 316 DCHECK(!pending_paint_ && !pending_paint_with_last_available_);
312 317
313 if ((!current_frame_.get() || current_frame_->IsEndOfStream()) && 318 if ((!current_frame_.get() || current_frame_->IsEndOfStream()) &&
314 (!last_available_frame_.get() || 319 (!last_available_frame_.get() ||
(...skipping 20 matching lines...) Expand all
335 base::AutoLock auto_lock(lock_); 340 base::AutoLock auto_lock(lock_);
336 341
337 // Note that we do not claim |pending_paint_| when we return NULL frame, in 342 // Note that we do not claim |pending_paint_| when we return NULL frame, in
338 // that case, |current_frame_| could be changed before PutCurrentFrame. 343 // that case, |current_frame_| could be changed before PutCurrentFrame.
339 if (pending_paint_) { 344 if (pending_paint_) {
340 DCHECK(current_frame_.get() == frame.get()); 345 DCHECK(current_frame_.get() == frame.get());
341 DCHECK(!pending_paint_with_last_available_); 346 DCHECK(!pending_paint_with_last_available_);
342 pending_paint_ = false; 347 pending_paint_ = false;
343 } else if (pending_paint_with_last_available_) { 348 } else if (pending_paint_with_last_available_) {
344 DCHECK(last_available_frame_.get() == frame.get()); 349 DCHECK(last_available_frame_.get() == frame.get());
350 DCHECK(!pending_paint_);
345 pending_paint_with_last_available_ = false; 351 pending_paint_with_last_available_ = false;
346 } else { 352 } else {
347 DCHECK(frame.get() == NULL); 353 DCHECK(frame.get() == NULL);
348 } 354 }
349 355
350 // We had cleared the |pending_paint_| flag, there are chances that current 356 // We had cleared the |pending_paint_| flag, there are chances that current
351 // frame is timed-out. We will wake up our main thread to advance the current 357 // frame is timed-out. We will wake up our main thread to advance the current
352 // frame when this is true. 358 // frame when this is true.
353 frame_available_.Signal(); 359 frame_available_.Signal();
354 if (state_ == kFlushing) { 360 if (state_ == kFlushing) {
355 FlushBuffers(); 361 FlushBuffers_Locked();
356 } else if (state_ == kError || state_ == kStopped) { 362 } else if (state_ == kError || state_ == kStopped) {
357 DoStopOrErrorFlush_Locked(); 363 DoStopOrErrorFlush_Locked();
358 } 364 }
359 } 365 }
360 366
361 void VideoRendererBase::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { 367 void VideoRendererBase::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) {
362 if (frame) { 368 if (frame) {
363 PipelineStatistics statistics; 369 PipelineStatistics statistics;
364 statistics.video_frames_decoded = 1; 370 statistics.video_frames_decoded = 1;
365 statistics_callback_->Run(statistics); 371 statistics_callback_->Run(statistics);
366 } 372 }
367 373
368 base::AutoLock auto_lock(lock_); 374 base::AutoLock auto_lock(lock_);
369 375
370 if (!frame) { 376 if (!frame) {
371 EnterErrorState_Locked(PIPELINE_ERROR_DECODE); 377 EnterErrorState_Locked(PIPELINE_ERROR_DECODE);
372 return; 378 return;
373 } 379 }
374 380
375 // Decoder could reach seek state before our Seek() get called. 381 // Decoder could reach seek state before our Seek() get called.
376 // We will enter kSeeking 382 // We will enter kSeeking
377 if (kFlushed == state_) 383 if (state_ == kFlushed)
378 state_ = kSeeking; 384 state_ = kSeeking;
379 385
380 // Synchronous flush between filters should prevent this from happening. 386 // Synchronous flush between filters should prevent this from happening.
381 DCHECK_NE(state_, kStopped); 387 DCHECK_NE(state_, kStopped);
382 if (frame.get() && !frame->IsEndOfStream()) 388 if (frame.get() && !frame->IsEndOfStream())
383 --pending_reads_; 389 --pending_reads_;
384 390
385 DCHECK(state_ != kUninitialized && state_ != kStopped && state_ != kError); 391 DCHECK(state_ != kUninitialized && state_ != kStopped && state_ != kError);
386 392
387 if (state_ == kPaused || state_ == kFlushing) { 393 if (state_ == kPaused || state_ == kFlushing) {
388 // Decoder are flushing rubbish video frame, we will not display them. 394 // Decoder are flushing rubbish video frame, we will not display them.
389 if (frame.get() && !frame->IsEndOfStream()) 395 if (frame.get() && !frame->IsEndOfStream())
390 frames_queue_done_.push_back(frame); 396 frames_queue_done_.push_back(frame);
391 DCHECK_LE(frames_queue_done_.size(), 397 DCHECK_LE(frames_queue_done_.size(),
392 static_cast<size_t>(Limits::kMaxVideoFrames)); 398 static_cast<size_t>(Limits::kMaxVideoFrames));
393 399
394 // Excluding kPause here, because in pause state, we will never 400 // Excluding kPause here, because in pause state, we will never
395 // transfer out-bounding buffer. We do not flush buffer when Compositor 401 // transfer out-bounding buffer. We do not flush buffer when Compositor
396 // hold reference to our video frame either. 402 // hold reference to our video frame either.
397 if (state_ == kFlushing && pending_paint_ == false) 403 if (state_ == kFlushing && pending_paint_ == false)
398 FlushBuffers(); 404 FlushBuffers_Locked();
399 405
400 return; 406 return;
401 } 407 }
402 408
403 // Discard frames until we reach our desired seek timestamp. 409 // Discard frames until we reach our desired seek timestamp.
404 if (state_ == kSeeking && !frame->IsEndOfStream() && 410 if (state_ == kSeeking && !frame->IsEndOfStream() &&
405 (frame->GetTimestamp() + frame->GetDuration()) <= seek_timestamp_) { 411 (frame->GetTimestamp() + frame->GetDuration()) <= seek_timestamp_) {
406 frames_queue_done_.push_back(frame); 412 frames_queue_done_.push_back(frame);
407 ScheduleRead_Locked(); 413 ScheduleRead_Locked();
408 } else { 414 } else {
(...skipping 24 matching lines...) Expand all
433 new_frame_available = true; 439 new_frame_available = true;
434 440
435 // If we reach prerolled state before Seek() is called by pipeline, 441 // If we reach prerolled state before Seek() is called by pipeline,
436 // |seek_callback_| is not set, we will return immediately during 442 // |seek_callback_| is not set, we will return immediately during
437 // when Seek() is eventually called. 443 // when Seek() is eventually called.
438 if (!seek_cb_.is_null()) { 444 if (!seek_cb_.is_null()) {
439 ResetAndRunCB(&seek_cb_, PIPELINE_OK); 445 ResetAndRunCB(&seek_cb_, PIPELINE_OK);
440 } 446 }
441 } 447 }
442 } else if (state_ == kFlushing && pending_reads_ == 0 && !pending_paint_) { 448 } else if (state_ == kFlushing && pending_reads_ == 0 && !pending_paint_) {
443 OnFlushDone(); 449 OnFlushDone_Locked();
444 } 450 }
445 451
446 if (new_frame_available) { 452 if (new_frame_available) {
447 base::AutoUnlock auto_unlock(lock_); 453 base::AutoUnlock auto_unlock(lock_);
448 OnFrameAvailable(); 454 OnFrameAvailable();
449 } 455 }
450 } 456 }
451 457
452 void VideoRendererBase::ReadInput(scoped_refptr<VideoFrame> frame) { 458 void VideoRendererBase::ReadInput(scoped_refptr<VideoFrame> frame) {
453 // We should never return empty frames or EOS frame. 459 // We should never return empty frames or EOS frame.
454 DCHECK(frame.get() && !frame->IsEndOfStream()); 460 DCHECK(frame.get() && !frame->IsEndOfStream());
455 461
456 decoder_->ProduceVideoFrame(frame); 462 decoder_->ProduceVideoFrame(frame);
457 ++pending_reads_; 463 ++pending_reads_;
458 } 464 }
459 465
460 void VideoRendererBase::ScheduleRead_Locked() { 466 void VideoRendererBase::ScheduleRead_Locked() {
461 lock_.AssertAcquired(); 467 lock_.AssertAcquired();
462 DCHECK_NE(kEnded, state_); 468 DCHECK_NE(kEnded, state_);
463 // TODO(jiesun): We use dummy buffer to feed decoder to let decoder to 469 // TODO(jiesun): We use dummy buffer to feed decoder to let decoder to
464 // provide buffer pools. In the future, we may want to implement real 470 // provide buffer pools. In the future, we may want to implement real
465 // buffer pool to recycle buffers. 471 // buffer pool to recycle buffers.
466 while (!frames_queue_done_.empty()) { 472 while (!frames_queue_done_.empty()) {
467 scoped_refptr<VideoFrame> video_frame = frames_queue_done_.front(); 473 scoped_refptr<VideoFrame> video_frame = frames_queue_done_.front();
468 frames_queue_done_.pop_front(); 474 frames_queue_done_.pop_front();
469 ReadInput(video_frame); 475 ReadInput(video_frame);
470 } 476 }
471 } 477 }
472 478
473 void VideoRendererBase::FlushBuffers() { 479 void VideoRendererBase::FlushBuffers_Locked() {
480 lock_.AssertAcquired();
474 DCHECK(!pending_paint_); 481 DCHECK(!pending_paint_);
475 482
476 // We should never put EOF frame into "done queue". 483 // We should never put EOF frame into "done queue".
477 while (!frames_queue_ready_.empty()) { 484 while (!frames_queue_ready_.empty()) {
478 scoped_refptr<VideoFrame> video_frame = frames_queue_ready_.front(); 485 scoped_refptr<VideoFrame> video_frame = frames_queue_ready_.front();
479 if (!video_frame->IsEndOfStream()) { 486 if (!video_frame->IsEndOfStream()) {
480 frames_queue_done_.push_back(video_frame); 487 frames_queue_done_.push_back(video_frame);
481 } 488 }
482 frames_queue_ready_.pop_front(); 489 frames_queue_ready_.pop_front();
483 } 490 }
484 if (current_frame_.get() && !current_frame_->IsEndOfStream()) { 491 if (current_frame_.get() && !current_frame_->IsEndOfStream()) {
485 frames_queue_done_.push_back(current_frame_); 492 frames_queue_done_.push_back(current_frame_);
486 } 493 }
487 current_frame_ = NULL; 494 current_frame_ = NULL;
488 495
489 // Flush all buffers out to decoder. 496 // Flush all buffers out to decoder.
490 ScheduleRead_Locked(); 497 ScheduleRead_Locked();
491 498
492 if (pending_reads_ == 0 && state_ == kFlushing) 499 if (pending_reads_ == 0 && state_ == kFlushing)
493 OnFlushDone(); 500 OnFlushDone_Locked();
494 } 501 }
495 502
496 void VideoRendererBase::OnFlushDone() { 503 void VideoRendererBase::OnFlushDone_Locked() {
497 // Check all buffers are return to owners. 504 lock_.AssertAcquired();
505 // Check all buffers are returned to owners.
498 DCHECK_EQ(frames_queue_done_.size(), 0u); 506 DCHECK_EQ(frames_queue_done_.size(), 0u);
499 DCHECK(!current_frame_.get()); 507 DCHECK(!current_frame_.get());
500 DCHECK(frames_queue_ready_.empty()); 508 DCHECK(frames_queue_ready_.empty());
501 509
502 if (flush_callback_.get()) { // This ensures callback is invoked once. 510 if (flush_callback_.get()) { // This ensures callback is invoked once.
503 flush_callback_->Run(); 511 flush_callback_->Run();
504 flush_callback_.reset(); 512 flush_callback_.reset();
505 } 513 }
506 state_ = kFlushed; 514 state_ = kFlushed;
507 } 515 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 host()->SetError(status); 586 host()->SetError(status);
579 587
580 if (callback.get()) 588 if (callback.get())
581 callback->Run(); 589 callback->Run();
582 } 590 }
583 591
584 void VideoRendererBase::DoStopOrErrorFlush_Locked() { 592 void VideoRendererBase::DoStopOrErrorFlush_Locked() {
585 DCHECK(!pending_paint_); 593 DCHECK(!pending_paint_);
586 DCHECK(!pending_paint_with_last_available_); 594 DCHECK(!pending_paint_with_last_available_);
587 lock_.AssertAcquired(); 595 lock_.AssertAcquired();
588 FlushBuffers(); 596 FlushBuffers_Locked();
589 last_available_frame_ = NULL; 597 last_available_frame_ = NULL;
590 DCHECK_EQ(pending_reads_, 0); 598 DCHECK_EQ(pending_reads_, 0);
591 } 599 }
592 600
593 } // namespace media 601 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698