Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: media/mojo/clients/mojo_renderer.cc

Issue 2383663002: Make mojo renderer capable of supporting multiple streams/tracks (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698