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

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

Issue 1815013002: Restore CDM context on Resume(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Embarassing typo. Created 4 years, 9 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
« no previous file with comments | « media/base/pipeline_impl.h ('k') | no next file » | 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_impl.h" 5 #include "media/base/pipeline_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 29 matching lines...) Expand all
40 running_(false), 40 running_(false),
41 did_loading_progress_(false), 41 did_loading_progress_(false),
42 volume_(1.0f), 42 volume_(1.0f),
43 playback_rate_(0.0), 43 playback_rate_(0.0),
44 status_(PIPELINE_OK), 44 status_(PIPELINE_OK),
45 state_(kCreated), 45 state_(kCreated),
46 suspend_timestamp_(kNoTimestamp()), 46 suspend_timestamp_(kNoTimestamp()),
47 renderer_ended_(false), 47 renderer_ended_(false),
48 text_renderer_ended_(false), 48 text_renderer_ended_(false),
49 demuxer_(NULL), 49 demuxer_(NULL),
50 pending_cdm_context_(nullptr), 50 cdm_context_(nullptr),
51 weak_factory_(this) { 51 weak_factory_(this) {
52 weak_this_ = weak_factory_.GetWeakPtr();
52 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); 53 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
53 } 54 }
54 55
55 PipelineImpl::~PipelineImpl() { 56 PipelineImpl::~PipelineImpl() {
56 DCHECK(thread_checker_.CalledOnValidThread()) 57 DCHECK(thread_checker_.CalledOnValidThread())
57 << "Pipeline must be destroyed on same thread that created it"; 58 << "Pipeline must be destroyed on same thread that created it";
58 DCHECK(!running_) << "Stop() must complete before destroying object"; 59 DCHECK(!running_) << "Stop() must complete before destroying object";
59 DCHECK(stop_cb_.is_null()); 60 DCHECK(stop_cb_.is_null());
60 DCHECK(seek_cb_.is_null()); 61 DCHECK(seek_cb_.is_null());
61 } 62 }
(...skipping 22 matching lines...) Expand all
84 renderer_ = std::move(renderer); 85 renderer_ = std::move(renderer);
85 ended_cb_ = ended_cb; 86 ended_cb_ = ended_cb;
86 error_cb_ = error_cb; 87 error_cb_ = error_cb;
87 seek_cb_ = seek_cb; 88 seek_cb_ = seek_cb;
88 metadata_cb_ = metadata_cb; 89 metadata_cb_ = metadata_cb;
89 buffering_state_cb_ = buffering_state_cb; 90 buffering_state_cb_ = buffering_state_cb;
90 duration_change_cb_ = duration_change_cb; 91 duration_change_cb_ = duration_change_cb;
91 add_text_track_cb_ = add_text_track_cb; 92 add_text_track_cb_ = add_text_track_cb;
92 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; 93 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
93 94
94 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::StartTask, 95 task_runner_->PostTask(FROM_HERE,
95 weak_factory_.GetWeakPtr())); 96 base::Bind(&PipelineImpl::StartTask, weak_this_));
96 } 97 }
97 98
98 void PipelineImpl::Stop(const base::Closure& stop_cb) { 99 void PipelineImpl::Stop(const base::Closure& stop_cb) {
99 DVLOG(2) << __FUNCTION__; 100 DVLOG(2) << __FUNCTION__;
100 task_runner_->PostTask( 101 task_runner_->PostTask(
101 FROM_HERE, 102 FROM_HERE, base::Bind(&PipelineImpl::StopTask, weak_this_, stop_cb));
102 base::Bind(&PipelineImpl::StopTask, weak_factory_.GetWeakPtr(), stop_cb));
103 } 103 }
104 104
105 void PipelineImpl::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) { 105 void PipelineImpl::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) {
106 base::AutoLock auto_lock(lock_); 106 base::AutoLock auto_lock(lock_);
107 if (!running_) { 107 if (!running_) {
108 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek()."; 108 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek().";
109 return; 109 return;
110 } 110 }
111 111
112 task_runner_->PostTask( 112 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SeekTask,
113 FROM_HERE, base::Bind(&PipelineImpl::SeekTask, weak_factory_.GetWeakPtr(), 113 weak_this_, time, seek_cb));
114 time, seek_cb));
115 } 114 }
116 115
117 bool PipelineImpl::IsRunning() const { 116 bool PipelineImpl::IsRunning() const {
118 base::AutoLock auto_lock(lock_); 117 base::AutoLock auto_lock(lock_);
119 return running_; 118 return running_;
120 } 119 }
121 120
122 double PipelineImpl::GetPlaybackRate() const { 121 double PipelineImpl::GetPlaybackRate() const {
123 base::AutoLock auto_lock(lock_); 122 base::AutoLock auto_lock(lock_);
124 return playback_rate_; 123 return playback_rate_;
125 } 124 }
126 125
127 void PipelineImpl::SetPlaybackRate(double playback_rate) { 126 void PipelineImpl::SetPlaybackRate(double playback_rate) {
128 if (playback_rate < 0.0) 127 if (playback_rate < 0.0)
129 return; 128 return;
130 129
131 base::AutoLock auto_lock(lock_); 130 base::AutoLock auto_lock(lock_);
132 playback_rate_ = playback_rate; 131 playback_rate_ = playback_rate;
133 if (running_) { 132 if (running_) {
134 task_runner_->PostTask( 133 task_runner_->PostTask(FROM_HERE,
135 FROM_HERE, base::Bind(&PipelineImpl::PlaybackRateChangedTask, 134 base::Bind(&PipelineImpl::PlaybackRateChangedTask,
136 weak_factory_.GetWeakPtr(), playback_rate)); 135 weak_this_, playback_rate));
137 } 136 }
138 } 137 }
139 138
140 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) { 139 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) {
141 task_runner_->PostTask(FROM_HERE, 140 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SuspendTask,
142 base::Bind(&PipelineImpl::SuspendTask, 141 weak_this_, suspend_cb));
143 weak_factory_.GetWeakPtr(), suspend_cb));
144 } 142 }
145 143
146 void PipelineImpl::Resume(scoped_ptr<Renderer> renderer, 144 void PipelineImpl::Resume(scoped_ptr<Renderer> renderer,
147 base::TimeDelta timestamp, 145 base::TimeDelta timestamp,
148 const PipelineStatusCB& seek_cb) { 146 const PipelineStatusCB& seek_cb) {
149 task_runner_->PostTask( 147 task_runner_->PostTask(
150 FROM_HERE, 148 FROM_HERE, base::Bind(&PipelineImpl::ResumeTask, weak_this_,
151 base::Bind(&PipelineImpl::ResumeTask, weak_factory_.GetWeakPtr(), 149 base::Passed(&renderer), timestamp, seek_cb));
152 base::Passed(&renderer), timestamp, seek_cb));
153 } 150 }
154 151
155 float PipelineImpl::GetVolume() const { 152 float PipelineImpl::GetVolume() const {
156 base::AutoLock auto_lock(lock_); 153 base::AutoLock auto_lock(lock_);
157 return volume_; 154 return volume_;
158 } 155 }
159 156
160 void PipelineImpl::SetVolume(float volume) { 157 void PipelineImpl::SetVolume(float volume) {
161 if (volume < 0.0f || volume > 1.0f) 158 if (volume < 0.0f || volume > 1.0f)
162 return; 159 return;
163 160
164 base::AutoLock auto_lock(lock_); 161 base::AutoLock auto_lock(lock_);
165 volume_ = volume; 162 volume_ = volume;
166 if (running_) { 163 if (running_) {
167 task_runner_->PostTask(FROM_HERE, 164 task_runner_->PostTask(
168 base::Bind(&PipelineImpl::VolumeChangedTask, 165 FROM_HERE,
169 weak_factory_.GetWeakPtr(), volume)); 166 base::Bind(&PipelineImpl::VolumeChangedTask, weak_this_, volume));
170 } 167 }
171 } 168 }
172 169
173 TimeDelta PipelineImpl::GetMediaTime() const { 170 TimeDelta PipelineImpl::GetMediaTime() const {
174 base::AutoLock auto_lock(lock_); 171 base::AutoLock auto_lock(lock_);
175 if (suspend_timestamp_ != kNoTimestamp()) 172 if (suspend_timestamp_ != kNoTimestamp())
176 return suspend_timestamp_; 173 return suspend_timestamp_;
177 return renderer_ ? std::min(renderer_->GetMediaTime(), duration_) 174 return renderer_ ? std::min(renderer_->GetMediaTime(), duration_)
178 : TimeDelta(); 175 : TimeDelta();
179 } 176 }
(...skipping 15 matching lines...) Expand all
195 return ret; 192 return ret;
196 } 193 }
197 194
198 PipelineStatistics PipelineImpl::GetStatistics() const { 195 PipelineStatistics PipelineImpl::GetStatistics() const {
199 base::AutoLock auto_lock(lock_); 196 base::AutoLock auto_lock(lock_);
200 return statistics_; 197 return statistics_;
201 } 198 }
202 199
203 void PipelineImpl::SetCdm(CdmContext* cdm_context, 200 void PipelineImpl::SetCdm(CdmContext* cdm_context,
204 const CdmAttachedCB& cdm_attached_cb) { 201 const CdmAttachedCB& cdm_attached_cb) {
205 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SetCdmTask, 202 task_runner_->PostTask(
206 weak_factory_.GetWeakPtr(), 203 FROM_HERE, base::Bind(&PipelineImpl::SetCdmTask, weak_this_, cdm_context,
207 cdm_context, cdm_attached_cb)); 204 cdm_attached_cb));
208 } 205 }
209 206
210 void PipelineImpl::SetErrorForTesting(PipelineStatus status) { 207 void PipelineImpl::SetErrorForTesting(PipelineStatus status) {
211 OnError(status); 208 OnError(status);
212 } 209 }
213 210
214 bool PipelineImpl::HasWeakPtrsForTesting() const { 211 bool PipelineImpl::HasWeakPtrsForTesting() const {
215 DCHECK(task_runner_->BelongsToCurrentThread()); 212 DCHECK(task_runner_->BelongsToCurrentThread());
216 return weak_factory_.HasWeakPtrs(); 213 return weak_factory_.HasWeakPtrs();
217 } 214 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 case kPlaying: 272 case kPlaying:
276 case kStopping: 273 case kStopping:
277 case kStopped: 274 case kStopped:
278 break; 275 break;
279 } 276 }
280 NOTREACHED() << "State has no transition: " << state_; 277 NOTREACHED() << "State has no transition: " << state_;
281 return state_; 278 return state_;
282 } 279 }
283 280
284 void PipelineImpl::OnDemuxerError(PipelineStatus error) { 281 void PipelineImpl::OnDemuxerError(PipelineStatus error) {
285 task_runner_->PostTask(FROM_HERE, 282 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::ErrorChangedTask,
286 base::Bind(&PipelineImpl::ErrorChangedTask, 283 weak_this_, error));
287 weak_factory_.GetWeakPtr(), error));
288 } 284 }
289 285
290 void PipelineImpl::AddTextStream(DemuxerStream* text_stream, 286 void PipelineImpl::AddTextStream(DemuxerStream* text_stream,
291 const TextTrackConfig& config) { 287 const TextTrackConfig& config) {
292 task_runner_->PostTask( 288 task_runner_->PostTask(
293 FROM_HERE, base::Bind(&PipelineImpl::AddTextStreamTask, 289 FROM_HERE, base::Bind(&PipelineImpl::AddTextStreamTask, weak_this_,
294 weak_factory_.GetWeakPtr(), text_stream, config)); 290 text_stream, config));
295 } 291 }
296 292
297 void PipelineImpl::RemoveTextStream(DemuxerStream* text_stream) { 293 void PipelineImpl::RemoveTextStream(DemuxerStream* text_stream) {
298 task_runner_->PostTask(FROM_HERE, 294 task_runner_->PostTask(
299 base::Bind(&PipelineImpl::RemoveTextStreamTask, 295 FROM_HERE,
300 weak_factory_.GetWeakPtr(), text_stream)); 296 base::Bind(&PipelineImpl::RemoveTextStreamTask, weak_this_, text_stream));
301 } 297 }
302 298
303 void PipelineImpl::OnError(PipelineStatus error) { 299 void PipelineImpl::OnError(PipelineStatus error) {
304 DCHECK(task_runner_->BelongsToCurrentThread()); 300 DCHECK(task_runner_->BelongsToCurrentThread());
305 DCHECK(IsRunning()); 301 DCHECK(IsRunning());
306 DCHECK_NE(PIPELINE_OK, error); 302 DCHECK_NE(PIPELINE_OK, error);
307 VLOG(1) << "Media pipeline error: " << error; 303 VLOG(1) << "Media pipeline error: " << error;
308 304
309 task_runner_->PostTask(FROM_HERE, 305 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::ErrorChangedTask,
310 base::Bind(&PipelineImpl::ErrorChangedTask, 306 weak_this_, error));
311 weak_factory_.GetWeakPtr(), error));
312 } 307 }
313 308
314 void PipelineImpl::SetDuration(TimeDelta duration) { 309 void PipelineImpl::SetDuration(TimeDelta duration) {
315 DCHECK(IsRunning()); 310 DCHECK(IsRunning());
316 media_log_->AddEvent(media_log_->CreateTimeEvent(MediaLogEvent::DURATION_SET, 311 media_log_->AddEvent(media_log_->CreateTimeEvent(MediaLogEvent::DURATION_SET,
317 "duration", duration)); 312 "duration", duration));
318 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); 313 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration);
319 314
320 base::AutoLock auto_lock(lock_); 315 base::AutoLock auto_lock(lock_);
321 duration_ = duration; 316 duration_ = duration;
(...skipping 17 matching lines...) Expand all
339 return; 334 return;
340 } 335 }
341 336
342 // Guard against accidentally clearing |pending_callbacks_| for states that 337 // Guard against accidentally clearing |pending_callbacks_| for states that
343 // use it as well as states that should not be using it. 338 // use it as well as states that should not be using it.
344 DCHECK_EQ(pending_callbacks_.get() != NULL, 339 DCHECK_EQ(pending_callbacks_.get() != NULL,
345 state_ == kSeeking || state_ == kSuspending || state_ == kResuming); 340 state_ == kSeeking || state_ == kSuspending || state_ == kResuming);
346 341
347 pending_callbacks_.reset(); 342 pending_callbacks_.reset();
348 343
349 PipelineStatusCB done_cb = base::Bind(&PipelineImpl::StateTransitionTask, 344 PipelineStatusCB done_cb =
350 weak_factory_.GetWeakPtr()); 345 base::Bind(&PipelineImpl::StateTransitionTask, weak_this_);
351 346
352 // Switch states, performing any entrance actions for the new state as well. 347 // Switch states, performing any entrance actions for the new state as well.
353 SetState(GetNextState()); 348 SetState(GetNextState());
354 switch (state_) { 349 switch (state_) {
355 case kInitDemuxer: 350 case kInitDemuxer:
356 return InitializeDemuxer(done_cb); 351 return InitializeDemuxer(done_cb);
357 352
358 case kInitRenderer: 353 case kInitRenderer:
359 // When the state_ transfers to kInitRenderer, it means the demuxer has 354 // When the state_ transfers to kInitRenderer, it means the demuxer has
360 // finished parsing the init info. It should call ReportMetadata in case 355 // finished parsing the init info. It should call ReportMetadata in case
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 } 517 }
523 518
524 void PipelineImpl::StartTask() { 519 void PipelineImpl::StartTask() {
525 DCHECK(task_runner_->BelongsToCurrentThread()); 520 DCHECK(task_runner_->BelongsToCurrentThread());
526 521
527 CHECK_EQ(kCreated, state_) 522 CHECK_EQ(kCreated, state_)
528 << "Media pipeline cannot be started more than once"; 523 << "Media pipeline cannot be started more than once";
529 524
530 text_renderer_ = CreateTextRenderer(); 525 text_renderer_ = CreateTextRenderer();
531 if (text_renderer_) { 526 if (text_renderer_) {
532 text_renderer_->Initialize(base::Bind(&PipelineImpl::OnTextRendererEnded, 527 text_renderer_->Initialize(
533 weak_factory_.GetWeakPtr())); 528 base::Bind(&PipelineImpl::OnTextRendererEnded, weak_this_));
534 }
535
536 // Set CDM early to avoid unnecessary delay in Renderer::Initialize().
537 if (pending_cdm_context_) {
538 renderer_->SetCdm(pending_cdm_context_, base::Bind(&IgnoreCdmAttached));
539 pending_cdm_context_ = nullptr;
540 } 529 }
541 530
542 StateTransitionTask(PIPELINE_OK); 531 StateTransitionTask(PIPELINE_OK);
543 } 532 }
544 533
545 void PipelineImpl::StopTask(const base::Closure& stop_cb) { 534 void PipelineImpl::StopTask(const base::Closure& stop_cb) {
546 DCHECK(task_runner_->BelongsToCurrentThread()); 535 DCHECK(task_runner_->BelongsToCurrentThread());
547 DCHECK(stop_cb_.is_null()); 536 DCHECK(stop_cb_.is_null());
548 537
549 if (state_ == kStopped) { 538 if (state_ == kStopped) {
(...skipping 19 matching lines...) Expand all
569 state_ == kSuspended || state_ == kResuming) { 558 state_ == kSuspended || state_ == kResuming) {
570 PipelineStatistics stats = GetStatistics(); 559 PipelineStatistics stats = GetStatistics();
571 if (stats.video_frames_decoded > 0) { 560 if (stats.video_frames_decoded > 0) {
572 UMA_HISTOGRAM_COUNTS("Media.DroppedFrameCount", 561 UMA_HISTOGRAM_COUNTS("Media.DroppedFrameCount",
573 stats.video_frames_dropped); 562 stats.video_frames_dropped);
574 } 563 }
575 } 564 }
576 565
577 SetState(kStopping); 566 SetState(kStopping);
578 pending_callbacks_.reset(); 567 pending_callbacks_.reset();
579 DoStop( 568 DoStop(base::Bind(&PipelineImpl::OnStopCompleted, weak_this_));
580 base::Bind(&PipelineImpl::OnStopCompleted, weak_factory_.GetWeakPtr()));
581 } 569 }
582 570
583 void PipelineImpl::ErrorChangedTask(PipelineStatus error) { 571 void PipelineImpl::ErrorChangedTask(PipelineStatus error) {
584 DCHECK(task_runner_->BelongsToCurrentThread()); 572 DCHECK(task_runner_->BelongsToCurrentThread());
585 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; 573 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!";
586 574
587 // Don't report pipeline error events to the media log here. The embedder will 575 // Don't report pipeline error events to the media log here. The embedder will
588 // log this when |error_cb_| is called. If the pipeline is already stopped or 576 // log this when |error_cb_| is called. If the pipeline is already stopped or
589 // stopping we also don't want to log any event. In case we are suspending or 577 // stopping we also don't want to log any event. In case we are suspending or
590 // suspended, the error may be recoverable, so don't propagate it now, instead 578 // suspended, the error may be recoverable, so don't propagate it now, instead
591 // let the subsequent seek during resume propagate it if it's unrecoverable. 579 // let the subsequent seek during resume propagate it if it's unrecoverable.
592 580
593 if (state_ == kStopping || state_ == kStopped || state_ == kSuspending || 581 if (state_ == kStopping || state_ == kStopped || state_ == kSuspending ||
594 state_ == kSuspended) { 582 state_ == kSuspended) {
595 return; 583 return;
596 } 584 }
597 585
598 SetState(kStopping); 586 SetState(kStopping);
599 pending_callbacks_.reset(); 587 pending_callbacks_.reset();
600 status_ = error; 588 status_ = error;
601 589
602 DoStop( 590 DoStop(base::Bind(&PipelineImpl::OnStopCompleted, weak_this_));
603 base::Bind(&PipelineImpl::OnStopCompleted, weak_factory_.GetWeakPtr()));
604 } 591 }
605 592
606 void PipelineImpl::PlaybackRateChangedTask(double playback_rate) { 593 void PipelineImpl::PlaybackRateChangedTask(double playback_rate) {
607 DCHECK(task_runner_->BelongsToCurrentThread()); 594 DCHECK(task_runner_->BelongsToCurrentThread());
608 595
609 // Playback rate changes are only carried out while playing. 596 // Playback rate changes are only carried out while playing.
610 if (state_ != kPlaying) 597 if (state_ != kPlaying)
611 return; 598 return;
612 599
613 renderer_->SetPlaybackRate(playback_rate); 600 renderer_->SetPlaybackRate(playback_rate);
(...skipping 25 matching lines...) Expand all
639 626
640 const base::TimeDelta seek_timestamp = 627 const base::TimeDelta seek_timestamp =
641 std::max(time, demuxer_->GetStartTime()); 628 std::max(time, demuxer_->GetStartTime());
642 629
643 SetState(kSeeking); 630 SetState(kSeeking);
644 seek_cb_ = seek_cb; 631 seek_cb_ = seek_cb;
645 renderer_ended_ = false; 632 renderer_ended_ = false;
646 text_renderer_ended_ = false; 633 text_renderer_ended_ = false;
647 start_timestamp_ = seek_timestamp; 634 start_timestamp_ = seek_timestamp;
648 635
649 DoSeek(seek_timestamp, base::Bind(&PipelineImpl::StateTransitionTask, 636 DoSeek(seek_timestamp,
650 weak_factory_.GetWeakPtr())); 637 base::Bind(&PipelineImpl::StateTransitionTask, weak_this_));
651 } 638 }
652 639
653 void PipelineImpl::SuspendTask(const PipelineStatusCB& suspend_cb) { 640 void PipelineImpl::SuspendTask(const PipelineStatusCB& suspend_cb) {
654 DCHECK(task_runner_->BelongsToCurrentThread()); 641 DCHECK(task_runner_->BelongsToCurrentThread());
655 642
656 // Suppress suspending if we're not playing. 643 // Suppress suspending if we're not playing.
657 if (state_ != kPlaying) { 644 if (state_ != kPlaying) {
658 DCHECK(state_ == kStopping || state_ == kStopped) 645 DCHECK(state_ == kStopping || state_ == kStopped)
659 << "Receive suspend in unexpected state: " << state_; 646 << "Receive suspend in unexpected state: " << state_;
660 suspend_cb.Run(PIPELINE_ERROR_INVALID_STATE); 647 suspend_cb.Run(PIPELINE_ERROR_INVALID_STATE);
(...skipping 24 matching lines...) Expand all
685 base::Unretained(text_renderer_.get()))); 672 base::Unretained(text_renderer_.get())));
686 } 673 }
687 674
688 fns.Push(base::Bind(&Renderer::Flush, base::Unretained(renderer_.get()))); 675 fns.Push(base::Bind(&Renderer::Flush, base::Unretained(renderer_.get())));
689 676
690 if (text_renderer_) { 677 if (text_renderer_) {
691 fns.Push(base::Bind(&TextRenderer::Flush, 678 fns.Push(base::Bind(&TextRenderer::Flush,
692 base::Unretained(text_renderer_.get()))); 679 base::Unretained(text_renderer_.get())));
693 } 680 }
694 681
695 pending_callbacks_ = 682 pending_callbacks_ = SerialRunner::Run(
696 SerialRunner::Run(fns, base::Bind(&PipelineImpl::StateTransitionTask, 683 fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this_));
697 weak_factory_.GetWeakPtr()));
698 } 684 }
699 685
700 void PipelineImpl::ResumeTask(scoped_ptr<Renderer> renderer, 686 void PipelineImpl::ResumeTask(scoped_ptr<Renderer> renderer,
701 base::TimeDelta timestamp, 687 base::TimeDelta timestamp,
702 const PipelineStatusCB& seek_cb) { 688 const PipelineStatusCB& seek_cb) {
703 DCHECK(task_runner_->BelongsToCurrentThread()); 689 DCHECK(task_runner_->BelongsToCurrentThread());
704 690
705 // Suppress resuming if we're not suspended. 691 // Suppress resuming if we're not suspended.
706 if (state_ != kSuspended) { 692 if (state_ != kSuspended) {
707 DCHECK(state_ == kStopping || state_ == kStopped) 693 DCHECK(state_ == kStopping || state_ == kStopped)
(...skipping 12 matching lines...) Expand all
720 seek_cb_ = seek_cb; 706 seek_cb_ = seek_cb;
721 renderer_ended_ = false; 707 renderer_ended_ = false;
722 text_renderer_ended_ = false; 708 text_renderer_ended_ = false;
723 start_timestamp_ = std::max(timestamp, demuxer_->GetStartTime()); 709 start_timestamp_ = std::max(timestamp, demuxer_->GetStartTime());
724 710
725 // Queue the asynchronous actions required to start playback. Unlike DoSeek(), 711 // Queue the asynchronous actions required to start playback. Unlike DoSeek(),
726 // we need to initialize the renderer ourselves (we don't want to enter state 712 // we need to initialize the renderer ourselves (we don't want to enter state
727 // kInitDemuxer, and even if we did the current code would seek to the start 713 // kInitDemuxer, and even if we did the current code would seek to the start
728 // instead of |timestamp|). 714 // instead of |timestamp|).
729 SerialRunner::Queue fns; 715 SerialRunner::Queue fns;
730 base::WeakPtr<PipelineImpl> weak_this = weak_factory_.GetWeakPtr();
731 716
732 fns.Push( 717 fns.Push(
733 base::Bind(&Demuxer::Seek, base::Unretained(demuxer_), start_timestamp_)); 718 base::Bind(&Demuxer::Seek, base::Unretained(demuxer_), start_timestamp_));
734 719
735 fns.Push(base::Bind(&PipelineImpl::InitializeRenderer, weak_this)); 720 fns.Push(base::Bind(&PipelineImpl::InitializeRenderer, weak_this_));
736 721
737 pending_callbacks_ = SerialRunner::Run( 722 pending_callbacks_ = SerialRunner::Run(
738 fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this)); 723 fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this_));
739 } 724 }
740 725
741 void PipelineImpl::SetCdmTask(CdmContext* cdm_context, 726 void PipelineImpl::SetCdmTask(CdmContext* cdm_context,
742 const CdmAttachedCB& cdm_attached_cb) { 727 const CdmAttachedCB& cdm_attached_cb) {
743 base::AutoLock auto_lock(lock_); 728 base::AutoLock auto_lock(lock_);
744 if (!renderer_) { 729 if (!renderer_) {
745 pending_cdm_context_ = cdm_context; 730 cdm_context_ = cdm_context;
746 cdm_attached_cb.Run(true); 731 cdm_attached_cb.Run(true);
747 return; 732 return;
748 } 733 }
749 734
750 renderer_->SetCdm(cdm_context, cdm_attached_cb); 735 renderer_->SetCdm(cdm_context,
736 base::Bind(&PipelineImpl::OnCdmAttached, weak_this_,
737 cdm_attached_cb, cdm_context));
738 }
739
740 void PipelineImpl::OnCdmAttached(const CdmAttachedCB& cdm_attached_cb,
741 CdmContext* cdm_context,
742 bool success) {
743 DCHECK(task_runner_->BelongsToCurrentThread());
744 if (success)
745 cdm_context_ = cdm_context;
746 cdm_attached_cb.Run(success);
751 } 747 }
752 748
753 void PipelineImpl::OnRendererEnded() { 749 void PipelineImpl::OnRendererEnded() {
754 DCHECK(task_runner_->BelongsToCurrentThread()); 750 DCHECK(task_runner_->BelongsToCurrentThread());
755 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); 751 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED));
756 752
757 if (state_ != kPlaying) 753 if (state_ != kPlaying)
758 return; 754 return;
759 755
760 DCHECK(!renderer_ended_); 756 DCHECK(!renderer_ended_);
(...skipping 29 matching lines...) Expand all
790 } 786 }
791 787
792 scoped_ptr<TextRenderer> PipelineImpl::CreateTextRenderer() { 788 scoped_ptr<TextRenderer> PipelineImpl::CreateTextRenderer() {
793 DCHECK(task_runner_->BelongsToCurrentThread()); 789 DCHECK(task_runner_->BelongsToCurrentThread());
794 790
795 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 791 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
796 if (!cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) 792 if (!cmd_line->HasSwitch(switches::kEnableInbandTextTracks))
797 return scoped_ptr<media::TextRenderer>(); 793 return scoped_ptr<media::TextRenderer>();
798 794
799 return scoped_ptr<media::TextRenderer>(new media::TextRenderer( 795 return scoped_ptr<media::TextRenderer>(new media::TextRenderer(
800 task_runner_, 796 task_runner_, base::Bind(&PipelineImpl::OnAddTextTrack, weak_this_)));
801 base::Bind(&PipelineImpl::OnAddTextTrack, weak_factory_.GetWeakPtr())));
802 } 797 }
803 798
804 void PipelineImpl::AddTextStreamTask(DemuxerStream* text_stream, 799 void PipelineImpl::AddTextStreamTask(DemuxerStream* text_stream,
805 const TextTrackConfig& config) { 800 const TextTrackConfig& config) {
806 DCHECK(task_runner_->BelongsToCurrentThread()); 801 DCHECK(task_runner_->BelongsToCurrentThread());
807 // TODO(matthewjheaney): fix up text_ended_ when text stream 802 // TODO(matthewjheaney): fix up text_ended_ when text stream
808 // is added (http://crbug.com/321446). 803 // is added (http://crbug.com/321446).
809 if (text_renderer_) 804 if (text_renderer_)
810 text_renderer_->AddTextStream(text_stream, config); 805 text_renderer_->AddTextStream(text_stream, config);
811 } 806 }
(...skipping 21 matching lines...) Expand all
833 if (!demuxer_->GetStream(DemuxerStream::AUDIO) && 828 if (!demuxer_->GetStream(DemuxerStream::AUDIO) &&
834 !demuxer_->GetStream(DemuxerStream::VIDEO)) { 829 !demuxer_->GetStream(DemuxerStream::VIDEO)) {
835 { 830 {
836 base::AutoLock auto_lock(lock_); 831 base::AutoLock auto_lock(lock_);
837 renderer_.reset(); 832 renderer_.reset();
838 } 833 }
839 OnError(PIPELINE_ERROR_COULD_NOT_RENDER); 834 OnError(PIPELINE_ERROR_COULD_NOT_RENDER);
840 return; 835 return;
841 } 836 }
842 837
843 base::WeakPtr<PipelineImpl> weak_this = weak_factory_.GetWeakPtr(); 838 if (cdm_context_)
839 renderer_->SetCdm(cdm_context_, base::Bind(&IgnoreCdmAttached));
840
844 renderer_->Initialize( 841 renderer_->Initialize(
845 demuxer_, done_cb, 842 demuxer_, done_cb,
846 base::Bind(&PipelineImpl::OnUpdateStatistics, weak_this), 843 base::Bind(&PipelineImpl::OnUpdateStatistics, weak_this_),
847 base::Bind(&PipelineImpl::BufferingStateChanged, weak_this), 844 base::Bind(&PipelineImpl::BufferingStateChanged, weak_this_),
848 base::Bind(&PipelineImpl::OnRendererEnded, weak_this), 845 base::Bind(&PipelineImpl::OnRendererEnded, weak_this_),
849 base::Bind(&PipelineImpl::OnError, weak_this), 846 base::Bind(&PipelineImpl::OnError, weak_this_),
850 waiting_for_decryption_key_cb_); 847 waiting_for_decryption_key_cb_);
851 } 848 }
852 849
853 void PipelineImpl::ReportMetadata() { 850 void PipelineImpl::ReportMetadata() {
854 DCHECK(task_runner_->BelongsToCurrentThread()); 851 DCHECK(task_runner_->BelongsToCurrentThread());
855 PipelineMetadata metadata; 852 PipelineMetadata metadata;
856 metadata.timeline_offset = demuxer_->GetTimelineOffset(); 853 metadata.timeline_offset = demuxer_->GetTimelineOffset();
857 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 854 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
858 if (stream) { 855 if (stream) {
859 metadata.has_video = true; 856 metadata.has_video = true;
860 metadata.natural_size = stream->video_decoder_config().natural_size(); 857 metadata.natural_size = stream->video_decoder_config().natural_size();
861 metadata.video_rotation = stream->video_rotation(); 858 metadata.video_rotation = stream->video_rotation();
862 } 859 }
863 if (demuxer_->GetStream(DemuxerStream::AUDIO)) { 860 if (demuxer_->GetStream(DemuxerStream::AUDIO)) {
864 metadata.has_audio = true; 861 metadata.has_audio = true;
865 } 862 }
866 metadata_cb_.Run(metadata); 863 metadata_cb_.Run(metadata);
867 } 864 }
868 865
869 void PipelineImpl::BufferingStateChanged(BufferingState new_buffering_state) { 866 void PipelineImpl::BufferingStateChanged(BufferingState new_buffering_state) {
870 DVLOG(1) << __FUNCTION__ << "(" << new_buffering_state << ") "; 867 DVLOG(1) << __FUNCTION__ << "(" << new_buffering_state << ") ";
871 DCHECK(task_runner_->BelongsToCurrentThread()); 868 DCHECK(task_runner_->BelongsToCurrentThread());
872 buffering_state_cb_.Run(new_buffering_state); 869 buffering_state_cb_.Run(new_buffering_state);
873 } 870 }
874 871
875 } // namespace media 872 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698