OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "media/base/android/media_codec_player.h" | 5 #include "media/base/android/media_codec_player.h" |
6 | 6 |
7 #include "base/barrier_closure.h" | 7 #include "base/barrier_closure.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | |
9 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
12 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
13 #include "media/base/android/media_codec_audio_decoder.h" | 14 #include "media/base/android/media_codec_audio_decoder.h" |
14 #include "media/base/android/media_codec_video_decoder.h" | 15 #include "media/base/android/media_codec_video_decoder.h" |
15 #include "media/base/android/media_drm_bridge.h" | 16 #include "media/base/android/media_drm_bridge.h" |
16 #include "media/base/android/media_player_manager.h" | 17 #include "media/base/android/media_player_manager.h" |
17 #include "media/base/android/media_task_runner.h" | 18 #include "media/base/android/media_task_runner.h" |
18 #include "media/base/bind_to_current_loop.h" | 19 #include "media/base/bind_to_current_loop.h" |
(...skipping 23 matching lines...) Expand all Loading... | |
42 : MediaPlayerAndroid(player_id, | 43 : MediaPlayerAndroid(player_id, |
43 manager.get(), | 44 manager.get(), |
44 on_decoder_resources_released_cb, | 45 on_decoder_resources_released_cb, |
45 frame_url), | 46 frame_url), |
46 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 47 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
47 demuxer_(demuxer.Pass()), | 48 demuxer_(demuxer.Pass()), |
48 state_(kStatePaused), | 49 state_(kStatePaused), |
49 interpolator_(&default_tick_clock_), | 50 interpolator_(&default_tick_clock_), |
50 pending_start_(false), | 51 pending_start_(false), |
51 pending_seek_(kNoTimestamp()), | 52 pending_seek_(kNoTimestamp()), |
52 drm_bridge_(nullptr), | |
53 cdm_registration_id_(0), | 53 cdm_registration_id_(0), |
54 key_is_required_(false), | 54 key_is_required_(false), |
55 key_is_added_(false), | 55 key_is_added_(false), |
56 media_weak_factory_(this) { | 56 media_weak_factory_(this) { |
57 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 57 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
58 | 58 |
59 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; | 59 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; |
60 | 60 |
61 completion_cb_ = | 61 completion_cb_ = |
62 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); | 62 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); |
(...skipping 29 matching lines...) Expand all Loading... | |
92 // Release the codecs here, before any member variable is destroyed to make | 92 // Release the codecs here, before any member variable is destroyed to make |
93 // the unit tests happy. | 93 // the unit tests happy. |
94 | 94 |
95 if (video_decoder_) | 95 if (video_decoder_) |
96 video_decoder_->ReleaseDecoderResources(); | 96 video_decoder_->ReleaseDecoderResources(); |
97 if (audio_decoder_) | 97 if (audio_decoder_) |
98 audio_decoder_->ReleaseDecoderResources(); | 98 audio_decoder_->ReleaseDecoderResources(); |
99 | 99 |
100 media_stat_->StopAndReport(GetInterpolatedTime()); | 100 media_stat_->StopAndReport(GetInterpolatedTime()); |
101 | 101 |
102 if (drm_bridge_) { | 102 if (cdm_) { |
103 DCHECK(cdm_registration_id_); | 103 DCHECK(cdm_registration_id_); |
104 drm_bridge_->UnregisterPlayer(cdm_registration_id_); | 104 static_cast<MediaDrmBridge*>(cdm_.get()) |
105 ->UnregisterPlayer(cdm_registration_id_); | |
105 } | 106 } |
106 } | 107 } |
107 | 108 |
108 void MediaCodecPlayer::Initialize() { | 109 void MediaCodecPlayer::Initialize() { |
109 DVLOG(1) << __FUNCTION__; | 110 DVLOG(1) << __FUNCTION__; |
110 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 111 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
111 | 112 |
112 interpolator_.SetUpperBound(base::TimeDelta()); | 113 interpolator_.SetUpperBound(base::TimeDelta()); |
113 | 114 |
114 CreateDecoders(); | 115 CreateDecoders(); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 return false; | 404 return false; |
404 } | 405 } |
405 | 406 |
406 bool MediaCodecPlayer::IsPlayerReady() { | 407 bool MediaCodecPlayer::IsPlayerReady() { |
407 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 408 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
408 // This method is called to check whether it's safe to release the player when | 409 // This method is called to check whether it's safe to release the player when |
409 // the OS needs more resources. This class can be released at any time. | 410 // the OS needs more resources. This class can be released at any time. |
410 return true; | 411 return true; |
411 } | 412 } |
412 | 413 |
413 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) { | 414 void MediaCodecPlayer::SetCdm(const scoped_refptr<MediaKeys>& cdm) { |
414 RUN_ON_MEDIA_THREAD(SetCdm, cdm); | 415 RUN_ON_MEDIA_THREAD(SetCdm, cdm); |
416 DCHECK(cdm); | |
jrummell
2015/10/29 21:05:17
Should this DCHECK() be first to fail the caller r
xhwang
2015/10/30 16:20:59
Done.
| |
415 | 417 |
416 DVLOG(1) << __FUNCTION__; | 418 DVLOG(1) << __FUNCTION__; |
417 | 419 |
418 // Currently we don't support DRM change during the middle of playback, even | 420 // Currently we don't support DRM change during the middle of playback, even |
419 // if the player is paused. There is no current plan to support it, see | 421 // if the player is paused. There is no current plan to support it, see |
420 // http://crbug.com/253792. | 422 // http://crbug.com/253792. |
421 if (state_ != kStatePaused || GetInterpolatedTime() > base::TimeDelta()) { | 423 if (state_ != kStatePaused || GetInterpolatedTime() > base::TimeDelta()) { |
422 VLOG(0) << "Setting DRM bridge after playback has started is not supported"; | 424 VLOG(0) << "Setting DRM bridge after playback has started is not supported"; |
423 return; | 425 return; |
424 } | 426 } |
425 | 427 |
426 if (drm_bridge_) { | 428 if (cdm_) { |
427 NOTREACHED() << "Currently we do not support resetting CDM."; | 429 NOTREACHED() << "Currently we do not support resetting CDM."; |
428 return; | 430 return; |
429 } | 431 } |
430 | 432 |
431 DCHECK(cdm); | 433 cdm_ = cdm; |
432 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm); | |
433 | 434 |
434 DCHECK(drm_bridge_); | 435 // Only MediaDrmBridge will be set on MediaCodecPlayer. |
436 MediaDrmBridge* drm_bridge = static_cast<MediaDrmBridge*>(cdm_.get()); | |
435 | 437 |
436 cdm_registration_id_ = drm_bridge_->RegisterPlayer( | 438 // Register CDM callbacks. The callbacks registered will be posted back to the |
437 base::Bind(&MediaCodecPlayer::OnKeyAdded, media_weak_this_), | 439 // media thread via BindToCurrentLoop. |
438 base::Bind(&MediaCodecPlayer::OnCdmUnset, media_weak_this_)); | |
439 | 440 |
440 MediaDrmBridge::MediaCryptoReadyCB cb = BindToCurrentLoop( | 441 // No need to set |cdm_unset_cb| since |this| holds a reference to the |cdm_|. |
Tima Vaisburd
2015/10/29 01:17:53
Please explain that the second callback will never
xhwang
2015/10/29 03:12:31
I'll update this comment when I address other comm
xhwang
2015/10/30 16:20:59
Done.
| |
441 base::Bind(&MediaCodecPlayer::OnMediaCryptoReady, media_weak_this_)); | 442 cdm_registration_id_ = drm_bridge->RegisterPlayer( |
443 BindToCurrentLoop( | |
444 base::Bind(&MediaCodecPlayer::OnKeyAdded, media_weak_this_)), | |
445 base::Bind(&base::DoNothing)); | |
442 | 446 |
443 // Post back to MediaDrmBridge's default thread. | 447 drm_bridge->SetMediaCryptoReadyCB(BindToCurrentLoop( |
444 ui_task_runner_->PostTask(FROM_HERE, | 448 base::Bind(&MediaCodecPlayer::OnMediaCryptoReady, media_weak_this_))); |
445 base::Bind(&MediaDrmBridge::SetMediaCryptoReadyCB, | |
446 drm_bridge_->WeakPtr(), cb)); | |
447 } | 449 } |
448 | 450 |
449 // Callbacks from Demuxer. | 451 // Callbacks from Demuxer. |
450 | 452 |
451 void MediaCodecPlayer::OnDemuxerConfigsAvailable( | 453 void MediaCodecPlayer::OnDemuxerConfigsAvailable( |
452 const DemuxerConfigs& configs) { | 454 const DemuxerConfigs& configs) { |
453 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 455 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
454 | 456 |
455 DVLOG(1) << __FUNCTION__; | 457 DVLOG(1) << __FUNCTION__; |
456 | 458 |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
958 DVLOG(1) << __FUNCTION__; | 960 DVLOG(1) << __FUNCTION__; |
959 | 961 |
960 key_is_added_ = true; | 962 key_is_added_ = true; |
961 | 963 |
962 if (state_ == kStateWaitingForKey) { | 964 if (state_ == kStateWaitingForKey) { |
963 SetState(kStatePlaying); | 965 SetState(kStatePlaying); |
964 StartPlaybackOrBrowserSeek(); | 966 StartPlaybackOrBrowserSeek(); |
965 } | 967 } |
966 } | 968 } |
967 | 969 |
968 void MediaCodecPlayer::OnCdmUnset() { | |
969 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | |
970 DVLOG(1) << __FUNCTION__; | |
971 | |
972 // This comment is copied from MediaSourcePlayer::OnCdmUnset(). | |
973 // TODO(xhwang): Currently this is only called during teardown. Support full | |
974 // detachment of CDM during playback. This will be needed when we start to | |
975 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release | |
976 // MediaDrm when the video is paused, or when the device goes to sleep (see | |
977 // http://crbug.com/272421). | |
978 | |
979 if (audio_decoder_) { | |
980 audio_decoder_->SetNeedsReconfigure(); | |
981 } | |
982 | |
983 if (video_decoder_) { | |
984 video_decoder_->SetProtectedSurfaceRequired(false); | |
985 video_decoder_->SetNeedsReconfigure(); | |
986 } | |
987 | |
988 cdm_registration_id_ = 0; | |
989 drm_bridge_ = nullptr; | |
990 media_crypto_.reset(); | |
991 } | |
992 | |
993 // State machine operations, called on Media thread | 970 // State machine operations, called on Media thread |
994 | 971 |
995 void MediaCodecPlayer::SetState(PlayerState new_state) { | 972 void MediaCodecPlayer::SetState(PlayerState new_state) { |
996 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 973 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
997 | 974 |
998 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); | 975 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); |
999 state_ = new_state; | 976 state_ = new_state; |
1000 } | 977 } |
1001 | 978 |
1002 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { | 979 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1417 RETURN_STRING(kStateWaitingForMediaCrypto); | 1394 RETURN_STRING(kStateWaitingForMediaCrypto); |
1418 RETURN_STRING(kStateWaitingForSeek); | 1395 RETURN_STRING(kStateWaitingForSeek); |
1419 RETURN_STRING(kStateError); | 1396 RETURN_STRING(kStateError); |
1420 } | 1397 } |
1421 return nullptr; // crash early | 1398 return nullptr; // crash early |
1422 } | 1399 } |
1423 | 1400 |
1424 #undef RETURN_STRING | 1401 #undef RETURN_STRING |
1425 | 1402 |
1426 } // namespace media | 1403 } // namespace media |
OLD | NEW |