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

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

Issue 335273002: Fix seeking when the start time is non-zero. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Created 6 years, 6 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/mock_filters.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "media/base/pipeline.h" 5 #include "media/base/pipeline.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 379
380 case kInitVideoRenderer: 380 case kInitVideoRenderer:
381 return InitializeVideoRenderer(done_cb); 381 return InitializeVideoRenderer(done_cb);
382 382
383 case kInitPrerolling: 383 case kInitPrerolling:
384 filter_collection_.reset(); 384 filter_collection_.reset();
385 { 385 {
386 base::AutoLock l(lock_); 386 base::AutoLock l(lock_);
387 // We do not want to start the clock running. We only want to set the 387 // We do not want to start the clock running. We only want to set the
388 // base media time so our timestamp calculations will be correct. 388 // base media time so our timestamp calculations will be correct.
389 clock_->SetTime(demuxer_->GetStartTime(), demuxer_->GetStartTime()); 389 clock_->SetTime(base::TimeDelta(), base::TimeDelta());
390 } 390 }
391 if (!audio_renderer_ && !video_renderer_) { 391 if (!audio_renderer_ && !video_renderer_) {
392 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); 392 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER);
393 return; 393 return;
394 } 394 }
395 395
396 { 396 {
397 PipelineMetadata metadata; 397 PipelineMetadata metadata;
398 metadata.has_audio = audio_renderer_; 398 metadata.has_audio = audio_renderer_;
399 metadata.has_video = video_renderer_; 399 metadata.has_video = video_renderer_;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 // in the following DoXXX() functions is considered safe as they are owned by 438 // in the following DoXXX() functions is considered safe as they are owned by
439 // |pending_callbacks_| and share the same lifetime. 439 // |pending_callbacks_| and share the same lifetime.
440 // 440 //
441 // That being said, deleting the renderers while keeping |pending_callbacks_| 441 // That being said, deleting the renderers while keeping |pending_callbacks_|
442 // running on the media thread would result in crashes. 442 // running on the media thread would result in crashes.
443 void Pipeline::DoInitialPreroll(const PipelineStatusCB& done_cb) { 443 void Pipeline::DoInitialPreroll(const PipelineStatusCB& done_cb) {
444 DCHECK(task_runner_->BelongsToCurrentThread()); 444 DCHECK(task_runner_->BelongsToCurrentThread());
445 DCHECK(!pending_callbacks_.get()); 445 DCHECK(!pending_callbacks_.get());
446 SerialRunner::Queue bound_fns; 446 SerialRunner::Queue bound_fns;
447 447
448 base::TimeDelta seek_timestamp = demuxer_->GetStartTime(); 448 const base::TimeDelta seek_timestamp = base::TimeDelta();
449 449
450 // Preroll renderers. 450 // Preroll renderers.
451 if (audio_renderer_) { 451 if (audio_renderer_) {
452 bound_fns.Push(base::Bind( 452 bound_fns.Push(base::Bind(
453 &AudioRenderer::Preroll, base::Unretained(audio_renderer_.get()), 453 &AudioRenderer::Preroll, base::Unretained(audio_renderer_.get()),
454 seek_timestamp)); 454 seek_timestamp));
455 } 455 }
456 456
457 if (video_renderer_) { 457 if (video_renderer_) {
458 bound_fns.Push(base::Bind( 458 bound_fns.Push(base::Bind(
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 // TODO(scherkus): should we run the callback? I'm tempted to say the API 736 // TODO(scherkus): should we run the callback? I'm tempted to say the API
737 // will only execute the first Seek() request. 737 // will only execute the first Seek() request.
738 DVLOG(1) << "Media pipeline has not started, ignoring seek to " 738 DVLOG(1) << "Media pipeline has not started, ignoring seek to "
739 << time.InMicroseconds() << " (current state: " << state_ << ")"; 739 << time.InMicroseconds() << " (current state: " << state_ << ")";
740 return; 740 return;
741 } 741 }
742 742
743 DCHECK(seek_cb_.is_null()); 743 DCHECK(seek_cb_.is_null());
744 744
745 SetState(kSeeking); 745 SetState(kSeeking);
746 base::TimeDelta seek_timestamp = std::max(time, demuxer_->GetStartTime());
747 seek_cb_ = seek_cb; 746 seek_cb_ = seek_cb;
748 audio_ended_ = false; 747 audio_ended_ = false;
749 video_ended_ = false; 748 video_ended_ = false;
750 text_ended_ = false; 749 text_ended_ = false;
751 750
752 // Kick off seeking! 751 // Kick off seeking!
753 { 752 {
754 base::AutoLock auto_lock(lock_); 753 base::AutoLock auto_lock(lock_);
755 PauseClockAndStopRendering_Locked(); 754 PauseClockAndStopRendering_Locked();
756 clock_->SetTime(seek_timestamp, seek_timestamp); 755 clock_->SetTime(time, time);
757 } 756 }
758 DoSeek(seek_timestamp, base::Bind( 757 DoSeek(time, base::Bind(
759 &Pipeline::OnStateTransition, base::Unretained(this))); 758 &Pipeline::OnStateTransition, base::Unretained(this)));
760 } 759 }
761 760
762 void Pipeline::DoAudioRendererEnded() { 761 void Pipeline::DoAudioRendererEnded() {
763 DCHECK(task_runner_->BelongsToCurrentThread()); 762 DCHECK(task_runner_->BelongsToCurrentThread());
764 763
765 if (state_ != kPlaying) 764 if (state_ != kPlaying)
766 return; 765 return;
767 766
768 DCHECK(!audio_ended_); 767 DCHECK(!audio_ended_);
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 976 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
978 lock_.AssertAcquired(); 977 lock_.AssertAcquired();
979 if (clock_state_ != CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE) 978 if (clock_state_ != CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE)
980 return; 979 return;
981 980
982 clock_state_ = CLOCK_PLAYING; 981 clock_state_ = CLOCK_PLAYING;
983 clock_->Play(); 982 clock_->Play();
984 } 983 }
985 984
986 } // namespace media 985 } // namespace media
OLDNEW
« no previous file with comments | « media/base/mock_filters.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698