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.
5 #include "chromecast/media/cma/backend/media_pipeline_device_fake.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/message_loop/message_loop_proxy.h"
15 #include "chromecast/media/cma/backend/audio_pipeline_device.h"
16 #include "chromecast/media/cma/backend/media_clock_device.h"
17 #include "chromecast/media/cma/backend/media_component_device.h"
18 #include "chromecast/media/cma/backend/video_pipeline_device.h"
19 #include "chromecast/media/cma/base/decoder_buffer_base.h"
20 #include "media/base/audio_decoder_config.h"
21 #include "media/base/buffers.h"
22 #include "media/base/video_decoder_config.h"
24 namespace chromecast
{
27 class MediaClockDeviceFake
: public MediaClockDevice
{
29 MediaClockDeviceFake();
30 ~MediaClockDeviceFake() override
;
32 // MediaClockDevice implementation.
33 State
GetState() const override
;
34 bool SetState(State new_state
) override
;
35 bool ResetTimeline(base::TimeDelta time
) override
;
36 bool SetRate(float rate
) override
;
37 base::TimeDelta
GetTime() override
;
42 // Media time sampled at STC time |stc_|.
43 base::TimeDelta media_time_
;
48 DISALLOW_COPY_AND_ASSIGN(MediaClockDeviceFake
);
51 MediaClockDeviceFake::MediaClockDeviceFake()
52 : state_(kStateUninitialized
),
53 media_time_(::media::kNoTimestamp()) {
57 MediaClockDeviceFake::~MediaClockDeviceFake() {
60 MediaClockDevice::State
MediaClockDeviceFake::GetState() const {
61 DCHECK(CalledOnValidThread());
65 bool MediaClockDeviceFake::SetState(State new_state
) {
66 DCHECK(CalledOnValidThread());
67 if (!MediaClockDevice::IsValidStateTransition(state_
, new_state
))
70 if (new_state
== state_
)
75 if (state_
== kStateRunning
) {
76 stc_
= base::TimeTicks::Now();
77 DCHECK(media_time_
!= ::media::kNoTimestamp());
81 if (state_
== kStateIdle
) {
82 media_time_
= ::media::kNoTimestamp();
89 bool MediaClockDeviceFake::ResetTimeline(base::TimeDelta time
) {
90 DCHECK(CalledOnValidThread());
91 DCHECK_EQ(state_
, kStateIdle
);
96 bool MediaClockDeviceFake::SetRate(float rate
) {
97 DCHECK(CalledOnValidThread());
98 if (state_
== kStateRunning
) {
99 base::TimeTicks now
= base::TimeTicks::Now();
100 media_time_
= media_time_
+ (now
- stc_
) * rate_
;
108 base::TimeDelta
MediaClockDeviceFake::GetTime() {
109 DCHECK(CalledOnValidThread());
110 if (state_
!= kStateRunning
)
113 if (media_time_
== ::media::kNoTimestamp())
114 return ::media::kNoTimestamp();
116 base::TimeTicks now
= base::TimeTicks::Now();
117 base::TimeDelta interpolated_media_time
=
118 media_time_
+ (now
- stc_
) * rate_
;
119 return interpolated_media_time
;
125 // Maximum number of frames that can be buffered.
126 const size_t kMaxFrameCount
= 20;
130 class MediaComponentDeviceFake
: public MediaComponentDevice
{
132 explicit MediaComponentDeviceFake(MediaClockDeviceFake
* media_clock_device
);
133 ~MediaComponentDeviceFake() override
;
135 // MediaComponentDevice implementation.
136 void SetClient(const Client
& client
) override
;
137 State
GetState() const override
;
138 bool SetState(State new_state
) override
;
139 bool SetStartPts(base::TimeDelta time
) override
;
140 FrameStatus
PushFrame(
141 const scoped_refptr
<DecryptContext
>& decrypt_context
,
142 const scoped_refptr
<DecoderBufferBase
>& buffer
,
143 const FrameStatusCB
& completion_cb
) override
;
144 base::TimeDelta
GetRenderingTime() const override
;
145 base::TimeDelta
GetRenderingDelay() const override
;
146 bool GetStatistics(Statistics
* stats
) const override
;
149 struct FakeDecoderBuffer
{
151 ~FakeDecoderBuffer();
156 // Presentation timestamp.
162 MediaClockDeviceFake
* const media_clock_device_
;
167 // Indicate whether the end of stream has been received.
170 // Media time of the last rendered audio sample.
171 base::TimeDelta rendering_time_
;
173 // Frame decoded/rendered since the pipeline left the idle state.
174 uint64 decoded_frame_count_
;
175 uint64 decoded_byte_count_
;
177 // List of frames not rendered yet.
178 std::list
<FakeDecoderBuffer
> frames_
;
180 // Indicate whether there is a scheduled rendering task.
181 bool scheduled_rendering_task_
;
184 scoped_refptr
<DecoderBufferBase
> pending_buffer_
;
185 FrameStatusCB frame_pushed_cb_
;
187 base::WeakPtr
<MediaComponentDeviceFake
> weak_this_
;
188 base::WeakPtrFactory
<MediaComponentDeviceFake
> weak_factory_
;
190 DISALLOW_COPY_AND_ASSIGN(MediaComponentDeviceFake
);
193 MediaComponentDeviceFake::FakeDecoderBuffer::FakeDecoderBuffer()
197 MediaComponentDeviceFake::FakeDecoderBuffer::~FakeDecoderBuffer() {
200 MediaComponentDeviceFake::MediaComponentDeviceFake(
201 MediaClockDeviceFake
* media_clock_device
)
202 : media_clock_device_(media_clock_device
),
203 state_(kStateUninitialized
),
204 rendering_time_(::media::kNoTimestamp()),
205 decoded_frame_count_(0),
206 decoded_byte_count_(0),
207 scheduled_rendering_task_(false),
208 weak_factory_(this) {
209 weak_this_
= weak_factory_
.GetWeakPtr();
213 MediaComponentDeviceFake::~MediaComponentDeviceFake() {
216 void MediaComponentDeviceFake::SetClient(const Client
& client
) {
217 DCHECK(CalledOnValidThread());
221 MediaComponentDevice::State
MediaComponentDeviceFake::GetState() const {
222 DCHECK(CalledOnValidThread());
226 bool MediaComponentDeviceFake::SetState(State new_state
) {
227 DCHECK(CalledOnValidThread());
228 if (!MediaComponentDevice::IsValidStateTransition(state_
, new_state
))
232 if (state_
== kStateIdle
) {
233 // Back to the idle state: reset a bunch of parameters.
235 rendering_time_
= ::media::kNoTimestamp();
236 decoded_frame_count_
= 0;
237 decoded_byte_count_
= 0;
239 pending_buffer_
= scoped_refptr
<DecoderBufferBase
>();
240 frame_pushed_cb_
.Reset();
244 if (state_
== kStateRunning
) {
245 if (!scheduled_rendering_task_
) {
246 scheduled_rendering_task_
= true;
247 base::MessageLoopProxy::current()->PostTask(
249 base::Bind(&MediaComponentDeviceFake::RenderTask
, weak_this_
));
257 bool MediaComponentDeviceFake::SetStartPts(base::TimeDelta time
) {
258 DCHECK(CalledOnValidThread());
259 DCHECK_EQ(state_
, kStateIdle
);
260 rendering_time_
= time
;
264 MediaComponentDevice::FrameStatus
MediaComponentDeviceFake::PushFrame(
265 const scoped_refptr
<DecryptContext
>& decrypt_context
,
266 const scoped_refptr
<DecoderBufferBase
>& buffer
,
267 const FrameStatusCB
& completion_cb
) {
268 DCHECK(CalledOnValidThread());
269 DCHECK(state_
== kStatePaused
|| state_
== kStateRunning
);
271 DCHECK(!pending_buffer_
.get());
272 DCHECK(buffer
.get());
274 if (buffer
->end_of_stream()) {
276 return kFrameSuccess
;
279 if (frames_
.size() > kMaxFrameCount
) {
280 pending_buffer_
= buffer
;
281 frame_pushed_cb_
= completion_cb
;
282 return kFramePending
;
285 FakeDecoderBuffer fake_buffer
;
286 fake_buffer
.size
= buffer
->data_size();
287 fake_buffer
.pts
= buffer
->timestamp();
288 frames_
.push_back(fake_buffer
);
289 return kFrameSuccess
;
292 base::TimeDelta
MediaComponentDeviceFake::GetRenderingTime() const {
293 return rendering_time_
;
296 base::TimeDelta
MediaComponentDeviceFake::GetRenderingDelay() const {
298 return ::media::kNoTimestamp();
301 void MediaComponentDeviceFake::RenderTask() {
302 scheduled_rendering_task_
= false;
304 if (state_
!= kStateRunning
)
307 base::TimeDelta media_time
= media_clock_device_
->GetTime();
308 if (media_time
== ::media::kNoTimestamp()) {
309 scheduled_rendering_task_
= true;
310 base::MessageLoopProxy::current()->PostDelayedTask(
312 base::Bind(&MediaComponentDeviceFake::RenderTask
, weak_this_
),
313 base::TimeDelta::FromMilliseconds(50));
317 while (!frames_
.empty() && frames_
.front().pts
<= media_time
) {
318 rendering_time_
= frames_
.front().pts
;
319 decoded_frame_count_
++;
320 decoded_byte_count_
+= frames_
.front().size
;
322 if (pending_buffer_
.get()) {
323 FakeDecoderBuffer fake_buffer
;
324 fake_buffer
.size
= pending_buffer_
->data_size();
325 fake_buffer
.pts
= pending_buffer_
->timestamp();
326 frames_
.push_back(fake_buffer
);
327 pending_buffer_
= scoped_refptr
<DecoderBufferBase
>();
328 base::ResetAndReturn(&frame_pushed_cb_
).Run(kFrameSuccess
);
332 if (frames_
.empty() && is_eos_
) {
333 if (!client_
.eos_cb
.is_null())
334 client_
.eos_cb
.Run();
338 scheduled_rendering_task_
= true;
339 base::MessageLoopProxy::current()->PostDelayedTask(
341 base::Bind(&MediaComponentDeviceFake::RenderTask
, weak_this_
),
342 base::TimeDelta::FromMilliseconds(50));
345 bool MediaComponentDeviceFake::GetStatistics(Statistics
* stats
) const {
346 if (state_
!= kStateRunning
)
349 // Note: what is returned here is not the number of samples but the number of
350 // frames. The value is different for audio.
351 stats
->decoded_bytes
= decoded_byte_count_
;
352 stats
->decoded_samples
= decoded_frame_count_
;
353 stats
->dropped_samples
= 0;
358 class AudioPipelineDeviceFake
: public AudioPipelineDevice
{
360 explicit AudioPipelineDeviceFake(MediaClockDeviceFake
* media_clock_device
);
361 ~AudioPipelineDeviceFake() override
;
363 // AudioPipelineDevice implementation.
364 void SetClient(const Client
& client
) override
;
365 State
GetState() const override
;
366 bool SetState(State new_state
) override
;
367 bool SetStartPts(base::TimeDelta time
) override
;
368 FrameStatus
PushFrame(
369 const scoped_refptr
<DecryptContext
>& decrypt_context
,
370 const scoped_refptr
<DecoderBufferBase
>& buffer
,
371 const FrameStatusCB
& completion_cb
) override
;
372 base::TimeDelta
GetRenderingTime() const override
;
373 base::TimeDelta
GetRenderingDelay() const override
;
374 bool SetConfig(const ::media::AudioDecoderConfig
& config
) override
;
375 void SetStreamVolumeMultiplier(float multiplier
) override
;
376 bool GetStatistics(Statistics
* stats
) const override
;
379 scoped_ptr
<MediaComponentDeviceFake
> fake_pipeline_
;
381 ::media::AudioDecoderConfig config_
;
383 DISALLOW_COPY_AND_ASSIGN(AudioPipelineDeviceFake
);
386 AudioPipelineDeviceFake::AudioPipelineDeviceFake(
387 MediaClockDeviceFake
* media_clock_device
)
388 : fake_pipeline_(new MediaComponentDeviceFake(media_clock_device
)) {
392 AudioPipelineDeviceFake::~AudioPipelineDeviceFake() {
395 void AudioPipelineDeviceFake::SetClient(const Client
& client
) {
396 fake_pipeline_
->SetClient(client
);
399 MediaComponentDevice::State
AudioPipelineDeviceFake::GetState() const {
400 return fake_pipeline_
->GetState();
403 bool AudioPipelineDeviceFake::SetState(State new_state
) {
404 bool success
= fake_pipeline_
->SetState(new_state
);
408 if (new_state
== kStateIdle
) {
409 DCHECK(config_
.IsValidConfig());
411 if (new_state
== kStateUninitialized
) {
412 config_
= ::media::AudioDecoderConfig();
417 bool AudioPipelineDeviceFake::SetStartPts(base::TimeDelta time
) {
418 return fake_pipeline_
->SetStartPts(time
);
421 MediaComponentDevice::FrameStatus
AudioPipelineDeviceFake::PushFrame(
422 const scoped_refptr
<DecryptContext
>& decrypt_context
,
423 const scoped_refptr
<DecoderBufferBase
>& buffer
,
424 const FrameStatusCB
& completion_cb
) {
425 return fake_pipeline_
->PushFrame(decrypt_context
, buffer
, completion_cb
);
428 base::TimeDelta
AudioPipelineDeviceFake::GetRenderingTime() const {
429 return fake_pipeline_
->GetRenderingTime();
432 base::TimeDelta
AudioPipelineDeviceFake::GetRenderingDelay() const {
433 return fake_pipeline_
->GetRenderingDelay();
436 bool AudioPipelineDeviceFake::SetConfig(
437 const ::media::AudioDecoderConfig
& config
) {
438 DCHECK(CalledOnValidThread());
439 if (!config
.IsValidConfig())
445 void AudioPipelineDeviceFake::SetStreamVolumeMultiplier(float multiplier
) {
446 DCHECK(CalledOnValidThread());
449 bool AudioPipelineDeviceFake::GetStatistics(Statistics
* stats
) const {
450 return fake_pipeline_
->GetStatistics(stats
);
454 class VideoPipelineDeviceFake
: public VideoPipelineDevice
{
456 explicit VideoPipelineDeviceFake(MediaClockDeviceFake
* media_clock_device
);
457 ~VideoPipelineDeviceFake() override
;
459 // VideoPipelineDevice implementation.
460 void SetClient(const Client
& client
) override
;
461 State
GetState() const override
;
462 bool SetState(State new_state
) override
;
463 bool SetStartPts(base::TimeDelta time
) override
;
464 FrameStatus
PushFrame(
465 const scoped_refptr
<DecryptContext
>& decrypt_context
,
466 const scoped_refptr
<DecoderBufferBase
>& buffer
,
467 const FrameStatusCB
& completion_cb
) override
;
468 base::TimeDelta
GetRenderingTime() const override
;
469 base::TimeDelta
GetRenderingDelay() const override
;
470 void SetVideoClient(const VideoClient
& client
) override
;
471 bool SetConfig(const ::media::VideoDecoderConfig
& config
) override
;
472 bool GetStatistics(Statistics
* stats
) const override
;
475 scoped_ptr
<MediaComponentDeviceFake
> fake_pipeline_
;
477 ::media::VideoDecoderConfig config_
;
479 DISALLOW_COPY_AND_ASSIGN(VideoPipelineDeviceFake
);
482 VideoPipelineDeviceFake::VideoPipelineDeviceFake(
483 MediaClockDeviceFake
* media_clock_device
)
484 : fake_pipeline_(new MediaComponentDeviceFake(media_clock_device
)) {
488 VideoPipelineDeviceFake::~VideoPipelineDeviceFake() {
491 void VideoPipelineDeviceFake::SetClient(const Client
& client
) {
492 fake_pipeline_
->SetClient(client
);
495 MediaComponentDevice::State
VideoPipelineDeviceFake::GetState() const {
496 return fake_pipeline_
->GetState();
499 bool VideoPipelineDeviceFake::SetState(State new_state
) {
500 bool success
= fake_pipeline_
->SetState(new_state
);
504 if (new_state
== kStateIdle
) {
505 DCHECK(config_
.IsValidConfig());
507 if (new_state
== kStateUninitialized
) {
508 config_
= ::media::VideoDecoderConfig();
513 bool VideoPipelineDeviceFake::SetStartPts(base::TimeDelta time
) {
514 return fake_pipeline_
->SetStartPts(time
);
517 MediaComponentDevice::FrameStatus
VideoPipelineDeviceFake::PushFrame(
518 const scoped_refptr
<DecryptContext
>& decrypt_context
,
519 const scoped_refptr
<DecoderBufferBase
>& buffer
,
520 const FrameStatusCB
& completion_cb
) {
521 return fake_pipeline_
->PushFrame(decrypt_context
, buffer
, completion_cb
);
524 base::TimeDelta
VideoPipelineDeviceFake::GetRenderingTime() const {
525 return fake_pipeline_
->GetRenderingTime();
528 base::TimeDelta
VideoPipelineDeviceFake::GetRenderingDelay() const {
529 return fake_pipeline_
->GetRenderingDelay();
532 void VideoPipelineDeviceFake::SetVideoClient(const VideoClient
& client
) {
535 bool VideoPipelineDeviceFake::SetConfig(
536 const ::media::VideoDecoderConfig
& config
) {
537 DCHECK(CalledOnValidThread());
538 if (!config
.IsValidConfig())
544 bool VideoPipelineDeviceFake::GetStatistics(Statistics
* stats
) const {
545 return fake_pipeline_
->GetStatistics(stats
);
549 MediaPipelineDeviceFake::MediaPipelineDeviceFake()
550 : media_clock_device_(new MediaClockDeviceFake()),
551 audio_pipeline_device_(
552 new AudioPipelineDeviceFake(media_clock_device_
.get())),
553 video_pipeline_device_(
554 new VideoPipelineDeviceFake(media_clock_device_
.get())) {
557 MediaPipelineDeviceFake::~MediaPipelineDeviceFake() {
560 AudioPipelineDevice
* MediaPipelineDeviceFake::GetAudioPipelineDevice() const {
561 return audio_pipeline_device_
.get();
564 VideoPipelineDevice
* MediaPipelineDeviceFake::GetVideoPipelineDevice() const {
565 return video_pipeline_device_
.get();
568 MediaClockDevice
* MediaPipelineDeviceFake::GetMediaClockDevice() const {
569 return media_clock_device_
.get();
573 } // namespace chromecast