Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 weak_this_ = weak_factory_.GetWeakPtr(); | 51 weak_this_ = weak_factory_.GetWeakPtr(); |
| 52 thread_checker_.DetachFromThread(); | 52 thread_checker_.DetachFromThread(); |
| 53 } | 53 } |
| 54 | 54 |
| 55 AvPipelineImpl::~AvPipelineImpl() { | 55 AvPipelineImpl::~AvPipelineImpl() { |
| 56 // If there are weak pointers in the wild, they must be invalidated | 56 // If there are weak pointers in the wild, they must be invalidated |
| 57 // on the right thread. | 57 // on the right thread. |
| 58 DCHECK(thread_checker_.CalledOnValidThread()); | 58 DCHECK(thread_checker_.CalledOnValidThread()); |
| 59 media_component_device_->SetClient(MediaComponentDevice::Client()); | 59 media_component_device_->SetClient(MediaComponentDevice::Client()); |
| 60 | 60 |
| 61 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId) | 61 { |
| 62 media_keys_->UnregisterPlayer(media_keys_callback_id_); | 62 base::AutoLock lock(media_keys_lock_); |
| 63 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId) | |
| 64 media_keys_->UnregisterPlayer(media_keys_callback_id_); | |
| 65 } | |
| 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 |
| 70 void AvPipelineImpl::SetCodedFrameProvider( | 73 void AvPipelineImpl::SetCodedFrameProvider( |
| 71 scoped_ptr<CodedFrameProvider> frame_provider, | 74 scoped_ptr<CodedFrameProvider> frame_provider, |
| 72 size_t max_buffer_size, | 75 size_t max_buffer_size, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 if (media_component_device_->GetState() == MediaComponentDevice::kStateIdle) { | 179 if (media_component_device_->GetState() == MediaComponentDevice::kStateIdle) { |
| 177 media_component_device_->SetState( | 180 media_component_device_->SetState( |
| 178 MediaComponentDevice::kStateUninitialized); | 181 MediaComponentDevice::kStateUninitialized); |
| 179 } | 182 } |
| 180 } | 183 } |
| 181 | 184 |
| 182 void AvPipelineImpl::SetCdm(BrowserCdmCast* media_keys) { | 185 void AvPipelineImpl::SetCdm(BrowserCdmCast* media_keys) { |
| 183 DCHECK(thread_checker_.CalledOnValidThread()); | 186 DCHECK(thread_checker_.CalledOnValidThread()); |
| 184 DCHECK(media_keys); | 187 DCHECK(media_keys); |
| 185 | 188 |
| 186 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId) | 189 { |
| 187 media_keys_->UnregisterPlayer(media_keys_callback_id_); | 190 base::AutoLock lock(media_keys_lock_); |
| 191 if (media_keys_ && media_keys_callback_id_ != kNoCallbackId) | |
| 192 media_keys_->UnregisterPlayer(media_keys_callback_id_); | |
| 188 | 193 |
| 189 media_keys_ = media_keys; | 194 media_keys_ = media_keys; |
| 190 media_keys_callback_id_ = media_keys_->RegisterPlayer( | 195 media_keys_callback_id_ = media_keys_->RegisterPlayer( |
| 191 ::media::BindToCurrentLoop( | 196 ::media::BindToCurrentLoop( |
| 192 base::Bind(&AvPipelineImpl::OnCdmStateChanged, weak_this_)), | 197 base::Bind(&AvPipelineImpl::OnCdmStateChanged, weak_this_)), |
| 193 ::media::BindToCurrentLoop( | 198 // CDM destruction requires immediate update; don't change threads. |
|
lcwu1
2015/03/03 18:52:35
A more detailed explanation of why the unset_cb sh
gunsch
2015/03/03 23:04:19
Done.
| |
| 194 base::Bind(&AvPipelineImpl::OnCdmDestroyed, weak_this_))); | 199 base::Bind(&AvPipelineImpl::OnCdmDestroyed, weak_this_)); |
| 200 } | |
| 195 } | 201 } |
| 196 | 202 |
| 197 void AvPipelineImpl::OnEos() { | 203 void AvPipelineImpl::OnEos() { |
| 198 DCHECK(thread_checker_.CalledOnValidThread()); | 204 DCHECK(thread_checker_.CalledOnValidThread()); |
| 199 CMALOG(kLogControl) << __FUNCTION__; | 205 CMALOG(kLogControl) << __FUNCTION__; |
| 200 if (state_ != kPlaying) | 206 if (state_ != kPlaying) |
| 201 return; | 207 return; |
| 202 | 208 |
| 203 if (!client_.eos_cb.is_null()) | 209 if (!client_.eos_cb.is_null()) |
| 204 client_.eos_cb.Run(); | 210 client_.eos_cb.Run(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 CMALOG(kLogControl) << __FUNCTION__ << ": EOS reached, stopped feeding"; | 261 CMALOG(kLogControl) << __FUNCTION__ << ": EOS reached, stopped feeding"; |
| 256 enable_feeding_ = false; | 262 enable_feeding_ = false; |
| 257 } | 263 } |
| 258 | 264 |
| 259 scoped_refptr<DecryptContext> decrypt_context; | 265 scoped_refptr<DecryptContext> decrypt_context; |
| 260 if (!pending_buffer_->end_of_stream() && | 266 if (!pending_buffer_->end_of_stream() && |
| 261 pending_buffer_->decrypt_config()) { | 267 pending_buffer_->decrypt_config()) { |
| 262 // Verify that CDM has the key ID. | 268 // Verify that CDM has the key ID. |
| 263 // Should not send the frame if the key ID is not available yet. | 269 // Should not send the frame if the key ID is not available yet. |
| 264 std::string key_id(pending_buffer_->decrypt_config()->key_id()); | 270 std::string key_id(pending_buffer_->decrypt_config()->key_id()); |
| 265 if (!media_keys_) { | 271 { |
| 266 CMALOG(kLogControl) << "No CDM for frame: pts=" | 272 base::AutoLock lock(media_keys_lock_); |
| 267 << pending_buffer_->timestamp().InMilliseconds(); | 273 if (!media_keys_) { |
| 268 return; | 274 CMALOG(kLogControl) << "No CDM for frame: pts=" |
| 275 << pending_buffer_->timestamp().InMilliseconds(); | |
| 276 return; | |
| 277 } | |
| 278 decrypt_context = media_keys_->GetDecryptContext(key_id); | |
| 269 } | 279 } |
| 270 decrypt_context = media_keys_->GetDecryptContext(key_id); | |
| 271 if (!decrypt_context.get()) { | 280 if (!decrypt_context.get()) { |
| 272 CMALOG(kLogControl) << "frame(pts=" | 281 CMALOG(kLogControl) << "frame(pts=" |
| 273 << pending_buffer_->timestamp().InMilliseconds() | 282 << pending_buffer_->timestamp().InMilliseconds() |
| 274 << "): waiting for key id " | 283 << "): waiting for key id " |
| 275 << base::HexEncode(&key_id[0], key_id.size()); | 284 << base::HexEncode(&key_id[0], key_id.size()); |
| 276 return; | 285 return; |
| 277 } | 286 } |
| 278 | 287 |
| 279 // If we do have the clear key, decrypt the pending buffer | 288 // If we do have the clear key, decrypt the pending buffer |
| 280 // and reset the decryption context (not needed anymore). | 289 // and reset the decryption context (not needed anymore). |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 | 330 |
| 322 // Update the buffering state if needed. | 331 // Update the buffering state if needed. |
| 323 if (buffering_state_.get()) | 332 if (buffering_state_.get()) |
| 324 UpdatePlayableFrames(); | 333 UpdatePlayableFrames(); |
| 325 | 334 |
| 326 // Process the pending buffer in case the CDM now has the frame key id. | 335 // Process the pending buffer in case the CDM now has the frame key id. |
| 327 ProcessPendingBuffer(); | 336 ProcessPendingBuffer(); |
| 328 } | 337 } |
| 329 | 338 |
| 330 void AvPipelineImpl::OnCdmDestroyed() { | 339 void AvPipelineImpl::OnCdmDestroyed() { |
| 331 DCHECK(thread_checker_.CalledOnValidThread()); | 340 DCHECK(thread_checker_.CalledOnValidThread()); |
|
lcwu1
2015/03/03 18:52:35
Now that this function can be called from the main
gunsch
2015/03/03 23:04:19
Done.
| |
| 332 media_keys_ = NULL; | 341 { |
| 342 base::AutoLock lock(media_keys_lock_); | |
| 343 media_keys_ = NULL; | |
| 344 } | |
| 333 } | 345 } |
| 334 | 346 |
| 335 void AvPipelineImpl::OnFrameBuffered( | 347 void AvPipelineImpl::OnFrameBuffered( |
| 336 const scoped_refptr<DecoderBufferBase>& buffer, | 348 const scoped_refptr<DecoderBufferBase>& buffer, |
| 337 bool is_at_max_capacity) { | 349 bool is_at_max_capacity) { |
| 338 DCHECK(thread_checker_.CalledOnValidThread()); | 350 DCHECK(thread_checker_.CalledOnValidThread()); |
| 339 | 351 |
| 340 if (!buffering_state_.get()) | 352 if (!buffering_state_.get()) |
| 341 return; | 353 return; |
| 342 | 354 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 } | 394 } |
| 383 } | 395 } |
| 384 | 396 |
| 385 // The frame is playable: remove it from the list of non playable frames. | 397 // The frame is playable: remove it from the list of non playable frames. |
| 386 non_playable_frames_.pop_front(); | 398 non_playable_frames_.pop_front(); |
| 387 } | 399 } |
| 388 } | 400 } |
| 389 | 401 |
| 390 } // namespace media | 402 } // namespace media |
| 391 } // namespace chromecast | 403 } // namespace chromecast |
| OLD | NEW |