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

Side by Side Diff: chromecast/media/cma/pipeline/av_pipeline_impl.cc

Issue 1257013003: Load CMA backend from shared library (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 4 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromecast/media/cma/pipeline/av_pipeline_impl.h" 5 #include "chromecast/media/cma/pipeline/av_pipeline_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/thread_task_runner_handle.h" 11 #include "base/thread_task_runner_handle.h"
12 #include "chromecast/media/base/decrypt_context.h" 12 #include "chromecast/media/base/decrypt_context_impl.h"
13 #include "chromecast/media/cdm/browser_cdm_cast.h" 13 #include "chromecast/media/cdm/browser_cdm_cast.h"
14 #include "chromecast/media/cma/backend/media_clock_device.h"
15 #include "chromecast/media/cma/backend/media_component_device.h"
16 #include "chromecast/media/cma/base/buffering_frame_provider.h" 14 #include "chromecast/media/cma/base/buffering_frame_provider.h"
17 #include "chromecast/media/cma/base/buffering_state.h" 15 #include "chromecast/media/cma/base/buffering_state.h"
16 #include "chromecast/media/cma/base/cast_decoder_buffer_impl.h"
18 #include "chromecast/media/cma/base/cma_logging.h" 17 #include "chromecast/media/cma/base/cma_logging.h"
19 #include "chromecast/media/cma/base/coded_frame_provider.h" 18 #include "chromecast/media/cma/base/coded_frame_provider.h"
20 #include "chromecast/media/cma/base/decoder_buffer_base.h" 19 #include "chromecast/media/cma/base/decoder_buffer_base.h"
21 #include "chromecast/media/cma/pipeline/decrypt_util.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"
22 #include "media/base/audio_decoder_config.h" 26 #include "media/base/audio_decoder_config.h"
23 #include "media/base/bind_to_current_loop.h" 27 #include "media/base/bind_to_current_loop.h"
24 #include "media/base/buffers.h" 28 #include "media/base/buffers.h"
25 #include "media/base/decrypt_config.h" 29 #include "media/base/decrypt_config.h"
26 30
27 namespace chromecast { 31 namespace chromecast {
28 namespace media { 32 namespace media {
29 33
30 namespace { 34 namespace {
31 35
32 const int kNoCallbackId = -1; 36 const int kNoCallbackId = -1;
33 37
34 } // namespace 38 } // namespace
35 39
36 AvPipelineImpl::AvPipelineImpl( 40 AvPipelineImpl::AvPipelineImpl(MediaComponentDevice* media_component_device,
37 MediaComponentDevice* media_component_device, 41 const UpdateConfigCB& update_config_cb)
38 const UpdateConfigCB& update_config_cb)
39 : update_config_cb_(update_config_cb), 42 : update_config_cb_(update_config_cb),
40 media_component_device_(media_component_device), 43 media_component_device_(media_component_device),
41 state_(kUninitialized), 44 state_(kUninitialized),
42 buffered_time_(::media::kNoTimestamp()), 45 buffered_time_(::media::kNoTimestamp()),
43 playable_buffered_time_(::media::kNoTimestamp()), 46 playable_buffered_time_(::media::kNoTimestamp()),
44 enable_feeding_(false), 47 enable_feeding_(false),
45 pending_read_(false), 48 pending_read_(false),
46 pending_push_(false), 49 pending_push_(false),
47 enable_time_update_(false), 50 enable_time_update_(false),
48 pending_time_update_task_(false), 51 pending_time_update_task_(false),
49 media_keys_(NULL), 52 media_keys_(NULL),
50 media_keys_callback_id_(kNoCallbackId), 53 media_keys_callback_id_(kNoCallbackId),
51 weak_factory_(this) { 54 weak_factory_(this) {
52 DCHECK(media_component_device); 55 DCHECK(media_component_device);
53 weak_this_ = weak_factory_.GetWeakPtr(); 56 weak_this_ = weak_factory_.GetWeakPtr();
54 thread_checker_.DetachFromThread(); 57 thread_checker_.DetachFromThread();
55 } 58 }
56 59
57 AvPipelineImpl::~AvPipelineImpl() { 60 AvPipelineImpl::~AvPipelineImpl() {
58 DCHECK(thread_checker_.CalledOnValidThread()); 61 DCHECK(thread_checker_.CalledOnValidThread());
59 media_component_device_->SetClient(MediaComponentDevice::Client()); 62 media_component_device_->SetClient(nullptr);
60 63
61 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId) 64 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId)
62 media_keys_->UnregisterPlayer(media_keys_callback_id_); 65 media_keys_->UnregisterPlayer(media_keys_callback_id_);
63 } 66 }
64 67
65 void AvPipelineImpl::TransitionToState(State state) { 68 void AvPipelineImpl::TransitionToState(State state) {
66 DCHECK(thread_checker_.CalledOnValidThread()); 69 DCHECK(thread_checker_.CalledOnValidThread());
67 state_ = state; 70 state_ = state;
68 } 71 }
69 72
(...skipping 16 matching lines...) Expand all
86 void AvPipelineImpl::SetClient(const AvPipelineClient& client) { 89 void AvPipelineImpl::SetClient(const AvPipelineClient& client) {
87 DCHECK(thread_checker_.CalledOnValidThread()); 90 DCHECK(thread_checker_.CalledOnValidThread());
88 DCHECK_EQ(state_, kUninitialized); 91 DCHECK_EQ(state_, kUninitialized);
89 client_ = client; 92 client_ = client;
90 } 93 }
91 94
92 bool AvPipelineImpl::Initialize() { 95 bool AvPipelineImpl::Initialize() {
93 DCHECK(thread_checker_.CalledOnValidThread()); 96 DCHECK(thread_checker_.CalledOnValidThread());
94 DCHECK_EQ(state_, kUninitialized); 97 DCHECK_EQ(state_, kUninitialized);
95 98
96 MediaComponentDevice::Client client; 99 media_component_device_->SetClient(new MediaComponentDeviceClientImpl(
97 client.eos_cb = base::Bind(&AvPipelineImpl::OnEos, weak_this_); 100 base::Bind(&AvPipelineImpl::OnEos, weak_this_)));
98 media_component_device_->SetClient(client);
99 if (!media_component_device_->SetState(MediaComponentDevice::kStateIdle)) 101 if (!media_component_device_->SetState(MediaComponentDevice::kStateIdle))
100 return false; 102 return false;
101 103
102 return true; 104 return true;
103 } 105 }
104 106
105 bool AvPipelineImpl::StartPlayingFrom( 107 bool AvPipelineImpl::StartPlayingFrom(
106 base::TimeDelta time, 108 base::TimeDelta time,
107 const scoped_refptr<BufferingState>& buffering_state) { 109 const scoped_refptr<BufferingState>& buffering_state) {
108 DCHECK(thread_checker_.CalledOnValidThread()); 110 DCHECK(thread_checker_.CalledOnValidThread());
109 DCHECK_EQ(state_, kFlushed); 111 DCHECK_EQ(state_, kFlushed);
110 112
111 // Media time where rendering should start 113 // Media time where rendering should start
112 // and switch to a state where the audio device accepts incoming buffers. 114 // and switch to a state where the audio device accepts incoming buffers.
113 if (!media_component_device_->SetStartPts(time) || 115 if (!media_component_device_->SetStartPts(time.InMicroseconds()) ||
114 !media_component_device_->SetState(MediaComponentDevice::kStatePaused)) { 116 !media_component_device_->SetState(MediaComponentDevice::kStatePaused)) {
115 return false; 117 return false;
116 } 118 }
117 119
118 // Buffering related initialization. 120 // Buffering related initialization.
119 DCHECK(frame_provider_); 121 DCHECK(frame_provider_);
120 buffering_state_ = buffering_state; 122 buffering_state_ = buffering_state;
121 if (buffering_state_.get()) 123 if (buffering_state_.get())
122 buffering_state_->SetMediaTime(time); 124 buffering_state_->SetMediaTime(time);
123 125
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 247
246 if (!pending_buffer_.get() || pending_push_) 248 if (!pending_buffer_.get() || pending_push_)
247 return; 249 return;
248 250
249 // Break the feeding loop when the end of stream is reached. 251 // Break the feeding loop when the end of stream is reached.
250 if (pending_buffer_->end_of_stream()) { 252 if (pending_buffer_->end_of_stream()) {
251 CMALOG(kLogControl) << __FUNCTION__ << ": EOS reached, stopped feeding"; 253 CMALOG(kLogControl) << __FUNCTION__ << ": EOS reached, stopped feeding";
252 enable_feeding_ = false; 254 enable_feeding_ = false;
253 } 255 }
254 256
255 scoped_refptr<DecryptContext> decrypt_context; 257 scoped_ptr<DecryptContextImpl> decrypt_context;
256 if (!pending_buffer_->end_of_stream() && 258 if (!pending_buffer_->end_of_stream() &&
257 pending_buffer_->decrypt_config()) { 259 pending_buffer_->decrypt_config()) {
258 // Verify that CDM has the key ID. 260 // Verify that CDM has the key ID.
259 // Should not send the frame if the key ID is not available yet. 261 // Should not send the frame if the key ID is not available yet.
260 std::string key_id(pending_buffer_->decrypt_config()->key_id()); 262 std::string key_id(pending_buffer_->decrypt_config()->key_id());
261 if (!media_keys_) { 263 if (!media_keys_) {
262 CMALOG(kLogControl) << "No CDM for frame: pts=" 264 CMALOG(kLogControl) << "No CDM for frame: pts="
263 << pending_buffer_->timestamp().InMilliseconds(); 265 << pending_buffer_->timestamp().InMilliseconds();
264 return; 266 return;
265 } 267 }
266 decrypt_context = media_keys_->GetDecryptContext(key_id); 268 decrypt_context = media_keys_->GetDecryptContext(key_id);
267 if (!decrypt_context.get()) { 269 if (!decrypt_context.get()) {
268 CMALOG(kLogControl) << "frame(pts=" 270 CMALOG(kLogControl) << "frame(pts="
269 << pending_buffer_->timestamp().InMilliseconds() 271 << pending_buffer_->timestamp().InMilliseconds()
270 << "): waiting for key id " 272 << "): waiting for key id "
271 << base::HexEncode(&key_id[0], key_id.size()); 273 << base::HexEncode(&key_id[0], key_id.size());
272 return; 274 return;
273 } 275 }
274 276
275 // If we do have the clear key, decrypt the pending buffer 277 // If we do have the clear key, decrypt the pending buffer
276 // and reset the decryption context (not needed anymore). 278 // and reset the decryption context (not needed anymore).
277 crypto::SymmetricKey* key = decrypt_context->GetKey(); 279 crypto::SymmetricKey* key = decrypt_context->GetKey();
278 if (key != NULL) { 280 if (key != NULL) {
279 pending_buffer_ = DecryptDecoderBuffer(pending_buffer_, key); 281 pending_buffer_ = DecryptDecoderBuffer(pending_buffer_, key);
280 decrypt_context = scoped_refptr<DecryptContext>(); 282 decrypt_context.reset();
281 } 283 }
282 } 284 }
283 285
284 if (!pending_buffer_->end_of_stream() && buffering_state_.get()) { 286 if (!pending_buffer_->end_of_stream() && buffering_state_.get()) {
285 base::TimeDelta timestamp = pending_buffer_->timestamp(); 287 base::TimeDelta timestamp = pending_buffer_->timestamp();
286 if (timestamp != ::media::kNoTimestamp()) 288 if (timestamp != ::media::kNoTimestamp())
287 buffering_state_->SetMaxRenderingTime(timestamp); 289 buffering_state_->SetMaxRenderingTime(timestamp);
288 } 290 }
289 291
290 MediaComponentDevice::FrameStatus status = media_component_device_->PushFrame( 292 MediaComponentDevice::FrameStatus status = media_component_device_->PushFrame(
291 decrypt_context, 293 decrypt_context.release(), new CastDecoderBufferImpl(pending_buffer_),
292 pending_buffer_, 294 new FrameStatusCBImpl(
293 base::Bind(&AvPipelineImpl::OnFramePushed, weak_this_)); 295 base::Bind(&AvPipelineImpl::OnFramePushed, weak_this_)));
294 pending_buffer_ = scoped_refptr<DecoderBufferBase>(); 296 pending_buffer_ = scoped_refptr<DecoderBufferBase>();
295 297
296 pending_push_ = (status == MediaComponentDevice::kFramePending); 298 pending_push_ = (status == MediaComponentDevice::kFramePending);
297 if (!pending_push_) 299 if (!pending_push_)
298 OnFramePushed(status); 300 OnFramePushed(status);
299 } 301 }
300 302
301 void AvPipelineImpl::OnFramePushed(MediaComponentDevice::FrameStatus status) { 303 void AvPipelineImpl::OnFramePushed(MediaComponentDevice::FrameStatus status) {
302 DCHECK(thread_checker_.CalledOnValidThread()); 304 DCHECK(thread_checker_.CalledOnValidThread());
303 pending_push_ = false; 305 pending_push_ = false;
(...skipping 24 matching lines...) Expand all
328 } 330 }
329 331
330 void AvPipelineImpl::OnFrameBuffered( 332 void AvPipelineImpl::OnFrameBuffered(
331 const scoped_refptr<DecoderBufferBase>& buffer, 333 const scoped_refptr<DecoderBufferBase>& buffer,
332 bool is_at_max_capacity) { 334 bool is_at_max_capacity) {
333 DCHECK(thread_checker_.CalledOnValidThread()); 335 DCHECK(thread_checker_.CalledOnValidThread());
334 336
335 if (!buffering_state_.get()) 337 if (!buffering_state_.get())
336 return; 338 return;
337 339
338 if (!buffer->end_of_stream() && 340 if (!buffer->end_of_stream() && (buffered_time_ == ::media::kNoTimestamp() ||
339 (buffered_time_ == ::media::kNoTimestamp() || 341 buffered_time_ < buffer->timestamp())) {
340 buffered_time_ < buffer->timestamp())) {
341 buffered_time_ = buffer->timestamp(); 342 buffered_time_ = buffer->timestamp();
342 } 343 }
343 344
344 if (is_at_max_capacity) 345 if (is_at_max_capacity)
345 buffering_state_->NotifyMaxCapacity(buffered_time_); 346 buffering_state_->NotifyMaxCapacity(buffered_time_);
346 347
347 // No need to update the list of playable frames, 348 // No need to update the list of playable frames,
348 // if we are already blocking on a frame. 349 // if we are already blocking on a frame.
349 bool update_playable_frames = non_playable_frames_.empty(); 350 bool update_playable_frames = non_playable_frames_.empty();
350 non_playable_frames_.push_back(buffer); 351 non_playable_frames_.push_back(buffer);
351 if (update_playable_frames) 352 if (update_playable_frames)
352 UpdatePlayableFrames(); 353 UpdatePlayableFrames();
353 } 354 }
354 355
355 void AvPipelineImpl::UpdatePlayableFrames() { 356 void AvPipelineImpl::UpdatePlayableFrames() {
356 while (!non_playable_frames_.empty()) { 357 while (!non_playable_frames_.empty()) {
357 const scoped_refptr<DecoderBufferBase>& non_playable_frame = 358 const scoped_refptr<DecoderBufferBase>& non_playable_frame =
358 non_playable_frames_.front(); 359 non_playable_frames_.front();
359 360
360 if (non_playable_frame->end_of_stream()) { 361 if (non_playable_frame->end_of_stream()) {
361 buffering_state_->NotifyEos(); 362 buffering_state_->NotifyEos();
362 } else { 363 } else {
363 const ::media::DecryptConfig* decrypt_config = 364 const CastDecryptConfig* decrypt_config =
364 non_playable_frame->decrypt_config(); 365 non_playable_frame->decrypt_config();
365 if (decrypt_config && 366 if (decrypt_config &&
366 !(media_keys_ && 367 !(media_keys_ &&
367 media_keys_->GetDecryptContext(decrypt_config->key_id()).get())) { 368 media_keys_->GetDecryptContext(decrypt_config->key_id()).get())) {
368 // The frame is still not playable. All the following are thus not 369 // The frame is still not playable. All the following are thus not
369 // playable. 370 // playable.
370 break; 371 break;
371 } 372 }
372 373
373 if (playable_buffered_time_ == ::media::kNoTimestamp() || 374 if (playable_buffered_time_ == ::media::kNoTimestamp() ||
374 playable_buffered_time_ < non_playable_frame->timestamp()) { 375 playable_buffered_time_ < non_playable_frame->timestamp()) {
375 playable_buffered_time_ = non_playable_frame->timestamp(); 376 playable_buffered_time_ = non_playable_frame->timestamp();
376 buffering_state_->SetBufferedTime(playable_buffered_time_); 377 buffering_state_->SetBufferedTime(playable_buffered_time_);
377 } 378 }
378 } 379 }
379 380
380 // The frame is playable: remove it from the list of non playable frames. 381 // The frame is playable: remove it from the list of non playable frames.
381 non_playable_frames_.pop_front(); 382 non_playable_frames_.pop_front();
382 } 383 }
383 } 384 }
384 385
385 } // namespace media 386 } // namespace media
386 } // namespace chromecast 387 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698