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

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

Issue 9155003: Fix media timeline so that thumb never exceeds buffered data (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 11 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) 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698