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

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

Issue 974623002: Chromecast: mitigate threading issue between AvPipeline/MediaKeys. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « chromecast/media/cma/pipeline/av_pipeline_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chromecast/media/cma/pipeline/av_pipeline_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698