Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/callback.h" | 5 #include "base/callback.h" |
| 6 #include "media/base/buffers.h" | 6 #include "media/base/buffers.h" |
| 7 #include "media/base/callback.h" | 7 #include "media/base/callback.h" |
| 8 #include "media/base/filter_host.h" | 8 #include "media/base/filter_host.h" |
| 9 #include "media/base/limits.h" | 9 #include "media/base/limits.h" |
| 10 #include "media/base/video_frame.h" | 10 #include "media/base/video_frame.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 static const int kIdleMilliseconds = 10; | 26 static const int kIdleMilliseconds = 10; |
| 27 | 27 |
| 28 VideoRendererBase::VideoRendererBase() | 28 VideoRendererBase::VideoRendererBase() |
| 29 : width_(0), | 29 : width_(0), |
| 30 height_(0), | 30 height_(0), |
| 31 frame_available_(&lock_), | 31 frame_available_(&lock_), |
| 32 state_(kUninitialized), | 32 state_(kUninitialized), |
| 33 thread_(kNullThreadHandle), | 33 thread_(kNullThreadHandle), |
| 34 pending_reads_(0), | 34 pending_reads_(0), |
| 35 pending_paint_(false), | 35 pending_paint_(false), |
| 36 pending_paint_with_last_available_(false), | |
| 36 playback_rate_(0) { | 37 playback_rate_(0) { |
| 37 } | 38 } |
| 38 | 39 |
| 39 VideoRendererBase::~VideoRendererBase() { | 40 VideoRendererBase::~VideoRendererBase() { |
| 40 AutoLock auto_lock(lock_); | 41 AutoLock auto_lock(lock_); |
| 41 DCHECK(state_ == kUninitialized || state_ == kStopped); | 42 DCHECK(state_ == kUninitialized || state_ == kStopped); |
| 42 } | 43 } |
| 43 | 44 |
| 44 // static | 45 // static |
| 45 bool VideoRendererBase::ParseMediaFormat( | 46 bool VideoRendererBase::ParseMediaFormat( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 state_ = kPaused; | 91 state_ = kPaused; |
| 91 } | 92 } |
| 92 | 93 |
| 93 void VideoRendererBase::Flush(FilterCallback* callback) { | 94 void VideoRendererBase::Flush(FilterCallback* callback) { |
| 94 DCHECK_EQ(state_, kPaused); | 95 DCHECK_EQ(state_, kPaused); |
| 95 | 96 |
| 96 AutoLock auto_lock(lock_); | 97 AutoLock auto_lock(lock_); |
| 97 flush_callback_.reset(callback); | 98 flush_callback_.reset(callback); |
| 98 state_ = kFlushing; | 99 state_ = kFlushing; |
| 99 | 100 |
| 100 if (pending_paint_ == false) | 101 if (pending_paint_ == false) |
|
scherkus (not reviewing)
2010/12/20 22:49:55
ditto?
sjl
2010/12/21 22:13:40
Do you mean '&& pending_paint_with_last_available_
| |
| 101 FlushBuffers(); | 102 FlushBuffers(); |
| 102 } | 103 } |
| 103 | 104 |
| 104 void VideoRendererBase::Stop(FilterCallback* callback) { | 105 void VideoRendererBase::Stop(FilterCallback* callback) { |
| 105 DCHECK_EQ(pending_reads_, 0); | 106 DCHECK_EQ(pending_reads_, 0); |
| 106 | 107 |
| 107 { | 108 { |
| 108 AutoLock auto_lock(lock_); | 109 AutoLock auto_lock(lock_); |
| 109 state_ = kStopped; | 110 state_ = kStopped; |
| 110 | 111 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 318 AutoUnlock auto_unlock(lock_); | 319 AutoUnlock auto_unlock(lock_); |
| 319 // Notify subclass that |current_frame_| has been updated. | 320 // Notify subclass that |current_frame_| has been updated. |
| 320 OnFrameAvailable(); | 321 OnFrameAvailable(); |
| 321 } | 322 } |
| 322 } | 323 } |
| 323 } | 324 } |
| 324 } | 325 } |
| 325 | 326 |
| 326 void VideoRendererBase::GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out) { | 327 void VideoRendererBase::GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out) { |
| 327 AutoLock auto_lock(lock_); | 328 AutoLock auto_lock(lock_); |
| 328 DCHECK(!pending_paint_); | 329 DCHECK(!pending_paint_ && !pending_paint_with_last_available_); |
| 329 | 330 |
| 330 if (!current_frame_.get() || current_frame_->IsEndOfStream()) { | 331 if (!current_frame_.get() || current_frame_->IsEndOfStream()) { |
| 331 *frame_out = NULL; | 332 if (!last_available_frame_.get() || |
| 332 return; | 333 last_available_frame_->IsEndOfStream()) { |
| 334 *frame_out = NULL; | |
| 335 return; | |
| 336 } | |
| 333 } | 337 } |
| 334 | 338 |
| 335 // We should have initialized and have the current frame. | 339 // We should have initialized and have the current frame. |
| 336 DCHECK(state_ != kUninitialized && state_ != kStopped && state_ != kError); | 340 DCHECK(state_ != kUninitialized && state_ != kStopped && state_ != kError); |
| 337 *frame_out = current_frame_; | 341 |
| 338 pending_paint_ = true; | 342 if (current_frame_) { |
| 343 *frame_out = current_frame_; | |
| 344 last_available_frame_ = current_frame_; | |
| 345 pending_paint_ = true; | |
| 346 } else { | |
| 347 DCHECK(last_available_frame_.get() != NULL); | |
| 348 *frame_out = last_available_frame_; | |
| 349 pending_paint_with_last_available_ = true; | |
| 350 } | |
| 339 } | 351 } |
| 340 | 352 |
| 341 void VideoRendererBase::PutCurrentFrame(scoped_refptr<VideoFrame> frame) { | 353 void VideoRendererBase::PutCurrentFrame(scoped_refptr<VideoFrame> frame) { |
| 342 AutoLock auto_lock(lock_); | 354 AutoLock auto_lock(lock_); |
| 343 | 355 |
| 344 // Note that we do not claim |pending_paint_| when we return NULL frame, in | 356 // Note that we do not claim |pending_paint_| when we return NULL frame, in |
| 345 // that case, |current_frame_| could be changed before PutCurrentFrame. | 357 // that case, |current_frame_| could be changed before PutCurrentFrame. |
| 346 DCHECK(pending_paint_ || frame.get() == NULL); | 358 if (pending_paint_) { |
| 347 DCHECK(current_frame_.get() == frame.get() || frame.get() == NULL); | 359 DCHECK(current_frame_.get() == frame.get()); |
| 360 DCHECK(pending_paint_with_last_available_ == false); | |
| 361 pending_paint_ = false; | |
| 362 } else if (pending_paint_with_last_available_) { | |
| 363 DCHECK(last_available_frame_.get() == frame.get()); | |
| 364 pending_paint_with_last_available_ = false; | |
| 365 } else { | |
| 366 DCHECK(frame.get() == NULL); | |
| 367 } | |
| 348 | 368 |
| 349 pending_paint_ = false; | |
| 350 // We had cleared the |pending_paint_| flag, there are chances that current | 369 // 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 | 370 // frame is timed-out. We will wake up our main thread to advance the current |
| 352 // frame when this is true. | 371 // frame when this is true. |
| 353 frame_available_.Signal(); | 372 frame_available_.Signal(); |
| 354 if (state_ == kFlushing) | 373 if (state_ == kFlushing) |
| 355 FlushBuffers(); | 374 FlushBuffers(); |
| 356 } | 375 } |
| 357 | 376 |
| 358 void VideoRendererBase::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { | 377 void VideoRendererBase::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { |
| 359 AutoLock auto_lock(lock_); | 378 AutoLock auto_lock(lock_); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 // provide buffer pools. In the future, we may want to implement real | 468 // provide buffer pools. In the future, we may want to implement real |
| 450 // buffer pool to recycle buffers. | 469 // buffer pool to recycle buffers. |
| 451 while (!frames_queue_done_.empty()) { | 470 while (!frames_queue_done_.empty()) { |
| 452 scoped_refptr<VideoFrame> video_frame = frames_queue_done_.front(); | 471 scoped_refptr<VideoFrame> video_frame = frames_queue_done_.front(); |
| 453 frames_queue_done_.pop_front(); | 472 frames_queue_done_.pop_front(); |
| 454 ReadInput(video_frame); | 473 ReadInput(video_frame); |
| 455 } | 474 } |
| 456 } | 475 } |
| 457 | 476 |
| 458 void VideoRendererBase::FlushBuffers() { | 477 void VideoRendererBase::FlushBuffers() { |
| 459 DCHECK(!pending_paint_); | 478 DCHECK(!pending_paint_); |
|
scherkus (not reviewing)
2010/12/20 22:49:55
add a DCHECK for pending_paint_with_last_available
sjl
2010/12/21 22:13:40
As above, it's ok if we have a pending paint on la
| |
| 460 | 479 |
| 461 // We should never put EOF frame into "done queue". | 480 // We should never put EOF frame into "done queue". |
| 462 while (!frames_queue_ready_.empty()) { | 481 while (!frames_queue_ready_.empty()) { |
| 463 scoped_refptr<VideoFrame> video_frame = frames_queue_ready_.front(); | 482 scoped_refptr<VideoFrame> video_frame = frames_queue_ready_.front(); |
| 464 if (!video_frame->IsEndOfStream()) { | 483 if (!video_frame->IsEndOfStream()) { |
| 465 frames_queue_done_.push_back(video_frame); | 484 frames_queue_done_.push_back(video_frame); |
| 466 } | 485 } |
| 467 frames_queue_ready_.pop_front(); | 486 frames_queue_ready_.pop_front(); |
| 468 } | 487 } |
| 469 if (current_frame_.get() && !current_frame_->IsEndOfStream()) { | 488 if (current_frame_.get() && !current_frame_->IsEndOfStream()) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 521 previous_time_ = now; | 540 previous_time_ = now; |
| 522 } | 541 } |
| 523 | 542 |
| 524 // Scale our sleep based on the playback rate. | 543 // Scale our sleep based on the playback rate. |
| 525 // TODO(scherkus): floating point badness and degrade gracefully. | 544 // TODO(scherkus): floating point badness and degrade gracefully. |
| 526 return base::TimeDelta::FromMicroseconds( | 545 return base::TimeDelta::FromMicroseconds( |
| 527 static_cast<int64>(sleep.InMicroseconds() / playback_rate)); | 546 static_cast<int64>(sleep.InMicroseconds() / playback_rate)); |
| 528 } | 547 } |
| 529 | 548 |
| 530 } // namespace media | 549 } // namespace media |
| OLD | NEW |