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

Side by Side Diff: chromecast/renderer/media/media_pipeline_proxy.cc

Issue 2300993003: CmaRenderer is dead. Long live MojoRenderer. (Closed)
Patch Set: update OWNERS file Created 4 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chromecast/renderer/media/media_pipeline_proxy.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/single_thread_task_runner.h"
15 #include "chromecast/common/media/cma_messages.h"
16 #include "chromecast/media/cma/base/coded_frame_provider.h"
17 #include "chromecast/renderer/media/audio_pipeline_proxy.h"
18 #include "chromecast/renderer/media/media_channel_proxy.h"
19 #include "chromecast/renderer/media/video_pipeline_proxy.h"
20
21 namespace chromecast {
22 namespace media {
23
24 // MediaPipelineProxyInternal -
25 // This class is not thread safe and should run on the same thread
26 // as the media channel proxy.
27 class MediaPipelineProxyInternal {
28 public:
29 static void Release(std::unique_ptr<MediaPipelineProxyInternal> proxy);
30
31 explicit MediaPipelineProxyInternal(
32 scoped_refptr<MediaChannelProxy> media_channel_proxy);
33 virtual ~MediaPipelineProxyInternal();
34
35 void SetClient(const MediaPipelineClient& client);
36 void SetCdm(int render_frame_id, int cdm_id);
37 void StartPlayingFrom(const base::TimeDelta& time);
38 void Flush(const base::Closure& flush_cb);
39 void Stop();
40 void SetPlaybackRate(double playback_rate);
41
42 private:
43 void Shutdown();
44
45 // Callbacks for CmaMessageFilterHost::MediaDelegate.
46 void OnFlushDone();
47
48 base::ThreadChecker thread_checker_;
49
50 scoped_refptr<MediaChannelProxy> media_channel_proxy_;
51
52 MediaPipelineClient client_;
53
54 // Store the callback for a flush.
55 base::Closure flush_cb_;
56
57 DISALLOW_COPY_AND_ASSIGN(MediaPipelineProxyInternal);
58 };
59
60 // static
61 void MediaPipelineProxyInternal::Release(
62 std::unique_ptr<MediaPipelineProxyInternal> proxy) {
63 proxy->Shutdown();
64 }
65
66 MediaPipelineProxyInternal::MediaPipelineProxyInternal(
67 scoped_refptr<MediaChannelProxy> media_channel_proxy)
68 : media_channel_proxy_(media_channel_proxy) {
69 DCHECK(media_channel_proxy.get());
70
71 // Creation can be done on a different thread.
72 thread_checker_.DetachFromThread();
73 }
74
75 MediaPipelineProxyInternal::~MediaPipelineProxyInternal() {
76 }
77
78 void MediaPipelineProxyInternal::Shutdown() {
79 DCHECK(thread_checker_.CalledOnValidThread());
80
81 // Remove any callback on VideoPipelineProxyInternal.
82 media_channel_proxy_->SetMediaDelegate(
83 CmaMessageFilterProxy::MediaDelegate());
84 }
85
86 void MediaPipelineProxyInternal::SetClient(const MediaPipelineClient& client) {
87 DCHECK(thread_checker_.CalledOnValidThread());
88 DCHECK(!client.error_cb.is_null());
89 DCHECK(!client.buffering_state_cb.is_null());
90 client_ = client;
91
92 CmaMessageFilterProxy::MediaDelegate delegate;
93 delegate.flush_cb = base::Bind(&MediaPipelineProxyInternal::OnFlushDone,
94 base::Unretained(this));
95 delegate.client = client;
96 bool success = media_channel_proxy_->SetMediaDelegate(delegate);
97 CHECK(success);
98 }
99
100 void MediaPipelineProxyInternal::SetCdm(int render_frame_id, int cdm_id) {
101 DCHECK(thread_checker_.CalledOnValidThread());
102 bool success = media_channel_proxy_->Send(
103 std::unique_ptr<IPC::Message>(new CmaHostMsg_SetCdm(
104 media_channel_proxy_->GetId(), render_frame_id, cdm_id)));
105 LOG_IF(ERROR, !success) << "Failed to send SetCdm=" << cdm_id;
106 }
107
108 void MediaPipelineProxyInternal::Flush(const base::Closure& flush_cb) {
109 DCHECK(thread_checker_.CalledOnValidThread());
110 bool success = media_channel_proxy_->Send(std::unique_ptr<IPC::Message>(
111 new CmaHostMsg_Flush(media_channel_proxy_->GetId())));
112 if (!success) {
113 LOG(ERROR) << "Failed to send Flush";
114 return;
115 }
116 DCHECK(flush_cb_.is_null());
117 flush_cb_ = flush_cb;
118 }
119
120 void MediaPipelineProxyInternal::Stop() {
121 DCHECK(thread_checker_.CalledOnValidThread());
122 bool success = media_channel_proxy_->Send(std::unique_ptr<IPC::Message>(
123 new CmaHostMsg_Stop(media_channel_proxy_->GetId())));
124 if (!success)
125 client_.error_cb.Run(::media::PIPELINE_ERROR_ABORT);
126 }
127
128 void MediaPipelineProxyInternal::StartPlayingFrom(const base::TimeDelta& time) {
129 DCHECK(thread_checker_.CalledOnValidThread());
130 bool success = media_channel_proxy_->Send(std::unique_ptr<IPC::Message>(
131 new CmaHostMsg_StartPlayingFrom(media_channel_proxy_->GetId(), time)));
132 if (!success)
133 client_.error_cb.Run(::media::PIPELINE_ERROR_ABORT);
134 }
135
136 void MediaPipelineProxyInternal::SetPlaybackRate(double playback_rate) {
137 DCHECK(thread_checker_.CalledOnValidThread());
138 media_channel_proxy_->Send(
139 std::unique_ptr<IPC::Message>(new CmaHostMsg_SetPlaybackRate(
140 media_channel_proxy_->GetId(), playback_rate)));
141 }
142
143 void MediaPipelineProxyInternal::OnFlushDone() {
144 DCHECK(thread_checker_.CalledOnValidThread());
145 DCHECK(!flush_cb_.is_null());
146 base::ResetAndReturn(&flush_cb_).Run();
147 }
148
149 // A macro runs current member function on |io_task_runner_| thread.
150 #define FORWARD_ON_IO_THREAD(param_fn, ...) \
151 io_task_runner_->PostTask( \
152 FROM_HERE, base::Bind(&MediaPipelineProxyInternal::param_fn, \
153 base::Unretained(proxy_.get()), ##__VA_ARGS__))
154
155 MediaPipelineProxy::MediaPipelineProxy(
156 int render_frame_id,
157 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
158 LoadType load_type)
159 : io_task_runner_(io_task_runner),
160 render_frame_id_(render_frame_id),
161 media_channel_proxy_(new MediaChannelProxy),
162 proxy_(new MediaPipelineProxyInternal(media_channel_proxy_)),
163 has_audio_(false),
164 has_video_(false),
165 audio_pipeline_(
166 new AudioPipelineProxy(io_task_runner, media_channel_proxy_)),
167 video_pipeline_(
168 new VideoPipelineProxy(io_task_runner, media_channel_proxy_)),
169 weak_factory_(this) {
170 weak_this_ = weak_factory_.GetWeakPtr();
171 io_task_runner_->PostTask(
172 FROM_HERE,
173 base::Bind(&MediaChannelProxy::Open, media_channel_proxy_, load_type));
174 thread_checker_.DetachFromThread();
175 }
176
177 MediaPipelineProxy::~MediaPipelineProxy() {
178 io_task_runner_->PostTask(
179 FROM_HERE,
180 base::Bind(&MediaPipelineProxyInternal::Release, base::Passed(&proxy_)));
181 io_task_runner_->PostTask(
182 FROM_HERE, base::Bind(&MediaChannelProxy::Close, media_channel_proxy_));
183 }
184
185 void MediaPipelineProxy::SetClient(const MediaPipelineClient& client) {
186 DCHECK(thread_checker_.CalledOnValidThread());
187 FORWARD_ON_IO_THREAD(SetClient, client);
188 }
189
190 void MediaPipelineProxy::SetCdm(int cdm_id) {
191 DCHECK(thread_checker_.CalledOnValidThread());
192 FORWARD_ON_IO_THREAD(SetCdm, render_frame_id_, cdm_id);
193 }
194
195 AudioPipelineProxy* MediaPipelineProxy::GetAudioPipeline() const {
196 return audio_pipeline_.get();
197 }
198
199 VideoPipelineProxy* MediaPipelineProxy::GetVideoPipeline() const {
200 return video_pipeline_.get();
201 }
202
203 void MediaPipelineProxy::InitializeAudio(
204 const ::media::AudioDecoderConfig& config,
205 std::unique_ptr<CodedFrameProvider> frame_provider,
206 const ::media::PipelineStatusCB& status_cb) {
207 DCHECK(thread_checker_.CalledOnValidThread());
208 has_audio_ = true;
209 audio_pipeline_->Initialize(config, std::move(frame_provider), status_cb);
210 }
211
212 void MediaPipelineProxy::InitializeVideo(
213 const std::vector<::media::VideoDecoderConfig>& configs,
214 std::unique_ptr<CodedFrameProvider> frame_provider,
215 const ::media::PipelineStatusCB& status_cb) {
216 DCHECK(thread_checker_.CalledOnValidThread());
217 has_video_ = true;
218 video_pipeline_->Initialize(configs, std::move(frame_provider), status_cb);
219 }
220
221 void MediaPipelineProxy::StartPlayingFrom(base::TimeDelta time) {
222 DCHECK(thread_checker_.CalledOnValidThread());
223 if (has_audio_)
224 audio_pipeline_->StartFeeding();
225 if (has_video_)
226 video_pipeline_->StartFeeding();
227 FORWARD_ON_IO_THREAD(StartPlayingFrom, time);
228 }
229
230 void MediaPipelineProxy::Flush(const base::Closure& flush_cb) {
231 DCHECK(thread_checker_.CalledOnValidThread());
232 DCHECK(has_audio_ || has_video_);
233
234 ::media::SerialRunner::Queue bound_fns;
235 if (has_audio_) {
236 bound_fns.Push(base::Bind(&AudioPipelineProxy::Flush,
237 base::Unretained(audio_pipeline_.get())));
238 }
239 if (has_video_) {
240 bound_fns.Push(base::Bind(&VideoPipelineProxy::Flush,
241 base::Unretained(video_pipeline_.get())));
242 }
243 ::media::PipelineStatusCB cb =
244 base::Bind(&MediaPipelineProxy::OnProxyFlushDone, weak_this_, flush_cb);
245 pending_flush_callbacks_ = ::media::SerialRunner::Run(bound_fns, cb);
246 }
247
248 void MediaPipelineProxy::OnProxyFlushDone(const base::Closure& flush_cb,
249 ::media::PipelineStatus status) {
250 DCHECK(thread_checker_.CalledOnValidThread());
251 DCHECK_EQ(status, ::media::PIPELINE_OK);
252 pending_flush_callbacks_.reset();
253 FORWARD_ON_IO_THREAD(Flush, flush_cb);
254 }
255
256 void MediaPipelineProxy::Stop() {
257 DCHECK(thread_checker_.CalledOnValidThread());
258 DCHECK(has_audio_ || has_video_);
259
260 // Cancel pending flush callbacks since we are about to stop/shutdown
261 // audio/video pipelines. This will ensure A/V Flush won't happen in
262 // stopped state.
263 pending_flush_callbacks_.reset();
264
265 if (has_audio_)
266 audio_pipeline_->Stop();
267 if (has_video_)
268 video_pipeline_->Stop();
269
270 FORWARD_ON_IO_THREAD(Stop);
271 }
272
273 void MediaPipelineProxy::SetPlaybackRate(double playback_rate) {
274 DCHECK(thread_checker_.CalledOnValidThread());
275 FORWARD_ON_IO_THREAD(SetPlaybackRate, playback_rate);
276 }
277
278 } // namespace cma
279 } // namespace chromecast
OLDNEW
« no previous file with comments | « chromecast/renderer/media/media_pipeline_proxy.h ('k') | chromecast/renderer/media/video_pipeline_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698