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 |