Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 void Suspend(); | 50 void Suspend(); |
| 51 void Resume(std::unique_ptr<Renderer> renderer, base::TimeDelta time); | 51 void Resume(std::unique_ptr<Renderer> renderer, base::TimeDelta time); |
| 52 void SetPlaybackRate(double playback_rate); | 52 void SetPlaybackRate(double playback_rate); |
| 53 void SetVolume(float volume); | 53 void SetVolume(float volume); |
| 54 base::TimeDelta GetMediaTime() const; | 54 base::TimeDelta GetMediaTime() const; |
| 55 Ranges<base::TimeDelta> GetBufferedTimeRanges() const; | 55 Ranges<base::TimeDelta> GetBufferedTimeRanges() const; |
| 56 bool DidLoadingProgress(); | 56 bool DidLoadingProgress(); |
| 57 PipelineStatistics GetStatistics() const; | 57 PipelineStatistics GetStatistics() const; |
| 58 void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); | 58 void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); |
| 59 | 59 |
| 60 // |enabledTrackIds| contains track ids of enabled audio tracks. | |
| 61 void OnEnabledAudioTracksChanged( | |
| 62 const std::vector<MediaTrack::Id>& enabledTrackIds); | |
| 63 | |
| 64 // |trackId| either empty, which means no video track is selected, or contain | |
| 65 // one element - the selected video track id. | |
| 66 void OnSelectedVideoTrackChanged( | |
| 67 const std::vector<MediaTrack::Id>& selectedTrackId); | |
| 68 | |
| 60 private: | 69 private: |
| 61 // Contains state shared between main and media thread. | 70 // Contains state shared between main and media thread. |
| 62 // Main thread can only read. Media thread can both - read and write. | 71 // Main thread can only read. Media thread can both - read and write. |
| 63 // So it is not necessary to lock when reading from the media thread. | 72 // So it is not necessary to lock when reading from the media thread. |
| 64 // This struct should only contain state that is not immediately needed by | 73 // This struct should only contain state that is not immediately needed by |
| 65 // PipelineClient and can be cached on the media thread until queried. | 74 // PipelineClient and can be cached on the media thread until queried. |
| 66 // Alternatively we could cache it on the main thread by posting the | 75 // Alternatively we could cache it on the main thread by posting the |
| 67 // notification to the main thread. But some of the state change notifications | 76 // notification to the main thread. But some of the state change notifications |
| 68 // (OnStatisticsUpdate and OnBufferedTimeRangesChanged) arrive much more | 77 // (OnStatisticsUpdate and OnBufferedTimeRangesChanged) arrive much more |
| 69 // frequently than needed. Posting all those notifications to the main thread | 78 // frequently than needed. Posting all those notifications to the main thread |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 } | 226 } |
| 218 | 227 |
| 219 media_task_runner_->PostTask( | 228 media_task_runner_->PostTask( |
| 220 FROM_HERE, | 229 FROM_HERE, |
| 221 base::Bind(&RendererWrapper::Start, | 230 base::Bind(&RendererWrapper::Start, |
| 222 base::Unretained(renderer_wrapper_.get()), demuxer, | 231 base::Unretained(renderer_wrapper_.get()), demuxer, |
| 223 base::Passed(&renderer), base::Passed(&text_renderer), | 232 base::Passed(&renderer), base::Passed(&text_renderer), |
| 224 weak_factory_.GetWeakPtr())); | 233 weak_factory_.GetWeakPtr())); |
| 225 } | 234 } |
| 226 | 235 |
| 236 void PipelineImpl::OnEnabledAudioTracksChanged( | |
| 237 const std::vector<MediaTrack::Id>& enabledTrackIds) { | |
| 238 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 239 media_task_runner_->PostTask( | |
| 240 FROM_HERE, | |
| 241 base::Bind(&RendererWrapper::OnEnabledAudioTracksChanged, | |
| 242 base::Unretained(renderer_wrapper_.get()), enabledTrackIds)); | |
| 243 } | |
| 244 | |
| 245 void PipelineImpl::OnSelectedVideoTrackChanged( | |
| 246 const std::vector<MediaTrack::Id>& selectedTrackId) { | |
| 247 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 248 media_task_runner_->PostTask( | |
| 249 FROM_HERE, | |
| 250 base::Bind(&RendererWrapper::OnSelectedVideoTrackChanged, | |
| 251 base::Unretained(renderer_wrapper_.get()), selectedTrackId)); | |
| 252 } | |
| 253 | |
| 227 void PipelineImpl::Stop() { | 254 void PipelineImpl::Stop() { |
| 228 DVLOG(2) << __FUNCTION__; | 255 DVLOG(2) << __FUNCTION__; |
| 229 DCHECK(thread_checker_.CalledOnValidThread()); | 256 DCHECK(thread_checker_.CalledOnValidThread()); |
| 230 | 257 |
| 231 if (!IsRunning()) { | 258 if (!IsRunning()) { |
| 232 DVLOG(2) << "Media pipeline isn't running. Ignoring Stop()"; | 259 DVLOG(2) << "Media pipeline isn't running. Ignoring Stop()"; |
| 233 return; | 260 return; |
| 234 } | 261 } |
| 235 | 262 |
| 236 if (media_task_runner_->BelongsToCurrentThread()) { | 263 if (media_task_runner_->BelongsToCurrentThread()) { |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 512 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); | 539 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); |
| 513 | 540 |
| 514 if (state_ != kPlaying) | 541 if (state_ != kPlaying) |
| 515 return; | 542 return; |
| 516 | 543 |
| 517 DCHECK(!renderer_ended_); | 544 DCHECK(!renderer_ended_); |
| 518 renderer_ended_ = true; | 545 renderer_ended_ = true; |
| 519 RunEndedCallbackIfNeeded(); | 546 RunEndedCallbackIfNeeded(); |
| 520 } | 547 } |
| 521 | 548 |
| 549 void PipelineImpl::RendererWrapper::OnEnabledAudioTracksChanged( | |
| 550 const std::vector<MediaTrack::Id>& enabledTrackIds) { | |
| 551 DCHECK(media_task_runner_->BelongsToCurrentThread()); | |
| 552 | |
| 553 // This might happen at the very beginning of the media playback, when the | |
| 554 // first video track gets selected by default before the playback has been | |
| 555 // started, so we don't need to react to this. | |
| 556 if (!demuxer_ || !shared_state_.renderer) { | |
| 557 return; | |
| 558 } | |
| 559 | |
| 560 base::TimeDelta currTime = (state_ == kPlaying) | |
| 561 ? shared_state_.renderer->GetMediaTime() | |
| 562 : start_timestamp_; | |
| 563 demuxer_->OnEnabledAudioTracksChanged(enabledTrackIds, currTime); | |
| 564 } | |
| 565 | |
| 566 void PipelineImpl::RendererWrapper::OnSelectedVideoTrackChanged( | |
| 567 const std::vector<MediaTrack::Id>& selectedTrackId) { | |
| 568 DCHECK(media_task_runner_->BelongsToCurrentThread()); | |
| 569 | |
| 570 // This might happen at the very beginning of the media playback, when the | |
| 571 // first video track gets selected by default before the playback has been | |
|
chcunningham
2016/06/24 23:32:55
What if something other than the first/default tra
| |
| 572 // started, so we don't need to react to this. | |
| 573 if (!demuxer_ || !shared_state_.renderer) { | |
| 574 return; | |
| 575 } | |
| 576 | |
| 577 base::TimeDelta currTime = (state_ == kPlaying) | |
| 578 ? shared_state_.renderer->GetMediaTime() | |
| 579 : start_timestamp_; | |
| 580 demuxer_->OnSelectedVideoTrackChanged(selectedTrackId, currTime); | |
| 581 } | |
| 582 | |
| 522 void PipelineImpl::RendererWrapper::OnStatisticsUpdate( | 583 void PipelineImpl::RendererWrapper::OnStatisticsUpdate( |
| 523 const PipelineStatistics& stats) { | 584 const PipelineStatistics& stats) { |
| 524 DVLOG(3) << __FUNCTION__; | 585 DVLOG(3) << __FUNCTION__; |
| 525 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 586 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 526 | 587 |
| 527 base::AutoLock auto_lock(shared_state_lock_); | 588 base::AutoLock auto_lock(shared_state_lock_); |
| 528 shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded; | 589 shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded; |
| 529 shared_state_.statistics.video_bytes_decoded += stats.video_bytes_decoded; | 590 shared_state_.statistics.video_bytes_decoded += stats.video_bytes_decoded; |
| 530 shared_state_.statistics.video_frames_decoded += stats.video_frames_decoded; | 591 shared_state_.statistics.video_frames_decoded += stats.video_frames_decoded; |
| 531 shared_state_.statistics.video_frames_dropped += stats.video_frames_dropped; | 592 shared_state_.statistics.video_frames_dropped += stats.video_frames_dropped; |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1227 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1288 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1228 | 1289 |
| 1229 base::AutoLock auto_lock(shared_state_lock_); | 1290 base::AutoLock auto_lock(shared_state_lock_); |
| 1230 if (shared_state_.suspend_timestamp != kNoTimestamp()) | 1291 if (shared_state_.suspend_timestamp != kNoTimestamp()) |
| 1231 return shared_state_.suspend_timestamp; | 1292 return shared_state_.suspend_timestamp; |
| 1232 return shared_state_.renderer ? shared_state_.renderer->GetMediaTime() | 1293 return shared_state_.renderer ? shared_state_.renderer->GetMediaTime() |
| 1233 : base::TimeDelta(); | 1294 : base::TimeDelta(); |
| 1234 } | 1295 } |
| 1235 | 1296 |
| 1236 } // namespace media | 1297 } // namespace media |
| OLD | NEW |