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 |