Chromium Code Reviews| 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" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 DVLOG(1) << __func__; | 71 DVLOG(1) << __func__; |
| 72 DCHECK(task_runner_->BelongsToCurrentThread()); | 72 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 73 | 73 |
| 74 // Create audio and video mojom::DemuxerStream and bind its lifetime to | 74 // Create audio and video mojom::DemuxerStream and bind its lifetime to |
| 75 // the pipe. | 75 // the pipe. |
| 76 DemuxerStream* const audio = | 76 DemuxerStream* const audio = |
| 77 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); | 77 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); |
| 78 DemuxerStream* const video = | 78 DemuxerStream* const video = |
| 79 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); | 79 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); |
| 80 | 80 |
| 81 mojom::DemuxerStreamPtr audio_stream; | 81 std::vector<mojom::DemuxerStreamPtr> streams; |
| 82 if (audio) { | 82 if (audio) { |
| 83 audio_stream_.reset( | 83 mojom::DemuxerStreamPtr audio_stream; |
| 84 streams_.emplace_back( | |
| 84 new MojoDemuxerStreamImpl(audio, MakeRequest(&audio_stream))); | 85 new MojoDemuxerStreamImpl(audio, MakeRequest(&audio_stream))); |
| 85 // Using base::Unretained(this) is safe because |this| owns | 86 MojoDemuxerStreamImpl* mojo_stream = streams_.back().get(); |
| 86 // |audio_stream_|, and the error handler can't be invoked once | 87 // Using base::Unretained(this) is safe because |this| owns |mojo_stream|, |
| 87 // |audio_stream_| is destroyed. | 88 // and the error handler can't be invoked once |mojo_stream| is destroyed. |
| 88 audio_stream_->set_connection_error_handler( | 89 mojo_stream->set_connection_error_handler( |
| 89 base::Bind(&MojoRenderer::OnDemuxerStreamConnectionError, | 90 base::Bind(&MojoRenderer::OnDemuxerStreamConnectionError, |
| 90 base::Unretained(this), DemuxerStream::AUDIO)); | 91 base::Unretained(this), mojo_stream)); |
|
xhwang
2017/01/31 00:15:21
For future discussion: I am not a fan of using poi
xhwang
2017/01/31 00:15:21
nit: It's a bit weird that we emplace_back the str
servolk
2017/01/31 01:10:40
Done. Although it's a tiny bit more inefficient, s
servolk
2017/01/31 01:10:40
I understand your concern in general, but TBH in t
| |
| 92 streams.push_back(std::move(audio_stream)); | |
| 91 } | 93 } |
| 92 | 94 |
| 93 mojom::DemuxerStreamPtr video_stream; | |
| 94 if (video) { | 95 if (video) { |
| 95 video_stream_.reset( | 96 mojom::DemuxerStreamPtr video_stream; |
| 97 streams_.emplace_back( | |
| 96 new MojoDemuxerStreamImpl(video, MakeRequest(&video_stream))); | 98 new MojoDemuxerStreamImpl(video, MakeRequest(&video_stream))); |
| 97 // Using base::Unretained(this) is safe because |this| owns | 99 MojoDemuxerStreamImpl* mojo_stream = streams_.back().get(); |
| 98 // |video_stream_|, and the error handler can't be invoked once | 100 // Using base::Unretained(this) is safe because |this| owns |mojo_stream|, |
| 99 // |video_stream_| is destroyed. | 101 // and the error handler can't be invoked once |mojo_stream| is destroyed. |
| 100 video_stream_->set_connection_error_handler( | 102 mojo_stream->set_connection_error_handler( |
| 101 base::Bind(&MojoRenderer::OnDemuxerStreamConnectionError, | 103 base::Bind(&MojoRenderer::OnDemuxerStreamConnectionError, |
| 102 base::Unretained(this), DemuxerStream::VIDEO)); | 104 base::Unretained(this), mojo_stream)); |
| 105 streams.push_back(std::move(video_stream)); | |
| 103 } | 106 } |
| 104 | 107 |
| 105 BindRemoteRendererIfNeeded(); | 108 BindRemoteRendererIfNeeded(); |
| 106 | 109 |
| 107 mojom::RendererClientAssociatedPtrInfo client_ptr_info; | 110 mojom::RendererClientAssociatedPtrInfo client_ptr_info; |
| 108 client_binding_.Bind(&client_ptr_info, remote_renderer_.associated_group()); | 111 client_binding_.Bind(&client_ptr_info, remote_renderer_.associated_group()); |
| 109 | 112 |
| 110 // Using base::Unretained(this) is safe because |this| owns | 113 // Using base::Unretained(this) is safe because |this| owns |
| 111 // |remote_renderer_|, and the callback won't be dispatched if | 114 // |remote_renderer_|, and the callback won't be dispatched if |
| 112 // |remote_renderer_| is destroyed. | 115 // |remote_renderer_| is destroyed. |
| 113 remote_renderer_->Initialize( | 116 remote_renderer_->Initialize( |
| 114 std::move(client_ptr_info), std::move(audio_stream), | 117 std::move(client_ptr_info), std::move(streams), base::nullopt, |
| 115 std::move(video_stream), base::nullopt, base::nullopt, | 118 base::nullopt, |
| 116 base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); | 119 base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); |
| 117 } | 120 } |
| 118 | 121 |
| 119 void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) { | 122 void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) { |
| 120 DVLOG(2) << __func__; | 123 DVLOG(2) << __func__; |
| 121 DCHECK(task_runner_->BelongsToCurrentThread()); | 124 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 122 | 125 |
| 123 BindRemoteRendererIfNeeded(); | 126 BindRemoteRendererIfNeeded(); |
| 124 | 127 |
| 125 mojom::RendererClientAssociatedPtrInfo client_ptr_info; | 128 mojom::RendererClientAssociatedPtrInfo client_ptr_info; |
| 126 client_binding_.Bind(&client_ptr_info, remote_renderer_.associated_group()); | 129 client_binding_.Bind(&client_ptr_info, remote_renderer_.associated_group()); |
| 127 | 130 |
| 128 MediaUrlParams url_params = demuxer_stream_provider_->GetMediaUrlParams(); | 131 MediaUrlParams url_params = demuxer_stream_provider_->GetMediaUrlParams(); |
| 129 | 132 |
| 130 // Using base::Unretained(this) is safe because |this| owns | 133 // Using base::Unretained(this) is safe because |this| owns |
| 131 // |remote_renderer_|, and the callback won't be dispatched if | 134 // |remote_renderer_|, and the callback won't be dispatched if |
| 132 // |remote_renderer_| is destroyed. | 135 // |remote_renderer_| is destroyed. |
| 136 std::vector<mojom::DemuxerStreamPtr> streams; | |
| 133 remote_renderer_->Initialize( | 137 remote_renderer_->Initialize( |
| 134 std::move(client_ptr_info), mojom::DemuxerStreamPtr(), | 138 std::move(client_ptr_info), std::move(streams), url_params.media_url, |
| 135 mojom::DemuxerStreamPtr(), url_params.media_url, | |
| 136 url_params.first_party_for_cookies, | 139 url_params.first_party_for_cookies, |
| 137 base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); | 140 base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); |
| 138 } | 141 } |
| 139 | 142 |
| 140 void MojoRenderer::SetCdm(CdmContext* cdm_context, | 143 void MojoRenderer::SetCdm(CdmContext* cdm_context, |
| 141 const CdmAttachedCB& cdm_attached_cb) { | 144 const CdmAttachedCB& cdm_attached_cb) { |
| 142 DVLOG(1) << __func__; | 145 DVLOG(1) << __func__; |
| 143 DCHECK(task_runner_->BelongsToCurrentThread()); | 146 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 144 DCHECK(cdm_context); | 147 DCHECK(cdm_context); |
| 145 DCHECK(!cdm_attached_cb.is_null()); | 148 DCHECK(!cdm_attached_cb.is_null()); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 DVLOG(1) << __func__; | 311 DVLOG(1) << __func__; |
| 309 DCHECK(task_runner_->BelongsToCurrentThread()); | 312 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 310 | 313 |
| 311 encountered_error_ = true; | 314 encountered_error_ = true; |
| 312 CancelPendingCallbacks(); | 315 CancelPendingCallbacks(); |
| 313 | 316 |
| 314 if (client_) | 317 if (client_) |
| 315 client_->OnError(PIPELINE_ERROR_DECODE); | 318 client_->OnError(PIPELINE_ERROR_DECODE); |
| 316 } | 319 } |
| 317 | 320 |
| 318 void MojoRenderer::OnDemuxerStreamConnectionError(DemuxerStream::Type type) { | 321 void MojoRenderer::OnDemuxerStreamConnectionError( |
| 319 DVLOG(1) << __func__ << ": " << type; | 322 MojoDemuxerStreamImpl* stream) { |
| 323 DVLOG(1) << __func__ << ": stream=" << stream; | |
| 320 DCHECK(task_runner_->BelongsToCurrentThread()); | 324 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 321 | 325 |
| 322 if (type == DemuxerStream::AUDIO) { | 326 for (auto& s : streams_) { |
| 323 audio_stream_.reset(); | 327 if (s.get() == stream) { |
|
xhwang
2017/01/31 00:15:21
ditto about using pointer as ID for comparison...
servolk
2017/01/31 01:10:40
TBH I think that using an ID instead of pointer wo
xhwang
2017/01/31 07:49:07
If we use ID, |streams_| will probably be a map in
servolk
2017/01/31 17:38:04
Yes, I understand that we could trivially map the
| |
| 324 } else if (type == DemuxerStream::VIDEO) { | 328 s.reset(); |
| 325 video_stream_.reset(); | 329 return; |
| 326 } else { | 330 } |
| 327 NOTREACHED() << "Unexpected demuxer stream type: " << type; | |
| 328 } | 331 } |
| 332 NOTREACHED() << "Unrecognized demuxer stream=" << stream; | |
| 329 } | 333 } |
| 330 | 334 |
| 331 void MojoRenderer::BindRemoteRendererIfNeeded() { | 335 void MojoRenderer::BindRemoteRendererIfNeeded() { |
| 332 DVLOG(2) << __func__; | 336 DVLOG(2) << __func__; |
| 333 DCHECK(task_runner_->BelongsToCurrentThread()); | 337 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 334 | 338 |
| 335 // If |remote_renderer_| has already been bound, do nothing. | 339 // If |remote_renderer_| has already been bound, do nothing. |
| 336 // Note that after Bind() is called, |remote_renderer_| is always bound even | 340 // Note that after Bind() is called, |remote_renderer_| is always bound even |
| 337 // after connection error. | 341 // after connection error. |
| 338 if (remote_renderer_.is_bound()) | 342 if (remote_renderer_.is_bound()) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); | 391 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| 388 | 392 |
| 389 if (!flush_cb_.is_null()) | 393 if (!flush_cb_.is_null()) |
| 390 base::ResetAndReturn(&flush_cb_).Run(); | 394 base::ResetAndReturn(&flush_cb_).Run(); |
| 391 | 395 |
| 392 if (!cdm_attached_cb_.is_null()) | 396 if (!cdm_attached_cb_.is_null()) |
| 393 base::ResetAndReturn(&cdm_attached_cb_).Run(false); | 397 base::ResetAndReturn(&cdm_attached_cb_).Run(false); |
| 394 } | 398 } |
| 395 | 399 |
| 396 } // namespace media | 400 } // namespace media |
| OLD | NEW |