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

Side by Side Diff: chromecast/media/cma/adapter/backend_adapter.cc

Issue 1372393007: [Chromecast] Upgrade to new CMA backend API (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Add V1 adapter Created 5 years, 2 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 2015 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/media/cma/adapter/backend_adapter.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "chromecast/base/task_runner_impl.h"
11 #include "chromecast/media/cma/adapter/audio_pipeline_device.h"
12 #include "chromecast/media/cma/adapter/media_clock_device.h"
13 #include "chromecast/media/cma/adapter/media_pipeline_backend_v1.h"
14 #include "chromecast/media/cma/adapter/video_pipeline_device.h"
15 #include "chromecast/public/graphics_types.h"
16 #include "chromecast/public/media/cast_decoder_buffer.h"
17 #include "chromecast/public/media/decrypt_context.h"
18 #include "chromecast/public/media/media_pipeline_device_params.h"
19
20 namespace chromecast {
21 namespace media {
22
23 #define RUN_ON_MEDIA_THREAD(type, method, ...) \
24 media_task_runner_->PostTask( \
25 FROM_HERE, \
26 base::Bind(&type::method, base::Unretained(this), ##__VA_ARGS__));
27
28 #define MAKE_SURE_MEDIA_THREAD(type, method, ...) \
29 DCHECK(media_task_runner_); \
30 if (!media_task_runner_->BelongsToCurrentThread()) { \
31 RUN_ON_MEDIA_THREAD(type, method, ##__VA_ARGS__) \
32 return; \
33 }
34
35 namespace {
36
37 MediaPipelineBackend::BufferStatus ConvertStatus(
38 MediaComponentDevice::FrameStatus status_in) {
39 switch (status_in) {
40 case MediaComponentDevice::kFrameSuccess:
41 return MediaPipelineBackend::kBufferSuccess;
42 case MediaComponentDevice::kFrameFailed:
43 return MediaPipelineBackend::kBufferFailed;
44 default:
45 NOTREACHED();
46 case MediaComponentDevice::kFramePending:
47 return MediaPipelineBackend::kBufferPending;
48 }
49 }
50
51 // Since the ownership model has changed from "callee-owned" to "caller-owned",
52 // we need wrappers to pass to the V1 interface that can safely be deleted
53 // at any time.
54 class DecryptContextWrapper : public DecryptContext {
55 public:
56 DecryptContextWrapper(DecryptContext* wrapped_in) : wrapped_(wrapped_in) {}
57
58 ~DecryptContextWrapper() override {}
59
60 // DecryptContext implementation:
61 CastKeySystem GetKeySystem() override {
62 return wrapped_ ? wrapped_->GetKeySystem() : KEY_SYSTEM_NONE;
63 }
64
65 bool Decrypt(CastDecoderBuffer* buffer,
66 std::vector<uint8_t>* output) override {
67 return wrapped_->Decrypt(buffer, output);
68 }
69
70 private:
71 DecryptContext* wrapped_;
72
73 DISALLOW_COPY_AND_ASSIGN(DecryptContextWrapper);
74 };
75
76 class CastDecoderBufferWrapper : public CastDecoderBuffer {
77 public:
78 CastDecoderBufferWrapper(CastDecoderBuffer* wrapped_in)
79 : wrapped_(wrapped_in) {
80 DCHECK(wrapped_);
81 }
82
83 ~CastDecoderBufferWrapper() override {}
84
85 // CastDecoderBuffer implementation:
86 StreamId stream_id() const override { return wrapped_->stream_id(); }
87 int64_t timestamp() const override { return wrapped_->timestamp(); }
88 const uint8_t* data() const override { return wrapped_->data(); }
89 size_t data_size() const override { return wrapped_->data_size(); }
90 const CastDecryptConfig* decrypt_config() const override {
91 return wrapped_->decrypt_config();
92 }
93 bool end_of_stream() const override { return wrapped_->end_of_stream(); }
94
95 private:
96 CastDecoderBuffer* wrapped_;
97
98 DISALLOW_COPY_AND_ASSIGN(CastDecoderBufferWrapper);
99 };
100
101 class FrameStatusCallback : public MediaComponentDevice::FrameStatusCB {
102 public:
103 FrameStatusCallback(
104 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
105 const base::WeakPtr<MediaPipelineBackendAdapter>& adapter,
106 bool video)
107 : media_task_runner_(media_task_runner),
108 adapter_(adapter),
109 video_(video) {
110 DCHECK(adapter_);
111 }
112
113 ~FrameStatusCallback() override {}
114
115 // MediaComponentDevice::FrameStatusCB implementation:
116 void Run(MediaComponentDevice::FrameStatus status) override {
117 MAKE_SURE_MEDIA_THREAD(FrameStatusCallback, Run, status);
118 if (adapter_) {
119 MediaPipelineBackend::BufferStatus status_out;
120 switch (status) {
121 case MediaComponentDevice::kFrameSuccess:
122 status_out = MediaPipelineBackend::kBufferSuccess;
123 break;
124 default:
125 NOTREACHED();
126 case MediaComponentDevice::kFrameFailed:
127 status_out = MediaPipelineBackend::kBufferFailed;
128 break;
129 }
130 adapter_->OnPushBufferComplete(video_, status_out);
131 }
132 }
133
134 private:
135 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
136 base::WeakPtr<MediaPipelineBackendAdapter> adapter_;
137 bool video_;
138
139 DISALLOW_COPY_AND_ASSIGN(FrameStatusCallback);
140 };
141
142 class V2AudioDecoder : public MediaPipelineBackend::AudioDecoder {
143 public:
144 V2AudioDecoder(
145 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
146 const base::WeakPtr<MediaPipelineBackendAdapter>& adapter,
147 media::AudioPipelineDevice* device)
148 : media_task_runner_(media_task_runner),
149 device_(device),
150 adapter_(adapter) {}
151
152 BufferStatus PushBuffer(DecryptContext* decrypt_context,
153 CastDecoderBuffer* buffer) override {
154 return ConvertStatus(device_->PushFrame(
155 new DecryptContextWrapper(decrypt_context),
156 new CastDecoderBufferWrapper(buffer),
157 new FrameStatusCallback(
158 media_task_runner_, adapter_, false /* video */)));
159 }
160
161 void GetStatistics(Statistics* statistics) override {
162 device_->GetStatistics(statistics);
163 }
164
165 bool SetConfig(const AudioConfig& config) override {
166 return device_->SetConfig(config);
167 }
168
169 bool SetVolume(float multiplier) override {
170 device_->SetStreamVolumeMultiplier(multiplier);
171 return true;
172 }
173
174 RenderingDelay GetRenderingDelay() override {
175 return device_->GetRenderingDelay();
176 }
177
178 private:
179 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
180 media::AudioPipelineDevice* device_;
181 base::WeakPtr<MediaPipelineBackendAdapter> adapter_;
182 };
183
184 class V2VideoDecoder : public MediaPipelineBackend::VideoDecoder {
185 public:
186 V2VideoDecoder(
187 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
188 base::WeakPtr<MediaPipelineBackendAdapter> adapter,
189 media::VideoPipelineDevice* device)
190 : media_task_runner_(media_task_runner),
191 device_(device),
192 adapter_(adapter) {}
193
194 BufferStatus PushBuffer(DecryptContext* decrypt_context,
195 CastDecoderBuffer* buffer) override {
196 return ConvertStatus(device_->PushFrame(
197 new DecryptContextWrapper(decrypt_context),
198 new CastDecoderBufferWrapper(buffer),
199 new FrameStatusCallback(
200 media_task_runner_, adapter_, true /* video */)));
201 }
202
203 void GetStatistics(MediaComponentDevice::Statistics* statistics) override {
204 device_->GetStatistics(statistics);
205 }
206
207 bool SetConfig(const VideoConfig& config) override {
208 return device_->SetConfig(config);
209 }
210
211 private:
212 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
213 media::VideoPipelineDevice* device_;
214 base::WeakPtr<MediaPipelineBackendAdapter> adapter_;
215 };
216
217 class AudioClientAdapter : public MediaComponentDevice::Client {
218 public:
219 AudioClientAdapter(
220 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
221 const base::WeakPtr<MediaPipelineBackendAdapter>& adapter)
222 : media_task_runner_(media_task_runner), adapter_(adapter) {}
223 void OnEndOfStream() override {
224 MAKE_SURE_MEDIA_THREAD(AudioClientAdapter, OnEndOfStream);
225 if (adapter_)
226 adapter_->OnEndOfAudioStream();
227 }
228
229 private:
230 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
231 base::WeakPtr<MediaPipelineBackendAdapter> adapter_;
232 };
233
234 class VideoClientAdapter : public MediaComponentDevice::Client,
235 public VideoPipelineDevice::VideoClient {
236 public:
237 VideoClientAdapter(
238 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
239 const base::WeakPtr<MediaPipelineBackendAdapter>& adapter)
240 : media_task_runner_(media_task_runner), adapter_(adapter) {}
241 void OnEndOfStream() override {
242 MAKE_SURE_MEDIA_THREAD(VideoClientAdapter, OnEndOfStream);
243 if (adapter_)
244 adapter_->OnEndOfVideoStream();
245 }
246 void OnNaturalSizeChanged(const Size& size) override {
247 MAKE_SURE_MEDIA_THREAD(VideoClientAdapter, OnNaturalSizeChanged, size);
248 if (adapter_)
249 adapter_->OnNaturalSizeChanged(size);
250 }
251
252 private:
253 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
254 base::WeakPtr<MediaPipelineBackendAdapter> adapter_;
255 };
256
257 } // namespace
258
259 MediaPipelineBackendAdapter::MediaPipelineBackendAdapter(
260 const MediaPipelineDeviceParams& params,
261 scoped_ptr<media::MediaPipelineBackendV1> backend_v1)
262 : backend_v1_(backend_v1.Pass()),
263 clock_(backend_v1_->GetClock()),
264 audio_(nullptr),
265 video_(nullptr),
266 playing_(false),
267 rate_(1.0f),
268 weak_factory_(this) {
269 DCHECK(clock_);
270
271 media_task_runner_ =
272 static_cast<TaskRunnerImpl*>(params.task_runner)->runner();
273 }
274
275 MediaPipelineBackendAdapter::~MediaPipelineBackendAdapter() {
276 }
277
278 MediaPipelineBackend::AudioDecoder*
279 MediaPipelineBackendAdapter::CreateAudioDecoder() {
280 DCHECK(!audio_);
281 audio_ = backend_v1_->GetAudio();
282 audio_->SetClient(
283 new AudioClientAdapter(media_task_runner_, weak_factory_.GetWeakPtr()));
284 audio_decoder_ = new V2AudioDecoder(
285 media_task_runner_, weak_factory_.GetWeakPtr(), audio_);
286 return audio_decoder_;
287 }
288
289 MediaPipelineBackend::VideoDecoder*
290 MediaPipelineBackendAdapter::CreateVideoDecoder() {
291 DCHECK(!video_);
292 video_ = backend_v1_->GetVideo();
293 video_->SetClient(
294 new VideoClientAdapter(media_task_runner_, weak_factory_.GetWeakPtr()));
295 video_->SetVideoClient(
296 new VideoClientAdapter(media_task_runner_, weak_factory_.GetWeakPtr()));
297 video_decoder_ = new V2VideoDecoder(
298 media_task_runner_, weak_factory_.GetWeakPtr(), video_);
299 return video_decoder_;
300 }
301
302 bool MediaPipelineBackendAdapter::Initialize(Delegate* delegate) {
303 DCHECK(delegate);
304 delegate_ = delegate;
305
306 if (!clock_->SetState(MediaClockDevice::kStateIdle))
307 return false;
308
309 if (audio_ && !audio_->SetState(MediaComponentDevice::kStateIdle))
310 return false;
311
312 if (video_ && !video_->SetState(MediaComponentDevice::kStateIdle))
313 return false;
314
315 return true;
316 }
317
318 bool MediaPipelineBackendAdapter::Start(int64_t start_pts) {
319 DCHECK(!playing_);
320 if (!clock_->ResetTimeline(start_pts))
321 return false;
322 if (audio_ && !audio_->SetStartPts(start_pts))
323 return false;
324 if (video_ && !video_->SetStartPts(start_pts))
325 return false;
326
327 if (!clock_->SetRate(rate_))
328 return false;
329 if (!clock_->SetState(MediaClockDevice::kStateRunning))
330 return false;
331 if (audio_ && !audio_->SetState(MediaComponentDevice::kStateRunning))
332 return false;
333 if (video_ && !video_->SetState(MediaComponentDevice::kStateRunning))
334 return false;
335
336 playing_ = true;
337 return true;
338 }
339
340 bool MediaPipelineBackendAdapter::Stop() {
341 DCHECK(playing_);
342 playing_ = false;
343 if (!clock_->SetState(MediaClockDevice::kStateIdle))
344 return false;
345 if (audio_ && !audio_->SetState(MediaComponentDevice::kStateIdle))
346 return false;
347 if (video_ && !video_->SetState(MediaComponentDevice::kStateIdle))
348 return false;
349 return true;
350 }
351
352 bool MediaPipelineBackendAdapter::Pause() {
353 DCHECK(playing_);
354 return clock_->SetRate(0.0f);
355 }
356
357 bool MediaPipelineBackendAdapter::Resume() {
358 DCHECK(playing_);
359 return clock_->SetRate(rate_);
360 }
361
362 int64_t MediaPipelineBackendAdapter::GetCurrentPts() {
363 return clock_->GetTimeMicroseconds();
364 }
365
366 bool MediaPipelineBackendAdapter::SetPlaybackRate(float rate) {
367 DCHECK_GE(rate, 0.0f);
368 DCHECK_LE(rate, 1.0f);
369 rate_ = rate;
370 if (playing_)
371 return clock_->SetRate(rate);
372 return true;
373 }
374
375 void MediaPipelineBackendAdapter::OnEndOfAudioStream() {
376 delegate_->OnEndOfStream(audio_decoder_);
377 }
378
379 void MediaPipelineBackendAdapter::OnEndOfVideoStream() {
380 delegate_->OnEndOfStream(video_decoder_);
381 }
382
383 void MediaPipelineBackendAdapter::OnPushBufferComplete(bool video,
384 BufferStatus status) {
385 MAKE_SURE_MEDIA_THREAD(
386 MediaPipelineBackendAdapter, OnPushBufferComplete, video, status);
387 if (video)
388 delegate_->OnPushBufferComplete(video_decoder_, status);
389 else
390 delegate_->OnPushBufferComplete(audio_decoder_, status);
391 }
392
393 void MediaPipelineBackendAdapter::OnNaturalSizeChanged(const Size& size) {
394 delegate_->OnVideoResolutionChanged(video_decoder_, size);
395 }
396
397 } // namespace media
398 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698