Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromecast / media / cma / pipeline / av_pipeline_impl.cc
blobae31b3a37923872bd6bfc372167e8fc8bff0e17b
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/pipeline/av_pipeline_impl.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "chromecast/media/base/decrypt_context_impl.h"
13 #include "chromecast/media/cdm/browser_cdm_cast.h"
14 #include "chromecast/media/cma/base/buffering_frame_provider.h"
15 #include "chromecast/media/cma/base/buffering_state.h"
16 #include "chromecast/media/cma/base/cast_decoder_buffer_impl.h"
17 #include "chromecast/media/cma/base/cma_logging.h"
18 #include "chromecast/media/cma/base/coded_frame_provider.h"
19 #include "chromecast/media/cma/base/decoder_buffer_base.h"
20 #include "chromecast/media/cma/pipeline/decrypt_util.h"
21 #include "chromecast/media/cma/pipeline/frame_status_cb_impl.h"
22 #include "chromecast/media/cma/pipeline/media_component_device_client_impl.h"
23 #include "chromecast/public/media/cast_decrypt_config.h"
24 #include "chromecast/public/media/media_clock_device.h"
25 #include "chromecast/public/media/media_component_device.h"
26 #include "media/base/audio_decoder_config.h"
27 #include "media/base/bind_to_current_loop.h"
28 #include "media/base/decrypt_config.h"
29 #include "media/base/timestamp_constants.h"
31 namespace chromecast {
32 namespace media {
34 namespace {
36 const int kNoCallbackId = -1;
38 } // namespace
40 AvPipelineImpl::AvPipelineImpl(MediaComponentDevice* media_component_device,
41 const UpdateConfigCB& update_config_cb)
42 : update_config_cb_(update_config_cb),
43 media_component_device_(media_component_device),
44 state_(kUninitialized),
45 buffered_time_(::media::kNoTimestamp()),
46 playable_buffered_time_(::media::kNoTimestamp()),
47 enable_feeding_(false),
48 pending_read_(false),
49 pending_push_(false),
50 enable_time_update_(false),
51 pending_time_update_task_(false),
52 media_keys_(NULL),
53 media_keys_callback_id_(kNoCallbackId),
54 weak_factory_(this) {
55 DCHECK(media_component_device);
56 weak_this_ = weak_factory_.GetWeakPtr();
57 thread_checker_.DetachFromThread();
60 AvPipelineImpl::~AvPipelineImpl() {
61 DCHECK(thread_checker_.CalledOnValidThread());
62 media_component_device_->SetClient(nullptr);
64 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId)
65 media_keys_->UnregisterPlayer(media_keys_callback_id_);
68 void AvPipelineImpl::TransitionToState(State state) {
69 DCHECK(thread_checker_.CalledOnValidThread());
70 state_ = state;
73 void AvPipelineImpl::SetCodedFrameProvider(
74 scoped_ptr<CodedFrameProvider> frame_provider,
75 size_t max_buffer_size,
76 size_t max_frame_size) {
77 DCHECK_EQ(state_, kUninitialized);
78 DCHECK(frame_provider);
80 // Wrap the incoming frame provider to add some buffering capabilities.
81 frame_provider_.reset(
82 new BufferingFrameProvider(
83 frame_provider.Pass(),
84 max_buffer_size,
85 max_frame_size,
86 base::Bind(&AvPipelineImpl::OnFrameBuffered, weak_this_)));
89 void AvPipelineImpl::SetClient(const AvPipelineClient& client) {
90 DCHECK(thread_checker_.CalledOnValidThread());
91 DCHECK_EQ(state_, kUninitialized);
92 client_ = client;
95 bool AvPipelineImpl::Initialize() {
96 DCHECK(thread_checker_.CalledOnValidThread());
97 DCHECK_EQ(state_, kUninitialized);
99 media_component_device_->SetClient(new MediaComponentDeviceClientImpl(
100 base::Bind(&AvPipelineImpl::OnEos, weak_this_)));
101 if (!media_component_device_->SetState(MediaComponentDevice::kStateIdle))
102 return false;
104 return true;
107 bool AvPipelineImpl::StartPlayingFrom(
108 base::TimeDelta time,
109 const scoped_refptr<BufferingState>& buffering_state) {
110 DCHECK(thread_checker_.CalledOnValidThread());
111 DCHECK_EQ(state_, kFlushed);
113 // Media time where rendering should start
114 // and switch to a state where the audio device accepts incoming buffers.
115 if (!media_component_device_->SetStartPts(time.InMicroseconds()) ||
116 !media_component_device_->SetState(MediaComponentDevice::kStatePaused)) {
117 return false;
120 // Buffering related initialization.
121 DCHECK(frame_provider_);
122 buffering_state_ = buffering_state;
123 if (buffering_state_.get())
124 buffering_state_->SetMediaTime(time);
126 if (!media_component_device_->SetState(MediaComponentDevice::kStateRunning))
127 return false;
129 // Start feeding the pipeline.
130 enable_feeding_ = true;
131 base::ThreadTaskRunnerHandle::Get()->PostTask(
132 FROM_HERE, base::Bind(&AvPipelineImpl::FetchBufferIfNeeded, weak_this_));
134 return true;
137 void AvPipelineImpl::Flush(const base::Closure& done_cb) {
138 DCHECK(thread_checker_.CalledOnValidThread());
139 DCHECK_EQ(state_, kFlushing);
140 DCHECK_EQ(
141 media_component_device_->GetState(), MediaComponentDevice::kStateRunning);
142 // Note: returning to idle state aborts any pending frame push.
143 media_component_device_->SetState(MediaComponentDevice::kStateIdle);
144 pending_push_ = false;
146 // Break the feeding loop.
147 enable_feeding_ = false;
149 // Remove any pending buffer.
150 pending_buffer_ = scoped_refptr<DecoderBufferBase>();
152 // Finally, remove any frames left in the frame provider.
153 pending_read_ = false;
154 buffered_time_ = ::media::kNoTimestamp();
155 playable_buffered_time_ = ::media::kNoTimestamp();
156 non_playable_frames_.clear();
157 frame_provider_->Flush(done_cb);
160 void AvPipelineImpl::Stop() {
161 DCHECK(thread_checker_.CalledOnValidThread());
163 // Stop can be called from any state.
164 if (state_ == kUninitialized || state_ == kStopped)
165 return;
167 // Stop feeding the pipeline.
168 enable_feeding_ = false;
170 // Release hardware resources on Stop.
171 if (media_component_device_->GetState() ==
172 MediaComponentDevice::kStatePaused ||
173 media_component_device_->GetState() ==
174 MediaComponentDevice::kStateRunning) {
175 media_component_device_->SetState(MediaComponentDevice::kStateIdle);
177 if (media_component_device_->GetState() == MediaComponentDevice::kStateIdle) {
178 media_component_device_->SetState(
179 MediaComponentDevice::kStateUninitialized);
183 void AvPipelineImpl::SetCdm(BrowserCdmCast* media_keys) {
184 DCHECK(thread_checker_.CalledOnValidThread());
185 DCHECK(media_keys);
187 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId)
188 media_keys_->UnregisterPlayer(media_keys_callback_id_);
190 media_keys_ = media_keys;
191 media_keys_callback_id_ = media_keys_->RegisterPlayer(
192 base::Bind(&AvPipelineImpl::OnCdmStateChanged, weak_this_),
193 base::Bind(&AvPipelineImpl::OnCdmDestroyed, weak_this_));
196 void AvPipelineImpl::OnEos() {
197 DCHECK(thread_checker_.CalledOnValidThread());
198 CMALOG(kLogControl) << __FUNCTION__;
199 if (state_ != kPlaying)
200 return;
202 if (!client_.eos_cb.is_null())
203 client_.eos_cb.Run();
206 void AvPipelineImpl::FetchBufferIfNeeded() {
207 DCHECK(thread_checker_.CalledOnValidThread());
208 if (!enable_feeding_)
209 return;
211 if (pending_read_ || pending_buffer_.get())
212 return;
214 pending_read_ = true;
215 frame_provider_->Read(
216 base::Bind(&AvPipelineImpl::OnNewFrame, weak_this_));
219 void AvPipelineImpl::OnNewFrame(
220 const scoped_refptr<DecoderBufferBase>& buffer,
221 const ::media::AudioDecoderConfig& audio_config,
222 const ::media::VideoDecoderConfig& video_config) {
223 DCHECK(thread_checker_.CalledOnValidThread());
224 pending_read_ = false;
226 if (audio_config.IsValidConfig() || video_config.IsValidConfig())
227 update_config_cb_.Run(buffer->stream_id(), audio_config, video_config);
229 pending_buffer_ = buffer;
230 ProcessPendingBuffer();
232 base::ThreadTaskRunnerHandle::Get()->PostTask(
233 FROM_HERE, base::Bind(&AvPipelineImpl::FetchBufferIfNeeded, weak_this_));
236 void AvPipelineImpl::ProcessPendingBuffer() {
237 if (!enable_feeding_)
238 return;
240 // Initiate a read if there isn't already one.
241 if (!pending_buffer_.get() && !pending_read_) {
242 base::ThreadTaskRunnerHandle::Get()->PostTask(
243 FROM_HERE,
244 base::Bind(&AvPipelineImpl::FetchBufferIfNeeded, weak_this_));
245 return;
248 if (!pending_buffer_.get() || pending_push_)
249 return;
251 // Break the feeding loop when the end of stream is reached.
252 if (pending_buffer_->end_of_stream()) {
253 CMALOG(kLogControl) << __FUNCTION__ << ": EOS reached, stopped feeding";
254 enable_feeding_ = false;
257 scoped_ptr<DecryptContextImpl> decrypt_context;
258 if (!pending_buffer_->end_of_stream() &&
259 pending_buffer_->decrypt_config()) {
260 // Verify that CDM has the key ID.
261 // Should not send the frame if the key ID is not available yet.
262 std::string key_id(pending_buffer_->decrypt_config()->key_id());
263 if (!media_keys_) {
264 CMALOG(kLogControl) << "No CDM for frame: pts="
265 << pending_buffer_->timestamp().InMilliseconds();
266 return;
268 decrypt_context = media_keys_->GetDecryptContext(key_id);
269 if (!decrypt_context.get()) {
270 CMALOG(kLogControl) << "frame(pts="
271 << pending_buffer_->timestamp().InMilliseconds()
272 << "): waiting for key id "
273 << base::HexEncode(&key_id[0], key_id.size());
274 return;
277 // If we do have the clear key, decrypt the pending buffer
278 // and reset the decryption context (not needed anymore).
279 crypto::SymmetricKey* key = decrypt_context->GetKey();
280 if (key != NULL) {
281 pending_buffer_ = DecryptDecoderBuffer(pending_buffer_, key);
282 decrypt_context.reset();
286 if (!pending_buffer_->end_of_stream() && buffering_state_.get()) {
287 base::TimeDelta timestamp = pending_buffer_->timestamp();
288 if (timestamp != ::media::kNoTimestamp())
289 buffering_state_->SetMaxRenderingTime(timestamp);
292 MediaComponentDevice::FrameStatus status = media_component_device_->PushFrame(
293 decrypt_context.release(), new CastDecoderBufferImpl(pending_buffer_),
294 new FrameStatusCBImpl(
295 base::Bind(&AvPipelineImpl::OnFramePushed, weak_this_)));
296 pending_buffer_ = scoped_refptr<DecoderBufferBase>();
298 pending_push_ = (status == MediaComponentDevice::kFramePending);
299 if (!pending_push_)
300 OnFramePushed(status);
303 void AvPipelineImpl::OnFramePushed(MediaComponentDevice::FrameStatus status) {
304 DCHECK(thread_checker_.CalledOnValidThread());
305 pending_push_ = false;
306 if (status == MediaComponentDevice::kFrameFailed) {
307 LOG(WARNING) << "AvPipelineImpl: PushFrame failed";
308 enable_feeding_ = false;
309 state_ = kError;
310 return;
312 base::ThreadTaskRunnerHandle::Get()->PostTask(
313 FROM_HERE, base::Bind(&AvPipelineImpl::ProcessPendingBuffer, weak_this_));
316 void AvPipelineImpl::OnCdmStateChanged() {
317 DCHECK(thread_checker_.CalledOnValidThread());
319 // Update the buffering state if needed.
320 if (buffering_state_.get())
321 UpdatePlayableFrames();
323 // Process the pending buffer in case the CDM now has the frame key id.
324 ProcessPendingBuffer();
327 void AvPipelineImpl::OnCdmDestroyed() {
328 DCHECK(thread_checker_.CalledOnValidThread());
329 media_keys_ = NULL;
332 void AvPipelineImpl::OnFrameBuffered(
333 const scoped_refptr<DecoderBufferBase>& buffer,
334 bool is_at_max_capacity) {
335 DCHECK(thread_checker_.CalledOnValidThread());
337 if (!buffering_state_.get())
338 return;
340 if (!buffer->end_of_stream() && (buffered_time_ == ::media::kNoTimestamp() ||
341 buffered_time_ < buffer->timestamp())) {
342 buffered_time_ = buffer->timestamp();
345 if (is_at_max_capacity)
346 buffering_state_->NotifyMaxCapacity(buffered_time_);
348 // No need to update the list of playable frames,
349 // if we are already blocking on a frame.
350 bool update_playable_frames = non_playable_frames_.empty();
351 non_playable_frames_.push_back(buffer);
352 if (update_playable_frames)
353 UpdatePlayableFrames();
356 void AvPipelineImpl::UpdatePlayableFrames() {
357 while (!non_playable_frames_.empty()) {
358 const scoped_refptr<DecoderBufferBase>& non_playable_frame =
359 non_playable_frames_.front();
361 if (non_playable_frame->end_of_stream()) {
362 buffering_state_->NotifyEos();
363 } else {
364 const CastDecryptConfig* decrypt_config =
365 non_playable_frame->decrypt_config();
366 if (decrypt_config &&
367 !(media_keys_ &&
368 media_keys_->GetDecryptContext(decrypt_config->key_id()).get())) {
369 // The frame is still not playable. All the following are thus not
370 // playable.
371 break;
374 if (playable_buffered_time_ == ::media::kNoTimestamp() ||
375 playable_buffered_time_ < non_playable_frame->timestamp()) {
376 playable_buffered_time_ = non_playable_frame->timestamp();
377 buffering_state_->SetBufferedTime(playable_buffered_time_);
381 // The frame is playable: remove it from the list of non playable frames.
382 non_playable_frames_.pop_front();
386 } // namespace media
387 } // namespace chromecast