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

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

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

Powered by Google App Engine
This is Rietveld 408576698