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

Side by Side Diff: media/base/pipeline_impl.cc

Issue 165163: Merge 21882 - Implemented a proper clock for audio/video synchronization.... (Closed) Base URL: svn://chrome-svn/chrome/branches/195/src/
Patch Set: Created 11 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
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/filters/video_renderer_base.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Modified: svn:mergeinfo
Merged /trunk/src/media/base/pipeline_impl.cc:r21882
OLDNEW
1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008-2009 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 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, 5 // TODO(scherkus): clean up PipelineImpl... too many crazy function names,
6 // potential deadlocks, etc... 6 // potential deadlocks, etc...
7 7
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/condition_variable.h" 9 #include "base/condition_variable.h"
10 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 CHECK(*count >= 0); 66 CHECK(*count >= 0);
67 if (*count == 0) { 67 if (*count == 0) {
68 cond_var->Signal(); 68 cond_var->Signal();
69 } 69 }
70 } 70 }
71 71
72 } // namespace 72 } // namespace
73 73
74 PipelineImpl::PipelineImpl(MessageLoop* message_loop) 74 PipelineImpl::PipelineImpl(MessageLoop* message_loop)
75 : message_loop_(message_loop), 75 : message_loop_(message_loop),
76 clock_(&base::Time::Now),
76 state_(kCreated), 77 state_(kCreated),
77 remaining_transitions_(0) { 78 remaining_transitions_(0) {
78 ResetState(); 79 ResetState();
79 } 80 }
80 81
81 PipelineImpl::~PipelineImpl() { 82 PipelineImpl::~PipelineImpl() {
82 AutoLock auto_lock(lock_); 83 AutoLock auto_lock(lock_);
83 DCHECK(!running_) << "Stop() must complete before destroying object"; 84 DCHECK(!running_) << "Stop() must complete before destroying object";
84 } 85 }
85 86
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 volume_ = volume; 195 volume_ = volume;
195 if (running_) { 196 if (running_) {
196 message_loop_->PostTask(FROM_HERE, 197 message_loop_->PostTask(FROM_HERE,
197 NewRunnableMethod(this, &PipelineImpl::VolumeChangedTask, 198 NewRunnableMethod(this, &PipelineImpl::VolumeChangedTask,
198 volume)); 199 volume));
199 } 200 }
200 } 201 }
201 202
202 base::TimeDelta PipelineImpl::GetCurrentTime() const { 203 base::TimeDelta PipelineImpl::GetCurrentTime() const {
203 AutoLock auto_lock(lock_); 204 AutoLock auto_lock(lock_);
204 return time_; 205 return clock_.Elapsed();
205 } 206 }
206 207
207 base::TimeDelta PipelineImpl::GetBufferedTime() const { 208 base::TimeDelta PipelineImpl::GetBufferedTime() const {
208 AutoLock auto_lock(lock_); 209 AutoLock auto_lock(lock_);
209 return buffered_time_; 210 return buffered_time_;
210 } 211 }
211 212
212 base::TimeDelta PipelineImpl::GetDuration() const { 213 base::TimeDelta PipelineImpl::GetDuration() const {
213 AutoLock auto_lock(lock_); 214 AutoLock auto_lock(lock_);
214 return duration_; 215 return duration_;
(...skipping 21 matching lines...) Expand all
236 AutoLock auto_lock(lock_); 237 AutoLock auto_lock(lock_);
237 return error_; 238 return error_;
238 } 239 }
239 240
240 void PipelineImpl::SetPipelineErrorCallback(PipelineCallback* error_callback) { 241 void PipelineImpl::SetPipelineErrorCallback(PipelineCallback* error_callback) {
241 error_callback_.reset(error_callback); 242 error_callback_.reset(error_callback);
242 } 243 }
243 244
244 void PipelineImpl::ResetState() { 245 void PipelineImpl::ResetState() {
245 AutoLock auto_lock(lock_); 246 AutoLock auto_lock(lock_);
247 const base::TimeDelta kZero;
246 running_ = false; 248 running_ = false;
247 duration_ = base::TimeDelta(); 249 duration_ = kZero;
248 buffered_time_ = base::TimeDelta(); 250 buffered_time_ = kZero;
249 buffered_bytes_ = 0; 251 buffered_bytes_ = 0;
250 total_bytes_ = 0; 252 total_bytes_ = 0;
251 video_width_ = 0; 253 video_width_ = 0;
252 video_height_ = 0; 254 video_height_ = 0;
253 volume_ = 1.0f; 255 volume_ = 1.0f;
254 playback_rate_ = 0.0f; 256 playback_rate_ = 0.0f;
255 error_ = PIPELINE_OK; 257 error_ = PIPELINE_OK;
256 time_ = base::TimeDelta(); 258 clock_.SetTime(kZero);
257 rendered_mime_types_.clear(); 259 rendered_mime_types_.clear();
258 } 260 }
259 261
260 bool PipelineImpl::IsPipelineOk() { 262 bool PipelineImpl::IsPipelineOk() {
261 return PIPELINE_OK == GetError(); 263 return PIPELINE_OK == GetError();
262 } 264 }
263 265
264 bool PipelineImpl::IsPipelineInitializing() { 266 bool PipelineImpl::IsPipelineInitializing() {
265 DCHECK_EQ(MessageLoop::current(), message_loop_); 267 DCHECK_EQ(MessageLoop::current(), message_loop_);
266 return state_ == kInitDataSource || 268 return state_ == kInitDataSource ||
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 302 }
301 303
302 base::TimeDelta PipelineImpl::GetTime() const { 304 base::TimeDelta PipelineImpl::GetTime() const {
303 DCHECK(IsRunning()); 305 DCHECK(IsRunning());
304 return GetCurrentTime(); 306 return GetCurrentTime();
305 } 307 }
306 308
307 void PipelineImpl::SetTime(base::TimeDelta time) { 309 void PipelineImpl::SetTime(base::TimeDelta time) {
308 DCHECK(IsRunning()); 310 DCHECK(IsRunning());
309 AutoLock auto_lock(lock_); 311 AutoLock auto_lock(lock_);
310 time_ = time; 312 clock_.SetTime(time);
311 } 313 }
312 314
313 void PipelineImpl::SetDuration(base::TimeDelta duration) { 315 void PipelineImpl::SetDuration(base::TimeDelta duration) {
314 DCHECK(IsRunning()); 316 DCHECK(IsRunning());
315 AutoLock auto_lock(lock_); 317 AutoLock auto_lock(lock_);
316 duration_ = duration; 318 duration_ = duration;
317 } 319 }
318 320
319 void PipelineImpl::SetBufferedTime(base::TimeDelta buffered_time) { 321 void PipelineImpl::SetBufferedTime(base::TimeDelta buffered_time) {
320 DCHECK(IsRunning()); 322 DCHECK(IsRunning());
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 542
541 // If our owner has requested to be notified of an error, execute 543 // If our owner has requested to be notified of an error, execute
542 // |error_callback_| unless we have a "good" error. 544 // |error_callback_| unless we have a "good" error.
543 if (error_callback_.get() && error != PIPELINE_STOPPING) { 545 if (error_callback_.get() && error != PIPELINE_STOPPING) {
544 error_callback_->Run(); 546 error_callback_->Run();
545 } 547 }
546 } 548 }
547 549
548 void PipelineImpl::PlaybackRateChangedTask(float playback_rate) { 550 void PipelineImpl::PlaybackRateChangedTask(float playback_rate) {
549 DCHECK_EQ(MessageLoop::current(), message_loop_); 551 DCHECK_EQ(MessageLoop::current(), message_loop_);
552 clock_.SetPlaybackRate(playback_rate);
550 for (FilterVector::iterator iter = filters_.begin(); 553 for (FilterVector::iterator iter = filters_.begin();
551 iter != filters_.end(); 554 iter != filters_.end();
552 ++iter) { 555 ++iter) {
553 (*iter)->SetPlaybackRate(playback_rate); 556 (*iter)->SetPlaybackRate(playback_rate);
554 } 557 }
555 } 558 }
556 559
557 void PipelineImpl::VolumeChangedTask(float volume) { 560 void PipelineImpl::VolumeChangedTask(float volume) {
558 DCHECK_EQ(MessageLoop::current(), message_loop_); 561 DCHECK_EQ(MessageLoop::current(), message_loop_);
559 562
(...skipping 24 matching lines...) Expand all
584 // kPausing (for each filter) 587 // kPausing (for each filter)
585 // kSeeking (for each filter) 588 // kSeeking (for each filter)
586 // kStarting (for each filter) 589 // kStarting (for each filter)
587 // kStarted 590 // kStarted
588 state_ = kPausing; 591 state_ = kPausing;
589 seek_timestamp_ = time; 592 seek_timestamp_ = time;
590 seek_callback_.reset(seek_callback); 593 seek_callback_.reset(seek_callback);
591 remaining_transitions_ = filters_.size(); 594 remaining_transitions_ = filters_.size();
592 595
593 // Kick off seeking! 596 // Kick off seeking!
597 clock_.Pause();
594 filters_.front()->Pause( 598 filters_.front()->Pause(
595 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); 599 NewCallback(this, &PipelineImpl::OnFilterStateTransition));
596 } 600 }
597 601
598 void PipelineImpl::FilterStateTransitionTask() { 602 void PipelineImpl::FilterStateTransitionTask() {
599 DCHECK_EQ(MessageLoop::current(), message_loop_); 603 DCHECK_EQ(MessageLoop::current(), message_loop_);
600 604
601 if (!StateTransitionsToStarted(state_)) { 605 if (!StateTransitionsToStarted(state_)) {
602 NOTREACHED() << "Invalid current state: " << state_; 606 NOTREACHED() << "Invalid current state: " << state_;
603 SetError(PIPELINE_ERROR_ABORT); 607 SetError(PIPELINE_ERROR_ABORT);
604 return; 608 return;
605 } 609 }
606 610
607 // Decrement the number of remaining transitions, making sure to transition 611 // Decrement the number of remaining transitions, making sure to transition
608 // to the next state if needed. 612 // to the next state if needed.
609 CHECK(remaining_transitions_ <= filters_.size()); 613 CHECK(remaining_transitions_ <= filters_.size());
610 CHECK(remaining_transitions_ > 0u); 614 CHECK(remaining_transitions_ > 0u);
611 if (--remaining_transitions_ == 0) { 615 if (--remaining_transitions_ == 0) {
612 state_ = FindNextState(state_); 616 state_ = FindNextState(state_);
617 if (state_ == kSeeking) {
618 clock_.SetTime(seek_timestamp_);
619 } else if (state_ == kStarting) {
620 clock_.Play();
621 }
622
613 if (StateTransitionsToStarted(state_)) { 623 if (StateTransitionsToStarted(state_)) {
614 remaining_transitions_ = filters_.size(); 624 remaining_transitions_ = filters_.size();
615 } 625 }
616 } 626 }
617 627
618 // Carry out the action for the current state. 628 // Carry out the action for the current state.
619 if (StateTransitionsToStarted(state_)) { 629 if (StateTransitionsToStarted(state_)) {
620 MediaFilter* filter = filters_[filters_.size() - remaining_transitions_]; 630 MediaFilter* filter = filters_[filters_.size() - remaining_transitions_];
621 if (state_ == kPausing) { 631 if (state_ == kPausing) {
622 filter->Pause(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); 632 filter->Pause(NewCallback(this, &PipelineImpl::OnFilterStateTransition));
623 } else if (state_ == kSeeking) { 633 } else if (state_ == kSeeking) {
624 filter->Seek(seek_timestamp_, 634 filter->Seek(seek_timestamp_,
625 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); 635 NewCallback(this, &PipelineImpl::OnFilterStateTransition));
626 } else if (state_ == kStarting) { 636 } else if (state_ == kStarting) {
627 filter->Play(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); 637 filter->Play(NewCallback(this, &PipelineImpl::OnFilterStateTransition));
628 } else { 638 } else {
629 NOTREACHED(); 639 NOTREACHED();
630 } 640 }
631 } else if (state_ == kStarted) { 641 } else if (state_ == kStarted) {
632 // We've completed the seek, update the time.
633 SetTime(seek_timestamp_);
634
635 // Execute the seek callback, if present. Note that this might be the 642 // Execute the seek callback, if present. Note that this might be the
636 // initial callback passed into Start(). 643 // initial callback passed into Start().
637 if (seek_callback_.get()) { 644 if (seek_callback_.get()) {
638 seek_callback_->Run(); 645 seek_callback_->Run();
639 seek_callback_.reset(); 646 seek_callback_.reset();
640 } 647 }
641 648
642 // Finally, reset our seeking timestamp back to zero. 649 // Finally, reset our seeking timestamp back to zero.
643 seek_timestamp_ = base::TimeDelta(); 650 seek_timestamp_ = base::TimeDelta();
644 } else { 651 } else {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 809
803 // Reset the pipeline, which will decrement a reference to this object. 810 // Reset the pipeline, which will decrement a reference to this object.
804 // We will get destroyed as soon as the remaining tasks finish executing. 811 // We will get destroyed as soon as the remaining tasks finish executing.
805 // To be safe, we'll set our pipeline reference to NULL. 812 // To be safe, we'll set our pipeline reference to NULL.
806 filters_.clear(); 813 filters_.clear();
807 filter_types_.clear(); 814 filter_types_.clear();
808 STLDeleteElements(&filter_threads_); 815 STLDeleteElements(&filter_threads_);
809 } 816 }
810 817
811 } // namespace media 818 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/filters/video_renderer_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698