| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/mojo/clients/mojo_renderer.h" | 5 #include "media/mojo/clients/mojo_renderer.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 13 #include "media/base/demuxer_stream_provider.h" | 13 #include "media/base/demuxer_stream_provider.h" |
| 14 #include "media/base/pipeline_status.h" | 14 #include "media/base/pipeline_status.h" |
| 15 #include "media/base/renderer_client.h" | 15 #include "media/base/renderer_client.h" |
| 16 #include "media/base/video_renderer_sink.h" | 16 #include "media/base/video_renderer_sink.h" |
| 17 #include "media/media_features.h" |
| 17 #include "media/mojo/clients/mojo_demuxer_stream_impl.h" | 18 #include "media/mojo/clients/mojo_demuxer_stream_impl.h" |
| 18 #include "media/renderers/video_overlay_factory.h" | 19 #include "media/renderers/video_overlay_factory.h" |
| 19 | 20 |
| 20 namespace media { | 21 namespace media { |
| 21 | 22 |
| 22 MojoRenderer::MojoRenderer( | 23 MojoRenderer::MojoRenderer( |
| 23 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 24 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 24 std::unique_ptr<VideoOverlayFactory> video_overlay_factory, | 25 std::unique_ptr<VideoOverlayFactory> video_overlay_factory, |
| 25 VideoRendererSink* video_renderer_sink, | 26 VideoRendererSink* video_renderer_sink, |
| 26 mojom::RendererPtr remote_renderer) | 27 mojom::RendererPtr remote_renderer) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 48 | 49 |
| 49 if (encountered_error_) { | 50 if (encountered_error_) { |
| 50 task_runner_->PostTask( | 51 task_runner_->PostTask( |
| 51 FROM_HERE, base::Bind(init_cb, PIPELINE_ERROR_INITIALIZATION_FAILED)); | 52 FROM_HERE, base::Bind(init_cb, PIPELINE_ERROR_INITIALIZATION_FAILED)); |
| 52 return; | 53 return; |
| 53 } | 54 } |
| 54 | 55 |
| 55 demuxer_stream_provider_ = demuxer_stream_provider; | 56 demuxer_stream_provider_ = demuxer_stream_provider; |
| 56 init_cb_ = init_cb; | 57 init_cb_ = init_cb; |
| 57 | 58 |
| 59 switch (demuxer_stream_provider_->GetType()) { |
| 60 case DemuxerStreamProvider::Type::STREAM: |
| 61 InitializeRendererFromStreams(client); |
| 62 break; |
| 63 case DemuxerStreamProvider::Type::URL: |
| 64 InitializeRendererFromUrl(client); |
| 65 break; |
| 66 } |
| 67 } |
| 68 |
| 69 void MojoRenderer::InitializeRendererFromStreams( |
| 70 media::RendererClient* client) { |
| 71 DVLOG(1) << __FUNCTION__; |
| 72 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 73 |
| 58 // Create audio and video mojom::DemuxerStream and bind its lifetime to | 74 // Create audio and video mojom::DemuxerStream and bind its lifetime to |
| 59 // the pipe. | 75 // the pipe. |
| 60 DemuxerStream* const audio = | 76 DemuxerStream* const audio = |
| 61 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); | 77 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); |
| 62 DemuxerStream* const video = | 78 DemuxerStream* const video = |
| 63 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); | 79 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); |
| 64 | 80 |
| 65 mojom::DemuxerStreamPtr audio_stream; | 81 mojom::DemuxerStreamPtr audio_stream; |
| 66 if (audio) { | 82 if (audio) { |
| 67 audio_stream_.reset( | 83 audio_stream_.reset( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 86 base::Unretained(this), DemuxerStream::VIDEO)); | 102 base::Unretained(this), DemuxerStream::VIDEO)); |
| 87 } | 103 } |
| 88 | 104 |
| 89 BindRemoteRendererIfNeeded(); | 105 BindRemoteRendererIfNeeded(); |
| 90 | 106 |
| 91 // Using base::Unretained(this) is safe because |this| owns | 107 // Using base::Unretained(this) is safe because |this| owns |
| 92 // |remote_renderer_|, and the callback won't be dispatched if | 108 // |remote_renderer_|, and the callback won't be dispatched if |
| 93 // |remote_renderer_| is destroyed. | 109 // |remote_renderer_| is destroyed. |
| 94 remote_renderer_->Initialize( | 110 remote_renderer_->Initialize( |
| 95 binding_.CreateInterfacePtrAndBind(), std::move(audio_stream), | 111 binding_.CreateInterfacePtrAndBind(), std::move(audio_stream), |
| 96 std::move(video_stream), | 112 std::move(video_stream), mojo::String(), -1, |
| 97 base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); | 113 base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); |
| 98 } | 114 } |
| 99 | 115 |
| 116 void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) { |
| 117 DVLOG(2) << __FUNCTION__; |
| 118 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 119 |
| 120 BindRemoteRendererIfNeeded(); |
| 121 |
| 122 // TODO(tguilbert): Register and Send the proper surface ID. See |
| 123 // crbug.com/627658 |
| 124 const int kFakeSurfaceId = 123; |
| 125 |
| 126 // Using base::Unretained(this) is safe because |this| owns |
| 127 // |remote_renderer_|, and the callback won't be dispatched if |
| 128 // |remote_renderer_| is destroyed. |
| 129 remote_renderer_->Initialize( |
| 130 binding_.CreateInterfacePtrAndBind(), mojom::DemuxerStreamPtr(), |
| 131 mojom::DemuxerStreamPtr(), |
| 132 mojo::String::From(demuxer_stream_provider_->GetUrl().spec()), |
| 133 kFakeSurfaceId, |
| 134 base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); |
| 135 } |
| 136 |
| 100 void MojoRenderer::SetCdm(CdmContext* cdm_context, | 137 void MojoRenderer::SetCdm(CdmContext* cdm_context, |
| 101 const CdmAttachedCB& cdm_attached_cb) { | 138 const CdmAttachedCB& cdm_attached_cb) { |
| 102 DVLOG(1) << __FUNCTION__; | 139 DVLOG(1) << __FUNCTION__; |
| 103 DCHECK(task_runner_->BelongsToCurrentThread()); | 140 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 104 DCHECK(cdm_context); | 141 DCHECK(cdm_context); |
| 105 DCHECK(!cdm_attached_cb.is_null()); | 142 DCHECK(!cdm_attached_cb.is_null()); |
| 106 DCHECK(cdm_attached_cb_.is_null()); | 143 DCHECK(cdm_attached_cb_.is_null()); |
| 107 | 144 |
| 108 if (encountered_error_) { | 145 if (encountered_error_) { |
| 109 task_runner_->PostTask(FROM_HERE, base::Bind(cdm_attached_cb, false)); | 146 task_runner_->PostTask(FROM_HERE, base::Bind(cdm_attached_cb, false)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 base::AutoLock auto_lock(lock_); | 212 base::AutoLock auto_lock(lock_); |
| 176 DVLOG(3) << __FUNCTION__ << ": " << time_.InMilliseconds() << " ms"; | 213 DVLOG(3) << __FUNCTION__ << ": " << time_.InMilliseconds() << " ms"; |
| 177 return time_; | 214 return time_; |
| 178 } | 215 } |
| 179 | 216 |
| 180 bool MojoRenderer::HasAudio() { | 217 bool MojoRenderer::HasAudio() { |
| 181 DVLOG(1) << __FUNCTION__; | 218 DVLOG(1) << __FUNCTION__; |
| 182 DCHECK(task_runner_->BelongsToCurrentThread()); | 219 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 183 DCHECK(remote_renderer_.is_bound()); | 220 DCHECK(remote_renderer_.is_bound()); |
| 184 | 221 |
| 222 // TODO(tguilbert): Update for the URL case. |
| 185 return !!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); | 223 return !!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); |
| 186 } | 224 } |
| 187 | 225 |
| 188 bool MojoRenderer::HasVideo() { | 226 bool MojoRenderer::HasVideo() { |
| 189 DVLOG(1) << __FUNCTION__; | 227 DVLOG(1) << __FUNCTION__; |
| 190 DCHECK(task_runner_->BelongsToCurrentThread()); | 228 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 191 DCHECK(remote_renderer_.is_bound()); | 229 DCHECK(remote_renderer_.is_bound()); |
| 192 | 230 |
| 231 // TODO(tguilbert): Update for the URL case. |
| 193 return !!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); | 232 return !!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); |
| 194 } | 233 } |
| 195 | 234 |
| 196 void MojoRenderer::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) { | 235 void MojoRenderer::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) { |
| 197 DVLOG(3) << __FUNCTION__ << ": " << time_usec << ", " << max_time_usec; | 236 DVLOG(3) << __FUNCTION__ << ": " << time_usec << ", " << max_time_usec; |
| 198 DCHECK(task_runner_->BelongsToCurrentThread()); | 237 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 199 | 238 |
| 200 base::AutoLock auto_lock(lock_); | 239 base::AutoLock auto_lock(lock_); |
| 201 time_ = base::TimeDelta::FromMicroseconds(time_usec); | 240 time_ = base::TimeDelta::FromMicroseconds(time_usec); |
| 202 } | 241 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 222 | 261 |
| 223 // TODO(tim): Should we plumb error code from remote renderer? | 262 // TODO(tim): Should we plumb error code from remote renderer? |
| 224 // http://crbug.com/410451. | 263 // http://crbug.com/410451. |
| 225 client_->OnError(PIPELINE_ERROR_DECODE); | 264 client_->OnError(PIPELINE_ERROR_DECODE); |
| 226 } | 265 } |
| 227 | 266 |
| 228 void MojoRenderer::OnVideoNaturalSizeChange(const gfx::Size& size) { | 267 void MojoRenderer::OnVideoNaturalSizeChange(const gfx::Size& size) { |
| 229 DVLOG(2) << __FUNCTION__ << ": " << size.ToString(); | 268 DVLOG(2) << __FUNCTION__ << ": " << size.ToString(); |
| 230 DCHECK(task_runner_->BelongsToCurrentThread()); | 269 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 231 | 270 |
| 271 #if !BUILDFLAG(FORCE_MOJO_MEDIA_PLAYER_RENDERER) |
| 272 // TODO(tguilbert): Investigate why this line crashes when using the |
| 273 // MediaPlayerRenderer. |
| 232 video_renderer_sink_->PaintSingleFrame( | 274 video_renderer_sink_->PaintSingleFrame( |
| 233 video_overlay_factory_->CreateFrame(size)); | 275 video_overlay_factory_->CreateFrame(size)); |
| 276 #endif |
| 277 |
| 234 client_->OnVideoNaturalSizeChange(size); | 278 client_->OnVideoNaturalSizeChange(size); |
| 235 } | 279 } |
| 236 | 280 |
| 281 void MojoRenderer::OnDurationChange(int64_t duration_usec) { |
| 282 DVLOG(2) << __FUNCTION__ << ": duration" << duration_usec; |
| 283 client_->OnDurationChange(base::TimeDelta::FromMicroseconds(duration_usec)); |
| 284 } |
| 285 |
| 237 void MojoRenderer::OnVideoOpacityChange(bool opaque) { | 286 void MojoRenderer::OnVideoOpacityChange(bool opaque) { |
| 238 DVLOG(2) << __FUNCTION__ << ": " << opaque; | 287 DVLOG(2) << __FUNCTION__ << ": " << opaque; |
| 239 DCHECK(task_runner_->BelongsToCurrentThread()); | 288 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 240 client_->OnVideoOpacityChange(opaque); | 289 client_->OnVideoOpacityChange(opaque); |
| 241 } | 290 } |
| 242 | 291 |
| 243 void MojoRenderer::OnStatisticsUpdate(const PipelineStatistics& stats) { | 292 void MojoRenderer::OnStatisticsUpdate(const PipelineStatistics& stats) { |
| 244 DVLOG(3) << __FUNCTION__; | 293 DVLOG(3) << __FUNCTION__; |
| 245 DCHECK(task_runner_->BelongsToCurrentThread()); | 294 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 246 client_->OnStatisticsUpdate(stats); | 295 client_->OnStatisticsUpdate(stats); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); | 384 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| 336 | 385 |
| 337 if (!flush_cb_.is_null()) | 386 if (!flush_cb_.is_null()) |
| 338 base::ResetAndReturn(&flush_cb_).Run(); | 387 base::ResetAndReturn(&flush_cb_).Run(); |
| 339 | 388 |
| 340 if (!cdm_attached_cb_.is_null()) | 389 if (!cdm_attached_cb_.is_null()) |
| 341 base::ResetAndReturn(&cdm_attached_cb_).Run(false); | 390 base::ResetAndReturn(&cdm_attached_cb_).Run(false); |
| 342 } | 391 } |
| 343 | 392 |
| 344 } // namespace media | 393 } // namespace media |
| OLD | NEW |