| 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 10 matching lines...) Expand all Loading... |
| 21 #include "media/base/demuxer.h" | 21 #include "media/base/demuxer.h" |
| 22 #include "media/base/media_log.h" | 22 #include "media/base/media_log.h" |
| 23 #include "media/base/media_switches.h" | 23 #include "media/base/media_switches.h" |
| 24 #include "media/base/renderer.h" | 24 #include "media/base/renderer.h" |
| 25 #include "media/base/renderer_client.h" | 25 #include "media/base/renderer_client.h" |
| 26 #include "media/base/serial_runner.h" | 26 #include "media/base/serial_runner.h" |
| 27 #include "media/base/text_renderer.h" | 27 #include "media/base/text_renderer.h" |
| 28 #include "media/base/text_track_config.h" | 28 #include "media/base/text_track_config.h" |
| 29 #include "media/base/timestamp_constants.h" | 29 #include "media/base/timestamp_constants.h" |
| 30 #include "media/base/video_decoder_config.h" | 30 #include "media/base/video_decoder_config.h" |
| 31 #include "media/media_features.h" |
| 31 | 32 |
| 32 static const double kDefaultPlaybackRate = 0.0; | 33 static const double kDefaultPlaybackRate = 0.0; |
| 33 static const float kDefaultVolume = 1.0f; | 34 static const float kDefaultVolume = 1.0f; |
| 34 | 35 |
| 35 namespace media { | 36 namespace media { |
| 36 | 37 |
| 37 class PipelineImpl::RendererWrapper : public DemuxerHost, | 38 class PipelineImpl::RendererWrapper : public DemuxerHost, |
| 38 public RendererClient { | 39 public RendererClient { |
| 39 public: | 40 public: |
| 40 RendererWrapper(base::WeakPtr<PipelineImpl> weak_pipeline, | 41 RendererWrapper(base::WeakPtr<PipelineImpl> weak_pipeline, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 64 void RemoveTextStream(DemuxerStream* text_stream) final; | 65 void RemoveTextStream(DemuxerStream* text_stream) final; |
| 65 | 66 |
| 66 // RendererClient implementation. | 67 // RendererClient implementation. |
| 67 void OnError(PipelineStatus error) final; | 68 void OnError(PipelineStatus error) final; |
| 68 void OnEnded() final; | 69 void OnEnded() final; |
| 69 void OnStatisticsUpdate(const PipelineStatistics& stats) final; | 70 void OnStatisticsUpdate(const PipelineStatistics& stats) final; |
| 70 void OnBufferingStateChange(BufferingState state) final; | 71 void OnBufferingStateChange(BufferingState state) final; |
| 71 void OnWaitingForDecryptionKey() final; | 72 void OnWaitingForDecryptionKey() final; |
| 72 void OnVideoNaturalSizeChange(const gfx::Size& size) final; | 73 void OnVideoNaturalSizeChange(const gfx::Size& size) final; |
| 73 void OnVideoOpacityChange(bool opaque) final; | 74 void OnVideoOpacityChange(bool opaque) final; |
| 75 void OnDurationChange(base::TimeDelta duration) final; |
| 74 | 76 |
| 75 void DoSeek(base::TimeDelta seek_timestamp, const PipelineStatusCB& done_cb); | 77 void DoSeek(base::TimeDelta seek_timestamp, const PipelineStatusCB& done_cb); |
| 76 void DoStop(const base::Closure& done_cb); | 78 void DoStop(const base::Closure& done_cb); |
| 77 void OnPipelineError(PipelineStatus error); | 79 void OnPipelineError(PipelineStatus error); |
| 78 void OnTextRendererEnded(); | 80 void OnTextRendererEnded(); |
| 79 void RunEndedCallbackIfNeeded(); | 81 void RunEndedCallbackIfNeeded(); |
| 80 void SetState(State next_state); | 82 void SetState(State next_state); |
| 81 State GetNextState() const; | 83 State GetNextState() const; |
| 82 void StateTransitionTask(PipelineStatus status); | 84 void StateTransitionTask(PipelineStatus status); |
| 83 void OnCdmAttached(const CdmAttachedCB& cdm_attached_cb, | 85 void OnCdmAttached(const CdmAttachedCB& cdm_attached_cb, |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 } | 538 } |
| 537 | 539 |
| 538 void PipelineImpl::RendererWrapper::OnVideoOpacityChange(bool opaque) { | 540 void PipelineImpl::RendererWrapper::OnVideoOpacityChange(bool opaque) { |
| 539 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 541 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 540 | 542 |
| 541 main_task_runner_->PostTask( | 543 main_task_runner_->PostTask( |
| 542 FROM_HERE, | 544 FROM_HERE, |
| 543 base::Bind(&PipelineImpl::OnVideoOpacityChange, weak_pipeline_, opaque)); | 545 base::Bind(&PipelineImpl::OnVideoOpacityChange, weak_pipeline_, opaque)); |
| 544 } | 546 } |
| 545 | 547 |
| 548 void PipelineImpl::RendererWrapper::OnDurationChange(base::TimeDelta duration) { |
| 549 #if BUILDFLAG(FORCE_MOJO_MEDIA_PLAYER_RENDERER) |
| 550 SetDuration(duration); |
| 551 #else |
| 552 // Duration changes should be surfaced by the DemuxerStream, via the |
| 553 // DemuxerHost interface. |
| 554 NOTREACHED(); |
| 555 #endif |
| 556 } |
| 557 |
| 546 void PipelineImpl::RendererWrapper::SetDuration(base::TimeDelta duration) { | 558 void PipelineImpl::RendererWrapper::SetDuration(base::TimeDelta duration) { |
| 547 // TODO(alokp): Add thread DCHECK after ensuring that all Demuxer | 559 // TODO(alokp): Add thread DCHECK after ensuring that all Demuxer |
| 548 // implementations call DemuxerHost on the media thread. | 560 // implementations call DemuxerHost on the media thread. |
| 549 media_log_->AddEvent(media_log_->CreateTimeEvent(MediaLogEvent::DURATION_SET, | 561 media_log_->AddEvent(media_log_->CreateTimeEvent(MediaLogEvent::DURATION_SET, |
| 550 "duration", duration)); | 562 "duration", duration)); |
| 551 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); | 563 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); |
| 552 | 564 |
| 553 main_task_runner_->PostTask( | 565 main_task_runner_->PostTask( |
| 554 FROM_HERE, | 566 FROM_HERE, |
| 555 base::Bind(&PipelineImpl::OnDurationChange, weak_pipeline_, duration)); | 567 base::Bind(&PipelineImpl::OnDurationChange, weak_pipeline_, duration)); |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 const PipelineStatusCB& done_cb) { | 989 const PipelineStatusCB& done_cb) { |
| 978 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 990 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 979 | 991 |
| 980 demuxer_->Initialize(this, done_cb, !!text_renderer_); | 992 demuxer_->Initialize(this, done_cb, !!text_renderer_); |
| 981 } | 993 } |
| 982 | 994 |
| 983 void PipelineImpl::RendererWrapper::InitializeRenderer( | 995 void PipelineImpl::RendererWrapper::InitializeRenderer( |
| 984 const PipelineStatusCB& done_cb) { | 996 const PipelineStatusCB& done_cb) { |
| 985 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 997 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 986 | 998 |
| 999 #if BUILDFLAG(FORCE_MOJO_MEDIA_PLAYER_RENDERER) |
| 1000 if (!demuxer_->GetStream(DemuxerStream::URL)) { |
| 1001 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 1002 return; |
| 1003 } |
| 1004 #else |
| 987 if (!demuxer_->GetStream(DemuxerStream::AUDIO) && | 1005 if (!demuxer_->GetStream(DemuxerStream::AUDIO) && |
| 988 !demuxer_->GetStream(DemuxerStream::VIDEO)) { | 1006 !demuxer_->GetStream(DemuxerStream::VIDEO)) { |
| 989 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); | 1007 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 990 return; | 1008 return; |
| 991 } | 1009 } |
| 1010 #endif // BUILDFLAG(FORCE_MOJO_MEDIA_PLAYER_RENDERER) |
| 992 | 1011 |
| 993 if (cdm_context_) | 1012 if (cdm_context_) |
| 994 renderer_->SetCdm(cdm_context_, base::Bind(&IgnoreCdmAttached)); | 1013 renderer_->SetCdm(cdm_context_, base::Bind(&IgnoreCdmAttached)); |
| 995 | 1014 |
| 996 renderer_->Initialize(demuxer_, this, done_cb); | 1015 renderer_->Initialize(demuxer_, this, done_cb); |
| 997 } | 1016 } |
| 998 | 1017 |
| 999 void PipelineImpl::RendererWrapper::ReportMetadata() { | 1018 void PipelineImpl::RendererWrapper::ReportMetadata() { |
| 1000 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 1019 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 1001 | 1020 |
| 1002 PipelineMetadata metadata; | 1021 PipelineMetadata metadata; |
| 1022 #if BUILDFLAG(FORCE_MOJO_MEDIA_PLAYER_RENDERER) |
| 1023 if (demuxer_->GetStream(DemuxerStream::URL)) { |
| 1024 // We don't know if the MediaPlayerRender has Audio/Video until we start |
| 1025 // playing. Conservatively assume that they do. |
| 1026 metadata.has_video = true; |
| 1027 metadata.has_audio = true; |
| 1028 } |
| 1029 #else |
| 1003 metadata.timeline_offset = demuxer_->GetTimelineOffset(); | 1030 metadata.timeline_offset = demuxer_->GetTimelineOffset(); |
| 1004 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 1031 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 1005 if (stream) { | 1032 if (stream) { |
| 1006 metadata.has_video = true; | 1033 metadata.has_video = true; |
| 1007 metadata.natural_size = stream->video_decoder_config().natural_size(); | 1034 metadata.natural_size = stream->video_decoder_config().natural_size(); |
| 1008 metadata.video_rotation = stream->video_rotation(); | 1035 metadata.video_rotation = stream->video_rotation(); |
| 1009 } | 1036 } |
| 1010 if (demuxer_->GetStream(DemuxerStream::AUDIO)) { | 1037 if (demuxer_->GetStream(DemuxerStream::AUDIO)) { |
| 1011 metadata.has_audio = true; | 1038 metadata.has_audio = true; |
| 1012 } | 1039 } |
| 1040 #endif // BUILDFLAG(FORCE_MOJO_MEDIA_PLAYER_RENDERER) |
| 1013 | 1041 |
| 1014 main_task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::OnMetadata, | 1042 main_task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::OnMetadata, |
| 1015 weak_pipeline_, metadata)); | 1043 weak_pipeline_, metadata)); |
| 1016 } | 1044 } |
| 1017 | 1045 |
| 1018 void PipelineImpl::OnError(PipelineStatus error) { | 1046 void PipelineImpl::OnError(PipelineStatus error) { |
| 1019 DVLOG(2) << __FUNCTION__; | 1047 DVLOG(2) << __FUNCTION__; |
| 1020 DCHECK(thread_checker_.CalledOnValidThread()); | 1048 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1021 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; | 1049 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; |
| 1022 | 1050 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 // even for accessing media time http://crbug.com/370634. | 1228 // even for accessing media time http://crbug.com/370634. |
| 1201 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1229 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1202 | 1230 |
| 1203 base::AutoLock auto_lock(media_time_lock_); | 1231 base::AutoLock auto_lock(media_time_lock_); |
| 1204 if (suspend_timestamp_ != kNoTimestamp()) | 1232 if (suspend_timestamp_ != kNoTimestamp()) |
| 1205 return suspend_timestamp_; | 1233 return suspend_timestamp_; |
| 1206 return renderer_ ? renderer_->GetMediaTime() : base::TimeDelta(); | 1234 return renderer_ ? renderer_->GetMediaTime() : base::TimeDelta(); |
| 1207 } | 1235 } |
| 1208 | 1236 |
| 1209 } // namespace media | 1237 } // namespace media |
| OLD | NEW |