| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/filter_host.h" | 9 #include "media/base/filter_host.h" |
| 10 #include "media/base/limits.h" | 10 #include "media/base/limits.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 AttemptFlush_Locked(); | 57 AttemptFlush_Locked(); |
| 58 } | 58 } |
| 59 | 59 |
| 60 void VideoRendererBase::Stop(const base::Closure& callback) { | 60 void VideoRendererBase::Stop(const base::Closure& callback) { |
| 61 base::PlatformThreadHandle thread_to_join = base::kNullThreadHandle; | 61 base::PlatformThreadHandle thread_to_join = base::kNullThreadHandle; |
| 62 { | 62 { |
| 63 base::AutoLock auto_lock(lock_); | 63 base::AutoLock auto_lock(lock_); |
| 64 state_ = kStopped; | 64 state_ = kStopped; |
| 65 | 65 |
| 66 statistics_callback_.Reset(); |
| 67 video_time_cb_.Reset(); |
| 66 if (!pending_paint_ && !pending_paint_with_last_available_) | 68 if (!pending_paint_ && !pending_paint_with_last_available_) |
| 67 DoStopOrError_Locked(); | 69 DoStopOrError_Locked(); |
| 68 | 70 |
| 69 // Clean up our thread if present. | 71 // Clean up our thread if present. |
| 70 if (thread_ != base::kNullThreadHandle) { | 72 if (thread_ != base::kNullThreadHandle) { |
| 71 // Signal the thread since it's possible to get stopped with the video | 73 // Signal the thread since it's possible to get stopped with the video |
| 72 // thread waiting for a read to complete. | 74 // thread waiting for a read to complete. |
| 73 frame_available_.Signal(); | 75 frame_available_.Signal(); |
| 74 thread_to_join = thread_; | 76 thread_to_join = thread_; |
| 75 thread_ = base::kNullThreadHandle; | 77 thread_ = base::kNullThreadHandle; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 92 DCHECK(!cb.is_null()); | 94 DCHECK(!cb.is_null()); |
| 93 DCHECK(seek_cb_.is_null()); | 95 DCHECK(seek_cb_.is_null()); |
| 94 | 96 |
| 95 state_ = kSeeking; | 97 state_ = kSeeking; |
| 96 seek_cb_ = cb; | 98 seek_cb_ = cb; |
| 97 seek_timestamp_ = time; | 99 seek_timestamp_ = time; |
| 98 AttemptRead_Locked(); | 100 AttemptRead_Locked(); |
| 99 } | 101 } |
| 100 | 102 |
| 101 void VideoRendererBase::Initialize(VideoDecoder* decoder, | 103 void VideoRendererBase::Initialize(VideoDecoder* decoder, |
| 102 const base::Closure& callback, | 104 const base::Closure& init_cb, |
| 103 const StatisticsCallback& stats_callback) { | 105 const StatisticsCallback& stats_callback, |
| 106 const VideoTimeCB& video_time_cb) { |
| 104 base::AutoLock auto_lock(lock_); | 107 base::AutoLock auto_lock(lock_); |
| 105 DCHECK(decoder); | 108 DCHECK(decoder); |
| 106 DCHECK(!callback.is_null()); | 109 DCHECK(!init_cb.is_null()); |
| 107 DCHECK(!stats_callback.is_null()); | 110 DCHECK(!stats_callback.is_null()); |
| 111 DCHECK(!video_time_cb.is_null()); |
| 108 DCHECK_EQ(kUninitialized, state_); | 112 DCHECK_EQ(kUninitialized, state_); |
| 109 decoder_ = decoder; | 113 decoder_ = decoder; |
| 110 | 114 |
| 111 statistics_callback_ = stats_callback; | 115 statistics_callback_ = stats_callback; |
| 116 video_time_cb_ = video_time_cb; |
| 112 | 117 |
| 113 // Notify the pipeline of the video dimensions. | 118 // Notify the pipeline of the video dimensions. |
| 114 host()->SetNaturalVideoSize(decoder_->natural_size()); | 119 host()->SetNaturalVideoSize(decoder_->natural_size()); |
| 115 | 120 |
| 116 // We're all good! Consider ourselves flushed. (ThreadMain() should never | 121 // We're all good! Consider ourselves flushed. (ThreadMain() should never |
| 117 // see us in the kUninitialized state). | 122 // see us in the kUninitialized state). |
| 118 // Since we had an initial Seek, we consider ourself flushed, because we | 123 // Since we had an initial Seek, we consider ourself flushed, because we |
| 119 // have not populated any buffers yet. | 124 // have not populated any buffers yet. |
| 120 state_ = kFlushed; | 125 state_ = kFlushed; |
| 121 | 126 |
| 122 set_opaque_cb_.Run(!decoder->HasAlpha()); | 127 set_opaque_cb_.Run(!decoder->HasAlpha()); |
| 123 set_opaque_cb_.Reset(); | 128 set_opaque_cb_.Reset(); |
| 124 | 129 |
| 125 // Create our video thread. | 130 // Create our video thread. |
| 126 if (!base::PlatformThread::Create(0, this, &thread_)) { | 131 if (!base::PlatformThread::Create(0, this, &thread_)) { |
| 127 NOTREACHED() << "Video thread creation failed"; | 132 NOTREACHED() << "Video thread creation failed"; |
| 128 state_ = kError; | 133 state_ = kError; |
| 129 host()->SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); | 134 host()->SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| 130 callback.Run(); | 135 init_cb.Run(); |
| 131 return; | 136 return; |
| 132 } | 137 } |
| 133 | 138 |
| 134 #if defined(OS_WIN) | 139 #if defined(OS_WIN) |
| 135 // Bump up our priority so our sleeping is more accurate. | 140 // Bump up our priority so our sleeping is more accurate. |
| 136 // TODO(scherkus): find out if this is necessary, but it seems to help. | 141 // TODO(scherkus): find out if this is necessary, but it seems to help. |
| 137 ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); | 142 ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); |
| 138 #endif // defined(OS_WIN) | 143 #endif // defined(OS_WIN) |
| 139 callback.Run(); | 144 init_cb.Run(); |
| 140 } | 145 } |
| 141 | 146 |
| 142 bool VideoRendererBase::HasEnded() { | 147 bool VideoRendererBase::HasEnded() { |
| 143 base::AutoLock auto_lock(lock_); | 148 base::AutoLock auto_lock(lock_); |
| 144 return state_ == kEnded; | 149 return state_ == kEnded; |
| 145 } | 150 } |
| 146 | 151 |
| 147 // PlatformThread::Delegate implementation. | 152 // PlatformThread::Delegate implementation. |
| 148 void VideoRendererBase::ThreadMain() { | 153 void VideoRendererBase::ThreadMain() { |
| 149 base::PlatformThread::SetName("CrVideoRenderer"); | 154 base::PlatformThread::SetName("CrVideoRenderer"); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 // frame rate. | 367 // frame rate. |
| 363 if (!frame->IsEndOfStream() && | 368 if (!frame->IsEndOfStream() && |
| 364 (frame->GetTimestamp() + frame->GetDuration()) > host()->GetDuration()) { | 369 (frame->GetTimestamp() + frame->GetDuration()) > host()->GetDuration()) { |
| 365 frame->SetDuration(host()->GetDuration() - frame->GetTimestamp()); | 370 frame->SetDuration(host()->GetDuration() - frame->GetTimestamp()); |
| 366 } | 371 } |
| 367 | 372 |
| 368 // This one's a keeper! Place it in the ready queue. | 373 // This one's a keeper! Place it in the ready queue. |
| 369 ready_frames_.push_back(frame); | 374 ready_frames_.push_back(frame); |
| 370 DCHECK_LE(ready_frames_.size(), | 375 DCHECK_LE(ready_frames_.size(), |
| 371 static_cast<size_t>(limits::kMaxVideoFrames)); | 376 static_cast<size_t>(limits::kMaxVideoFrames)); |
| 377 video_time_cb_.Run(frame->GetTimestamp() + frame->GetDuration()); |
| 372 frame_available_.Signal(); | 378 frame_available_.Signal(); |
| 373 | 379 |
| 374 PipelineStatistics statistics; | 380 PipelineStatistics statistics; |
| 375 statistics.video_frames_decoded = 1; | 381 statistics.video_frames_decoded = 1; |
| 376 statistics_callback_.Run(statistics); | 382 statistics_callback_.Run(statistics); |
| 377 | 383 |
| 378 int outstanding_frames = | 384 int outstanding_frames = |
| 379 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + | 385 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + |
| 380 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); | 386 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); |
| 381 // Always request more decoded video if we have capacity. This serves two | 387 // Always request more decoded video if we have capacity. This serves two |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 | 465 |
| 460 void VideoRendererBase::DoStopOrError_Locked() { | 466 void VideoRendererBase::DoStopOrError_Locked() { |
| 461 DCHECK(!pending_paint_); | 467 DCHECK(!pending_paint_); |
| 462 DCHECK(!pending_paint_with_last_available_); | 468 DCHECK(!pending_paint_with_last_available_); |
| 463 lock_.AssertAcquired(); | 469 lock_.AssertAcquired(); |
| 464 current_frame_ = NULL; | 470 current_frame_ = NULL; |
| 465 last_available_frame_ = NULL; | 471 last_available_frame_ = NULL; |
| 466 } | 472 } |
| 467 | 473 |
| 468 } // namespace media | 474 } // namespace media |
| OLD | NEW |