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(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, | 41 RendererWrapper(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 void RemoveTextStream(DemuxerStream* text_stream) final; | 107 void RemoveTextStream(DemuxerStream* text_stream) final; |
107 | 108 |
108 // RendererClient implementation. | 109 // RendererClient implementation. |
109 void OnError(PipelineStatus error) final; | 110 void OnError(PipelineStatus error) final; |
110 void OnEnded() final; | 111 void OnEnded() final; |
111 void OnStatisticsUpdate(const PipelineStatistics& stats) final; | 112 void OnStatisticsUpdate(const PipelineStatistics& stats) final; |
112 void OnBufferingStateChange(BufferingState state) final; | 113 void OnBufferingStateChange(BufferingState state) final; |
113 void OnWaitingForDecryptionKey() final; | 114 void OnWaitingForDecryptionKey() final; |
114 void OnVideoNaturalSizeChange(const gfx::Size& size) final; | 115 void OnVideoNaturalSizeChange(const gfx::Size& size) final; |
115 void OnVideoOpacityChange(bool opaque) final; | 116 void OnVideoOpacityChange(bool opaque) final; |
| 117 void OnDurationChange(base::TimeDelta duration) final; |
116 | 118 |
117 // TextRenderer tasks and notifications. | 119 // TextRenderer tasks and notifications. |
118 void OnTextRendererEnded(); | 120 void OnTextRendererEnded(); |
119 void AddTextStreamTask(DemuxerStream* text_stream, | 121 void AddTextStreamTask(DemuxerStream* text_stream, |
120 const TextTrackConfig& config); | 122 const TextTrackConfig& config); |
121 void RemoveTextStreamTask(DemuxerStream* text_stream); | 123 void RemoveTextStreamTask(DemuxerStream* text_stream); |
122 | 124 |
123 // Common handlers for notifications from renderers and demuxer. | 125 // Common handlers for notifications from renderers and demuxer. |
124 void OnPipelineError(PipelineStatus error); | 126 void OnPipelineError(PipelineStatus error); |
125 void OnCdmAttached(const CdmAttachedCB& cdm_attached_cb, | 127 void OnCdmAttached(const CdmAttachedCB& cdm_attached_cb, |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 } | 599 } |
598 | 600 |
599 void PipelineImpl::RendererWrapper::OnVideoOpacityChange(bool opaque) { | 601 void PipelineImpl::RendererWrapper::OnVideoOpacityChange(bool opaque) { |
600 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 602 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
601 | 603 |
602 main_task_runner_->PostTask( | 604 main_task_runner_->PostTask( |
603 FROM_HERE, | 605 FROM_HERE, |
604 base::Bind(&PipelineImpl::OnVideoOpacityChange, weak_pipeline_, opaque)); | 606 base::Bind(&PipelineImpl::OnVideoOpacityChange, weak_pipeline_, opaque)); |
605 } | 607 } |
606 | 608 |
| 609 void PipelineImpl::RendererWrapper::OnDurationChange(base::TimeDelta duration) { |
| 610 #if BUILDFLAG(FORCE_MOJO_MEDIA_PLAYER_RENDERER) |
| 611 SetDuration(duration); |
| 612 #else |
| 613 // Duration changes should be surfaced by the DemuxerStream, via the |
| 614 // DemuxerHost interface. |
| 615 NOTREACHED(); |
| 616 #endif |
| 617 } |
| 618 |
607 void PipelineImpl::RendererWrapper::OnTextRendererEnded() { | 619 void PipelineImpl::RendererWrapper::OnTextRendererEnded() { |
608 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 620 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
609 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::TEXT_ENDED)); | 621 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::TEXT_ENDED)); |
610 | 622 |
611 if (state_ != kPlaying) | 623 if (state_ != kPlaying) |
612 return; | 624 return; |
613 | 625 |
614 DCHECK(!text_renderer_ended_); | 626 DCHECK(!text_renderer_ended_); |
615 text_renderer_ended_ = true; | 627 text_renderer_ended_ = true; |
616 CheckPlaybackEnded(); | 628 CheckPlaybackEnded(); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 const PipelineStatusCB& done_cb) { | 884 const PipelineStatusCB& done_cb) { |
873 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 885 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
874 | 886 |
875 demuxer_->Initialize(this, done_cb, !!text_renderer_); | 887 demuxer_->Initialize(this, done_cb, !!text_renderer_); |
876 } | 888 } |
877 | 889 |
878 void PipelineImpl::RendererWrapper::InitializeRenderer( | 890 void PipelineImpl::RendererWrapper::InitializeRenderer( |
879 const PipelineStatusCB& done_cb) { | 891 const PipelineStatusCB& done_cb) { |
880 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 892 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
881 | 893 |
882 if (!demuxer_->GetStream(DemuxerStream::AUDIO) && | 894 switch (demuxer_->GetType()) { |
883 !demuxer_->GetStream(DemuxerStream::VIDEO)) { | 895 case DemuxerStreamProvider::Type::STREAM: |
884 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); | 896 if (!demuxer_->GetStream(DemuxerStream::AUDIO) && |
885 return; | 897 !demuxer_->GetStream(DemuxerStream::VIDEO)) { |
| 898 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 899 return; |
| 900 } |
| 901 break; |
| 902 |
| 903 case DemuxerStreamProvider::Type::URL: |
| 904 // N.B: Empty GURL are not valid. |
| 905 if (!demuxer_->GetUrl().is_valid()) { |
| 906 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 907 return; |
| 908 } |
| 909 break; |
886 } | 910 } |
887 | 911 |
888 if (cdm_context_) | 912 if (cdm_context_) |
889 shared_state_.renderer->SetCdm(cdm_context_, | 913 shared_state_.renderer->SetCdm(cdm_context_, |
890 base::Bind(&IgnoreCdmAttached)); | 914 base::Bind(&IgnoreCdmAttached)); |
891 | 915 |
892 shared_state_.renderer->Initialize(demuxer_, this, done_cb); | 916 shared_state_.renderer->Initialize(demuxer_, this, done_cb); |
893 } | 917 } |
894 | 918 |
895 void PipelineImpl::RendererWrapper::DestroyRenderer() { | 919 void PipelineImpl::RendererWrapper::DestroyRenderer() { |
896 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 920 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
897 | 921 |
898 // Destroy the renderer outside the lock scope to avoid holding the lock | 922 // Destroy the renderer outside the lock scope to avoid holding the lock |
899 // while renderer is being destroyed (in case Renderer destructor is costly). | 923 // while renderer is being destroyed (in case Renderer destructor is costly). |
900 std::unique_ptr<Renderer> renderer; | 924 std::unique_ptr<Renderer> renderer; |
901 { | 925 { |
902 base::AutoLock auto_lock(shared_state_lock_); | 926 base::AutoLock auto_lock(shared_state_lock_); |
903 renderer.swap(shared_state_.renderer); | 927 renderer.swap(shared_state_.renderer); |
904 } | 928 } |
905 } | 929 } |
906 | 930 |
907 void PipelineImpl::RendererWrapper::ReportMetadata() { | 931 void PipelineImpl::RendererWrapper::ReportMetadata() { |
908 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 932 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
909 | 933 |
910 PipelineMetadata metadata; | 934 PipelineMetadata metadata; |
911 metadata.timeline_offset = demuxer_->GetTimelineOffset(); | 935 DemuxerStream* stream; |
912 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 936 |
913 if (stream) { | 937 switch (demuxer_->GetType()) { |
914 metadata.has_video = true; | 938 case DemuxerStreamProvider::Type::STREAM: |
915 metadata.natural_size = stream->video_decoder_config().natural_size(); | 939 metadata.timeline_offset = demuxer_->GetTimelineOffset(); |
916 metadata.video_rotation = stream->video_rotation(); | 940 stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
917 } | 941 if (stream) { |
918 if (demuxer_->GetStream(DemuxerStream::AUDIO)) { | 942 metadata.has_video = true; |
919 metadata.has_audio = true; | 943 metadata.natural_size = stream->video_decoder_config().natural_size(); |
| 944 metadata.video_rotation = stream->video_rotation(); |
| 945 } |
| 946 if (demuxer_->GetStream(DemuxerStream::AUDIO)) { |
| 947 metadata.has_audio = true; |
| 948 } |
| 949 break; |
| 950 |
| 951 case DemuxerStreamProvider::Type::URL: |
| 952 // We don't know if the MediaPlayerRender has Audio/Video until we start |
| 953 // playing. Conservatively assume that they do. |
| 954 metadata.has_video = true; |
| 955 metadata.has_audio = true; |
| 956 break; |
920 } | 957 } |
921 | 958 |
922 main_task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::OnMetadata, | 959 main_task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::OnMetadata, |
923 weak_pipeline_, metadata)); | 960 weak_pipeline_, metadata)); |
924 } | 961 } |
925 | 962 |
926 PipelineImpl::PipelineImpl( | 963 PipelineImpl::PipelineImpl( |
927 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 964 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
928 MediaLog* media_log) | 965 MediaLog* media_log) |
929 : media_task_runner_(media_task_runner), | 966 : media_task_runner_(media_task_runner), |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1295 void PipelineImpl::OnSuspendDone(base::TimeDelta suspend_time) { | 1332 void PipelineImpl::OnSuspendDone(base::TimeDelta suspend_time) { |
1296 DVLOG(3) << __FUNCTION__ << "(" << suspend_time.InMicroseconds() << ")"; | 1333 DVLOG(3) << __FUNCTION__ << "(" << suspend_time.InMicroseconds() << ")"; |
1297 DCHECK(thread_checker_.CalledOnValidThread()); | 1334 DCHECK(thread_checker_.CalledOnValidThread()); |
1298 DCHECK(IsRunning()); | 1335 DCHECK(IsRunning()); |
1299 | 1336 |
1300 DCHECK(!suspend_cb_.is_null()); | 1337 DCHECK(!suspend_cb_.is_null()); |
1301 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); | 1338 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); |
1302 } | 1339 } |
1303 | 1340 |
1304 } // namespace media | 1341 } // namespace media |
OLD | NEW |