OLD | NEW |
---|---|
(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/media/cma/backend/media_pipeline_device_fake.h" | |
6 | |
7 #include <list> | |
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/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" | |
23 | |
24 namespace chromecast { | |
25 namespace media { | |
26 | |
27 class MediaClockDeviceFake : public MediaClockDevice { | |
28 public: | |
29 MediaClockDeviceFake(); | |
30 virtual ~MediaClockDeviceFake(); | |
31 | |
32 // MediaClockDevice implementation. | |
33 virtual State GetState() const OVERRIDE; | |
34 virtual bool SetState(State new_state) OVERRIDE; | |
35 virtual bool ResetTimeline(base::TimeDelta time) OVERRIDE; | |
36 virtual bool SetRate(float rate) OVERRIDE; | |
37 virtual base::TimeDelta GetTime() OVERRIDE; | |
damienv1
2014/10/06 17:00:23
Replace OVERRIDE with override everywhere in this
| |
38 | |
39 private: | |
40 State state_; | |
41 | |
42 // Media time sampled at STC time |stc_|. | |
43 base::TimeDelta media_time_; | |
44 base::TimeTicks stc_; | |
45 | |
46 float rate_; | |
47 | |
48 DISALLOW_COPY_AND_ASSIGN(MediaClockDeviceFake); | |
49 }; | |
50 | |
51 MediaClockDeviceFake::MediaClockDeviceFake() | |
52 : state_(kStateUninitialized), | |
53 media_time_(::media::kNoTimestamp()) { | |
54 DetachFromThread(); | |
55 } | |
56 | |
57 MediaClockDeviceFake::~MediaClockDeviceFake() { | |
58 } | |
59 | |
60 MediaClockDevice::State MediaClockDeviceFake::GetState() const { | |
61 DCHECK(CalledOnValidThread()); | |
62 return state_; | |
63 } | |
64 | |
65 bool MediaClockDeviceFake::SetState(State new_state) { | |
66 DCHECK(CalledOnValidThread()); | |
67 if (!MediaClockDevice::IsValidStateTransition(state_, new_state)) | |
68 return false; | |
69 | |
70 if (new_state == state_) | |
71 return true; | |
72 | |
73 state_ = new_state; | |
74 | |
75 if (state_ == kStateRunning) { | |
76 stc_ = base::TimeTicks::Now(); | |
77 DCHECK(media_time_ != ::media::kNoTimestamp()); | |
78 return true; | |
79 } | |
80 | |
81 if (state_ == kStateIdle) { | |
82 media_time_ = ::media::kNoTimestamp(); | |
83 return true; | |
84 } | |
85 | |
86 return true; | |
87 } | |
88 | |
89 bool MediaClockDeviceFake::ResetTimeline(base::TimeDelta time) { | |
90 DCHECK(CalledOnValidThread()); | |
91 DCHECK_EQ(state_, kStateIdle); | |
92 media_time_ = time; | |
93 return true; | |
94 } | |
95 | |
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_; | |
101 stc_ = now; | |
102 } | |
103 | |
104 rate_ = rate; | |
105 return true; | |
106 } | |
107 | |
108 base::TimeDelta MediaClockDeviceFake::GetTime() { | |
109 DCHECK(CalledOnValidThread()); | |
110 if (state_ != kStateRunning) | |
111 return media_time_; | |
112 | |
113 if (media_time_ == ::media::kNoTimestamp()) | |
114 return ::media::kNoTimestamp(); | |
115 | |
116 base::TimeTicks now = base::TimeTicks::Now(); | |
117 base::TimeDelta interpolated_media_time = | |
118 media_time_ + (now - stc_) * rate_; | |
119 return interpolated_media_time; | |
120 } | |
121 | |
122 | |
123 namespace { | |
124 | |
125 // Maximum number of frames that can be buffered. | |
126 const size_t kMaxFrameCount = 20; | |
127 | |
128 } // namespace | |
129 | |
130 class MediaComponentDeviceFake : public MediaComponentDevice { | |
131 public: | |
132 explicit MediaComponentDeviceFake(MediaClockDeviceFake* media_clock_device); | |
133 virtual ~MediaComponentDeviceFake(); | |
134 | |
135 // MediaComponentDevice implementation. | |
136 virtual void SetClient(const Client& client) OVERRIDE; | |
137 virtual State GetState() const OVERRIDE; | |
138 virtual bool SetState(State new_state) OVERRIDE; | |
139 virtual bool SetStartPts(base::TimeDelta time) OVERRIDE; | |
140 virtual FrameStatus PushFrame( | |
141 const scoped_refptr<DecryptContext>& decrypt_context, | |
142 const scoped_refptr<DecoderBufferBase>& buffer, | |
143 const FrameStatusCB& completion_cb) OVERRIDE; | |
144 virtual base::TimeDelta GetRenderingTime() const OVERRIDE; | |
145 virtual base::TimeDelta GetRenderingDelay() const OVERRIDE; | |
146 virtual bool GetStatistics(Statistics* stats) const OVERRIDE; | |
147 | |
148 private: | |
149 struct FakeDecoderBuffer { | |
150 FakeDecoderBuffer(); | |
151 ~FakeDecoderBuffer(); | |
152 | |
153 // Buffer size. | |
154 size_t size; | |
155 | |
156 // Presentation timestamp. | |
157 base::TimeDelta pts; | |
158 }; | |
159 | |
160 void RenderTask(); | |
161 | |
162 MediaClockDeviceFake* const media_clock_device_; | |
163 Client client_; | |
164 | |
165 State state_; | |
166 | |
167 // Indicate whether the end of stream has been received. | |
168 bool is_eos_; | |
169 | |
170 // Media time of the last rendered audio sample. | |
171 base::TimeDelta rendering_time_; | |
172 | |
173 // Frame decoded/rendered since the pipeline left the idle state. | |
174 uint64 decoded_frame_count_; | |
175 uint64 decoded_byte_count_; | |
176 | |
177 // List of frames not rendered yet. | |
178 std::list<FakeDecoderBuffer> frames_; | |
179 | |
180 // Indicate whether there is a scheduled rendering task. | |
181 bool scheduled_rendering_task_; | |
182 | |
183 // Pending frame. | |
184 scoped_refptr<DecoderBufferBase> pending_buffer_; | |
185 FrameStatusCB frame_pushed_cb_; | |
186 | |
187 base::WeakPtr<MediaComponentDeviceFake> weak_this_; | |
188 base::WeakPtrFactory<MediaComponentDeviceFake> weak_factory_; | |
189 | |
190 DISALLOW_COPY_AND_ASSIGN(MediaComponentDeviceFake); | |
191 }; | |
192 | |
193 MediaComponentDeviceFake::FakeDecoderBuffer::FakeDecoderBuffer() | |
194 : size(0) { | |
195 } | |
196 | |
197 MediaComponentDeviceFake::FakeDecoderBuffer::~FakeDecoderBuffer() { | |
198 } | |
199 | |
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(); | |
210 DetachFromThread(); | |
211 } | |
212 | |
213 MediaComponentDeviceFake::~MediaComponentDeviceFake() { | |
214 } | |
215 | |
216 void MediaComponentDeviceFake::SetClient(const Client& client) { | |
217 DCHECK(CalledOnValidThread()); | |
218 client_ = client; | |
219 } | |
220 | |
221 MediaComponentDevice::State MediaComponentDeviceFake::GetState() const { | |
222 DCHECK(CalledOnValidThread()); | |
223 return state_; | |
224 } | |
225 | |
226 bool MediaComponentDeviceFake::SetState(State new_state) { | |
227 DCHECK(CalledOnValidThread()); | |
228 if (!MediaComponentDevice::IsValidStateTransition(state_, new_state)) | |
229 return false; | |
230 state_ = new_state; | |
231 | |
232 if (state_ == kStateIdle) { | |
233 // Back to the idle state: reset a bunch of parameters. | |
234 is_eos_ = false; | |
235 rendering_time_ = ::media::kNoTimestamp(); | |
236 decoded_frame_count_ = 0; | |
237 decoded_byte_count_ = 0; | |
238 frames_.clear(); | |
239 pending_buffer_ = scoped_refptr<DecoderBufferBase>(); | |
240 frame_pushed_cb_.Reset(); | |
241 return true; | |
242 } | |
243 | |
244 if (state_ == kStateRunning) { | |
245 if (!scheduled_rendering_task_) { | |
246 scheduled_rendering_task_ = true; | |
247 base::MessageLoopProxy::current()->PostTask( | |
248 FROM_HERE, | |
249 base::Bind(&MediaComponentDeviceFake::RenderTask, weak_this_)); | |
250 } | |
251 return true; | |
252 } | |
253 | |
254 return true; | |
255 } | |
256 | |
257 bool MediaComponentDeviceFake::SetStartPts(base::TimeDelta time) { | |
258 DCHECK(CalledOnValidThread()); | |
259 DCHECK_EQ(state_, kStateIdle); | |
260 rendering_time_ = time; | |
261 return true; | |
262 } | |
263 | |
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); | |
270 DCHECK(!is_eos_); | |
271 DCHECK(!pending_buffer_.get()); | |
272 DCHECK(buffer.get()); | |
273 | |
274 if (buffer->end_of_stream()) { | |
275 is_eos_ = true; | |
276 return kFrameSuccess; | |
277 } | |
278 | |
279 if (frames_.size() > kMaxFrameCount) { | |
280 pending_buffer_ = buffer; | |
281 frame_pushed_cb_ = completion_cb; | |
282 return kFramePending; | |
283 } | |
284 | |
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; | |
290 } | |
291 | |
292 base::TimeDelta MediaComponentDeviceFake::GetRenderingTime() const { | |
293 return rendering_time_; | |
294 } | |
295 | |
296 base::TimeDelta MediaComponentDeviceFake::GetRenderingDelay() const { | |
297 NOTIMPLEMENTED(); | |
298 return ::media::kNoTimestamp(); | |
299 } | |
300 | |
301 void MediaComponentDeviceFake::RenderTask() { | |
302 scheduled_rendering_task_ = false; | |
303 | |
304 if (state_ != kStateRunning) | |
305 return; | |
306 | |
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( | |
311 FROM_HERE, | |
312 base::Bind(&MediaComponentDeviceFake::RenderTask, weak_this_), | |
313 base::TimeDelta::FromMilliseconds(50)); | |
314 return; | |
315 } | |
316 | |
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; | |
321 frames_.pop_front(); | |
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); | |
329 } | |
330 } | |
331 | |
332 if (frames_.empty() && is_eos_) { | |
333 if (!client_.eos_cb.is_null()) | |
334 client_.eos_cb.Run(); | |
335 return; | |
336 } | |
337 | |
338 scheduled_rendering_task_ = true; | |
339 base::MessageLoopProxy::current()->PostDelayedTask( | |
340 FROM_HERE, | |
341 base::Bind(&MediaComponentDeviceFake::RenderTask, weak_this_), | |
342 base::TimeDelta::FromMilliseconds(50)); | |
343 } | |
344 | |
345 bool MediaComponentDeviceFake::GetStatistics(Statistics* stats) const { | |
346 if (state_ != kStateRunning) | |
347 return false; | |
348 | |
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; | |
354 return true; | |
355 } | |
356 | |
357 | |
358 class AudioPipelineDeviceFake : public AudioPipelineDevice { | |
359 public: | |
360 explicit AudioPipelineDeviceFake(MediaClockDeviceFake* media_clock_device); | |
361 virtual ~AudioPipelineDeviceFake(); | |
362 | |
363 // AudioPipelineDevice implementation. | |
364 virtual void SetClient(const Client& client) OVERRIDE; | |
365 virtual State GetState() const OVERRIDE; | |
366 virtual bool SetState(State new_state) OVERRIDE; | |
367 virtual bool SetStartPts(base::TimeDelta time) OVERRIDE; | |
368 virtual FrameStatus PushFrame( | |
369 const scoped_refptr<DecryptContext>& decrypt_context, | |
370 const scoped_refptr<DecoderBufferBase>& buffer, | |
371 const FrameStatusCB& completion_cb) OVERRIDE; | |
372 virtual base::TimeDelta GetRenderingTime() const OVERRIDE; | |
373 virtual base::TimeDelta GetRenderingDelay() const OVERRIDE; | |
374 virtual bool SetConfig(const ::media::AudioDecoderConfig& config) OVERRIDE; | |
375 virtual void SetStreamVolumeMultiplier(float multiplier) OVERRIDE; | |
376 virtual bool GetStatistics(Statistics* stats) const OVERRIDE; | |
377 | |
378 private: | |
379 scoped_ptr<MediaComponentDeviceFake> fake_pipeline_; | |
380 | |
381 ::media::AudioDecoderConfig config_; | |
382 | |
383 DISALLOW_COPY_AND_ASSIGN(AudioPipelineDeviceFake); | |
384 }; | |
385 | |
386 AudioPipelineDeviceFake::AudioPipelineDeviceFake( | |
387 MediaClockDeviceFake* media_clock_device) | |
388 : fake_pipeline_(new MediaComponentDeviceFake(media_clock_device)) { | |
389 DetachFromThread(); | |
390 } | |
391 | |
392 AudioPipelineDeviceFake::~AudioPipelineDeviceFake() { | |
393 } | |
394 | |
395 void AudioPipelineDeviceFake::SetClient(const Client& client) { | |
396 fake_pipeline_->SetClient(client); | |
397 } | |
398 | |
399 MediaComponentDevice::State AudioPipelineDeviceFake::GetState() const { | |
400 return fake_pipeline_->GetState(); | |
401 } | |
402 | |
403 bool AudioPipelineDeviceFake::SetState(State new_state) { | |
404 bool success = fake_pipeline_->SetState(new_state); | |
405 if (!success) | |
406 return false; | |
407 | |
408 if (new_state == kStateIdle) { | |
409 DCHECK(config_.IsValidConfig()); | |
410 } | |
411 if (new_state == kStateUninitialized) { | |
412 config_ = ::media::AudioDecoderConfig(); | |
413 } | |
414 return true; | |
415 } | |
416 | |
417 bool AudioPipelineDeviceFake::SetStartPts(base::TimeDelta time) { | |
418 return fake_pipeline_->SetStartPts(time); | |
419 } | |
420 | |
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); | |
426 } | |
427 | |
428 base::TimeDelta AudioPipelineDeviceFake::GetRenderingTime() const { | |
429 return fake_pipeline_->GetRenderingTime(); | |
430 } | |
431 | |
432 base::TimeDelta AudioPipelineDeviceFake::GetRenderingDelay() const { | |
433 return fake_pipeline_->GetRenderingDelay(); | |
434 } | |
435 | |
436 bool AudioPipelineDeviceFake::SetConfig( | |
437 const ::media::AudioDecoderConfig& config) { | |
438 DCHECK(CalledOnValidThread()); | |
439 if (!config.IsValidConfig()) | |
440 return false; | |
441 config_ = config; | |
442 return true; | |
443 } | |
444 | |
445 void AudioPipelineDeviceFake::SetStreamVolumeMultiplier(float multiplier) { | |
446 DCHECK(CalledOnValidThread()); | |
447 } | |
448 | |
449 bool AudioPipelineDeviceFake::GetStatistics(Statistics* stats) const { | |
450 return fake_pipeline_->GetStatistics(stats); | |
451 } | |
452 | |
453 | |
454 class VideoPipelineDeviceFake : public VideoPipelineDevice { | |
455 public: | |
456 explicit VideoPipelineDeviceFake(MediaClockDeviceFake* media_clock_device); | |
457 virtual ~VideoPipelineDeviceFake(); | |
458 | |
459 // VideoPipelineDevice implementation. | |
460 virtual void SetClient(const Client& client) OVERRIDE; | |
461 virtual State GetState() const OVERRIDE; | |
462 virtual bool SetState(State new_state) OVERRIDE; | |
463 virtual bool SetStartPts(base::TimeDelta time) OVERRIDE; | |
464 virtual FrameStatus PushFrame( | |
465 const scoped_refptr<DecryptContext>& decrypt_context, | |
466 const scoped_refptr<DecoderBufferBase>& buffer, | |
467 const FrameStatusCB& completion_cb) OVERRIDE; | |
468 virtual base::TimeDelta GetRenderingTime() const OVERRIDE; | |
469 virtual base::TimeDelta GetRenderingDelay() const OVERRIDE; | |
470 virtual void SetVideoClient(const VideoClient& client) OVERRIDE; | |
471 virtual bool SetConfig(const ::media::VideoDecoderConfig& config) OVERRIDE; | |
472 virtual bool GetStatistics(Statistics* stats) const OVERRIDE; | |
473 | |
474 private: | |
475 scoped_ptr<MediaComponentDeviceFake> fake_pipeline_; | |
476 | |
477 ::media::VideoDecoderConfig config_; | |
478 | |
479 DISALLOW_COPY_AND_ASSIGN(VideoPipelineDeviceFake); | |
480 }; | |
481 | |
482 VideoPipelineDeviceFake::VideoPipelineDeviceFake( | |
483 MediaClockDeviceFake* media_clock_device) | |
484 : fake_pipeline_(new MediaComponentDeviceFake(media_clock_device)) { | |
485 DetachFromThread(); | |
486 } | |
487 | |
488 VideoPipelineDeviceFake::~VideoPipelineDeviceFake() { | |
489 } | |
490 | |
491 void VideoPipelineDeviceFake::SetClient(const Client& client) { | |
492 fake_pipeline_->SetClient(client); | |
493 } | |
494 | |
495 MediaComponentDevice::State VideoPipelineDeviceFake::GetState() const { | |
496 return fake_pipeline_->GetState(); | |
497 } | |
498 | |
499 bool VideoPipelineDeviceFake::SetState(State new_state) { | |
500 bool success = fake_pipeline_->SetState(new_state); | |
501 if (!success) | |
502 return false; | |
503 | |
504 if (new_state == kStateIdle) { | |
505 DCHECK(config_.IsValidConfig()); | |
506 } | |
507 if (new_state == kStateUninitialized) { | |
508 config_ = ::media::VideoDecoderConfig(); | |
509 } | |
510 return true; | |
511 } | |
512 | |
513 bool VideoPipelineDeviceFake::SetStartPts(base::TimeDelta time) { | |
514 return fake_pipeline_->SetStartPts(time); | |
515 } | |
516 | |
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); | |
522 } | |
523 | |
524 base::TimeDelta VideoPipelineDeviceFake::GetRenderingTime() const { | |
525 return fake_pipeline_->GetRenderingTime(); | |
526 } | |
527 | |
528 base::TimeDelta VideoPipelineDeviceFake::GetRenderingDelay() const { | |
529 return fake_pipeline_->GetRenderingDelay(); | |
530 } | |
531 | |
532 void VideoPipelineDeviceFake::SetVideoClient(const VideoClient& client) { | |
533 } | |
534 | |
535 bool VideoPipelineDeviceFake::SetConfig( | |
536 const ::media::VideoDecoderConfig& config) { | |
537 DCHECK(CalledOnValidThread()); | |
538 if (!config.IsValidConfig()) | |
539 return false; | |
540 config_ = config; | |
541 return true; | |
542 } | |
543 | |
544 bool VideoPipelineDeviceFake::GetStatistics(Statistics* stats) const { | |
545 return fake_pipeline_->GetStatistics(stats); | |
546 } | |
547 | |
548 | |
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())) { | |
555 } | |
556 | |
557 MediaPipelineDeviceFake::~MediaPipelineDeviceFake() { | |
558 } | |
559 | |
560 AudioPipelineDevice* MediaPipelineDeviceFake::GetAudioPipelineDevice() const { | |
561 return audio_pipeline_device_.get(); | |
562 } | |
563 | |
564 VideoPipelineDevice* MediaPipelineDeviceFake::GetVideoPipelineDevice() const { | |
565 return video_pipeline_device_.get(); | |
566 } | |
567 | |
568 MediaClockDevice* MediaPipelineDeviceFake::GetMediaClockDevice() const { | |
569 return media_clock_device_.get(); | |
570 } | |
571 | |
572 } // namespace media | |
573 } // namespace chromecast | |
OLD | NEW |