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

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

Powered by Google App Engine
This is Rietveld 408576698