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" |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
| 18 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "media/base/audio_decoder_config.h" | |
| 20 #include "media/base/bind_to_current_loop.h" | 21 #include "media/base/bind_to_current_loop.h" |
| 21 #include "media/base/demuxer.h" | 22 #include "media/base/demuxer.h" |
| 22 #include "media/base/media_log.h" | 23 #include "media/base/media_log.h" |
| 23 #include "media/base/media_switches.h" | 24 #include "media/base/media_switches.h" |
| 24 #include "media/base/renderer.h" | 25 #include "media/base/renderer.h" |
| 25 #include "media/base/renderer_client.h" | 26 #include "media/base/renderer_client.h" |
| 26 #include "media/base/serial_runner.h" | 27 #include "media/base/serial_runner.h" |
| 27 #include "media/base/text_renderer.h" | 28 #include "media/base/text_renderer.h" |
| 28 #include "media/base/text_track_config.h" | 29 #include "media/base/text_track_config.h" |
| 29 #include "media/base/timestamp_constants.h" | 30 #include "media/base/timestamp_constants.h" |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 59 | 60 |
| 60 // |enabledTrackIds| contains track ids of enabled audio tracks. | 61 // |enabledTrackIds| contains track ids of enabled audio tracks. |
| 61 void OnEnabledAudioTracksChanged( | 62 void OnEnabledAudioTracksChanged( |
| 62 const std::vector<MediaTrack::Id>& enabledTrackIds); | 63 const std::vector<MediaTrack::Id>& enabledTrackIds); |
| 63 | 64 |
| 64 // |trackId| either empty, which means no video track is selected, or contain | 65 // |trackId| either empty, which means no video track is selected, or contain |
| 65 // one element - the selected video track id. | 66 // one element - the selected video track id. |
| 66 void OnSelectedVideoTrackChanged( | 67 void OnSelectedVideoTrackChanged( |
| 67 const std::vector<MediaTrack::Id>& selectedTrackId); | 68 const std::vector<MediaTrack::Id>& selectedTrackId); |
| 68 | 69 |
| 70 // Get current video/audio configure. | |
| 71 VideoDecoderConfig GetVideoDecoderConfig() const; | |
| 72 AudioDecoderConfig GetAudioDecoderConfig() const; | |
| 73 | |
| 69 private: | 74 private: |
| 70 // Contains state shared between main and media thread. | 75 // Contains state shared between main and media thread. |
| 71 // Main thread can only read. Media thread can both - read and write. | 76 // Main thread can only read. Media thread can both - read and write. |
| 72 // So it is not necessary to lock when reading from the media thread. | 77 // So it is not necessary to lock when reading from the media thread. |
| 73 // This struct should only contain state that is not immediately needed by | 78 // This struct should only contain state that is not immediately needed by |
| 74 // PipelineClient and can be cached on the media thread until queried. | 79 // PipelineClient and can be cached on the media thread until queried. |
| 75 // Alternatively we could cache it on the main thread by posting the | 80 // Alternatively we could cache it on the main thread by posting the |
| 76 // notification to the main thread. But some of the state change notifications | 81 // notification to the main thread. But some of the state change notifications |
| 77 // (OnStatisticsUpdate and OnBufferedTimeRangesChanged) arrive much more | 82 // (OnStatisticsUpdate and OnBufferedTimeRangesChanged) arrive much more |
| 78 // frequently than needed. Posting all those notifications to the main thread | 83 // frequently than needed. Posting all those notifications to the main thread |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 // reset the pipeline state, and restore this to PIPELINE_OK. | 168 // reset the pipeline state, and restore this to PIPELINE_OK. |
| 164 PipelineStatus status_; | 169 PipelineStatus status_; |
| 165 | 170 |
| 166 // Whether we've received the audio/video/text ended events. | 171 // Whether we've received the audio/video/text ended events. |
| 167 bool renderer_ended_; | 172 bool renderer_ended_; |
| 168 bool text_renderer_ended_; | 173 bool text_renderer_ended_; |
| 169 | 174 |
| 170 // Series of tasks to Start(), Seek(), and Resume(). | 175 // Series of tasks to Start(), Seek(), and Resume(). |
| 171 std::unique_ptr<SerialRunner> pending_callbacks_; | 176 std::unique_ptr<SerialRunner> pending_callbacks_; |
| 172 | 177 |
| 178 // Current audio/video decoder config. | |
| 179 AudioDecoderConfig audio_decoder_config_; | |
| 180 VideoDecoderConfig video_decoder_config_; | |
| 181 | |
| 173 base::WeakPtr<RendererWrapper> weak_this_; | 182 base::WeakPtr<RendererWrapper> weak_this_; |
| 174 base::WeakPtrFactory<RendererWrapper> weak_factory_; | 183 base::WeakPtrFactory<RendererWrapper> weak_factory_; |
| 175 DISALLOW_COPY_AND_ASSIGN(RendererWrapper); | 184 DISALLOW_COPY_AND_ASSIGN(RendererWrapper); |
| 176 }; | 185 }; |
| 177 | 186 |
| 178 PipelineImpl::RendererWrapper::RendererWrapper( | 187 PipelineImpl::RendererWrapper::RendererWrapper( |
| 179 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, | 188 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, |
| 180 scoped_refptr<MediaLog> media_log) | 189 scoped_refptr<MediaLog> media_log) |
| 181 : media_task_runner_(std::move(media_task_runner)), | 190 : media_task_runner_(std::move(media_task_runner)), |
| 182 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 191 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); | 554 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); |
| 546 | 555 |
| 547 if (state_ != kPlaying) | 556 if (state_ != kPlaying) |
| 548 return; | 557 return; |
| 549 | 558 |
| 550 DCHECK(!renderer_ended_); | 559 DCHECK(!renderer_ended_); |
| 551 renderer_ended_ = true; | 560 renderer_ended_ = true; |
| 552 CheckPlaybackEnded(); | 561 CheckPlaybackEnded(); |
| 553 } | 562 } |
| 554 | 563 |
| 564 VideoDecoderConfig PipelineImpl::RendererWrapper::GetVideoDecoderConfig() | |
| 565 const { | |
| 566 return video_decoder_config_; | |
| 567 } | |
| 568 | |
| 569 AudioDecoderConfig PipelineImpl::RendererWrapper::GetAudioDecoderConfig() | |
|
miu
2016/09/14 20:59:27
base::Optional<AudioDecoderConfig> PipelineImpl::R
| |
| 570 const { | |
| 571 return audio_decoder_config_; | |
| 572 } | |
| 573 | |
| 555 void PipelineImpl::OnEnabledAudioTracksChanged( | 574 void PipelineImpl::OnEnabledAudioTracksChanged( |
| 556 const std::vector<MediaTrack::Id>& enabledTrackIds) { | 575 const std::vector<MediaTrack::Id>& enabledTrackIds) { |
| 557 DCHECK(thread_checker_.CalledOnValidThread()); | 576 DCHECK(thread_checker_.CalledOnValidThread()); |
| 558 media_task_runner_->PostTask( | 577 media_task_runner_->PostTask( |
| 559 FROM_HERE, | 578 FROM_HERE, |
| 560 base::Bind(&RendererWrapper::OnEnabledAudioTracksChanged, | 579 base::Bind(&RendererWrapper::OnEnabledAudioTracksChanged, |
| 561 base::Unretained(renderer_wrapper_.get()), enabledTrackIds)); | 580 base::Unretained(renderer_wrapper_.get()), enabledTrackIds)); |
| 562 } | 581 } |
| 563 | 582 |
| 564 void PipelineImpl::OnSelectedVideoTrackChanged( | 583 void PipelineImpl::OnSelectedVideoTrackChanged( |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 817 void PipelineImpl::RendererWrapper::InitializeRenderer( | 836 void PipelineImpl::RendererWrapper::InitializeRenderer( |
| 818 const PipelineStatusCB& done_cb) { | 837 const PipelineStatusCB& done_cb) { |
| 819 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 838 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 820 | 839 |
| 821 if (!demuxer_->GetStream(DemuxerStream::AUDIO) && | 840 if (!demuxer_->GetStream(DemuxerStream::AUDIO) && |
| 822 !demuxer_->GetStream(DemuxerStream::VIDEO)) { | 841 !demuxer_->GetStream(DemuxerStream::VIDEO)) { |
| 823 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); | 842 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 824 return; | 843 return; |
| 825 } | 844 } |
| 826 | 845 |
| 846 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 847 if (stream) | |
| 848 audio_decoder_config_ = stream->audio_decoder_config(); | |
| 849 stream = demuxer_->GetStream(DemuxerStream::VIDEO); | |
| 850 if (stream) | |
| 851 video_decoder_config_ = stream->video_decoder_config(); | |
| 852 | |
| 827 if (cdm_context_) | 853 if (cdm_context_) |
| 828 shared_state_.renderer->SetCdm(cdm_context_, | 854 shared_state_.renderer->SetCdm(cdm_context_, |
| 829 base::Bind(&IgnoreCdmAttached)); | 855 base::Bind(&IgnoreCdmAttached)); |
| 830 | 856 |
| 831 shared_state_.renderer->Initialize(demuxer_, this, done_cb); | 857 shared_state_.renderer->Initialize(demuxer_, this, done_cb); |
| 832 } | 858 } |
| 833 | 859 |
| 834 void PipelineImpl::RendererWrapper::DestroyRenderer() { | 860 void PipelineImpl::RendererWrapper::DestroyRenderer() { |
| 835 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 861 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 836 | 862 |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1252 | 1278 |
| 1253 void PipelineImpl::OnSuspendDone() { | 1279 void PipelineImpl::OnSuspendDone() { |
| 1254 DVLOG(3) << __func__; | 1280 DVLOG(3) << __func__; |
| 1255 DCHECK(thread_checker_.CalledOnValidThread()); | 1281 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1256 DCHECK(IsRunning()); | 1282 DCHECK(IsRunning()); |
| 1257 | 1283 |
| 1258 DCHECK(!suspend_cb_.is_null()); | 1284 DCHECK(!suspend_cb_.is_null()); |
| 1259 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); | 1285 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); |
| 1260 } | 1286 } |
| 1261 | 1287 |
| 1288 VideoDecoderConfig PipelineImpl::GetVideoDecoderConfig() const { | |
| 1289 if (!renderer_wrapper_) | |
| 1290 return VideoDecoderConfig(); | |
| 1291 return renderer_wrapper_->GetVideoDecoderConfig(); | |
| 1292 } | |
| 1293 | |
| 1294 AudioDecoderConfig PipelineImpl::GetAudioDecoderConfig() const { | |
| 1295 if (!renderer_wrapper_) | |
| 1296 return AudioDecoderConfig(); | |
| 1297 return renderer_wrapper_->GetAudioDecoderConfig(); | |
| 1298 } | |
| 1299 | |
| 1262 } // namespace media | 1300 } // namespace media |
| OLD | NEW |