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 |