Chromium Code Reviews| 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/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
| 12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 13 #include "media/base/android/media_codec_audio_decoder.h" | 13 #include "media/base/android/media_codec_audio_decoder.h" |
| 14 #include "media/base/android/media_codec_video_decoder.h" | 14 #include "media/base/android/media_codec_video_decoder.h" |
| 15 #include "media/base/android/media_drm_bridge.h" | |
| 15 #include "media/base/android/media_player_manager.h" | 16 #include "media/base/android/media_player_manager.h" |
| 16 #include "media/base/timestamp_constants.h" | 17 #include "media/base/timestamp_constants.h" |
| 17 | 18 |
| 18 #define RUN_ON_MEDIA_THREAD(METHOD, ...) \ | 19 #define RUN_ON_MEDIA_THREAD(METHOD, ...) \ |
| 19 do { \ | 20 do { \ |
| 20 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \ | 21 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \ |
| 21 DCHECK(ui_task_runner_->BelongsToCurrentThread()); \ | 22 DCHECK(ui_task_runner_->BelongsToCurrentThread()); \ |
| 22 GetMediaTaskRunner()->PostTask( \ | 23 GetMediaTaskRunner()->PostTask( \ |
| 23 FROM_HERE, base::Bind(&MediaCodecPlayer::METHOD, media_weak_this_, \ | 24 FROM_HERE, base::Bind(&MediaCodecPlayer::METHOD, media_weak_this_, \ |
| 24 ##__VA_ARGS__)); \ | 25 ##__VA_ARGS__)); \ |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 55 : MediaPlayerAndroid(player_id, | 56 : MediaPlayerAndroid(player_id, |
| 56 manager.get(), | 57 manager.get(), |
| 57 request_media_resources_cb, | 58 request_media_resources_cb, |
| 58 frame_url), | 59 frame_url), |
| 59 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 60 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 60 demuxer_(demuxer.Pass()), | 61 demuxer_(demuxer.Pass()), |
| 61 state_(kStatePaused), | 62 state_(kStatePaused), |
| 62 interpolator_(&default_tick_clock_), | 63 interpolator_(&default_tick_clock_), |
| 63 pending_start_(false), | 64 pending_start_(false), |
| 64 pending_seek_(kNoTimestamp()), | 65 pending_seek_(kNoTimestamp()), |
| 66 drm_bridge_(nullptr), | |
| 67 cdm_registration_id_(0), | |
| 68 key_is_required_(false), | |
| 69 key_is_added_(false), | |
| 65 media_weak_factory_(this) { | 70 media_weak_factory_(this) { |
| 66 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 71 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 67 | 72 |
| 68 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; | 73 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; |
| 69 | 74 |
| 70 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id); | 75 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id); |
| 71 | 76 |
| 72 completion_cb_ = | 77 completion_cb_ = |
| 73 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); | 78 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); |
| 79 key_required_cb_ = base::Bind(&MediaPlayerManager::OnWaitingForDecryptionKey, | |
| 80 manager, player_id); | |
| 74 seek_done_cb_ = | 81 seek_done_cb_ = |
| 75 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id); | 82 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id); |
| 76 error_cb_ = base::Bind(&MediaPlayerManager::OnError, manager, player_id); | 83 error_cb_ = base::Bind(&MediaPlayerManager::OnError, manager, player_id); |
| 77 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener, | 84 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener, |
| 78 WeakPtrForUIThread(), nullptr); | 85 WeakPtrForUIThread(), nullptr); |
| 79 detach_listener_cb_ = | 86 detach_listener_cb_ = |
| 80 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread()); | 87 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread()); |
| 81 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged, | 88 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged, |
| 82 WeakPtrForUIThread()); | 89 WeakPtrForUIThread()); |
| 83 time_update_cb_ = | 90 time_update_cb_ = |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 97 | 104 |
| 98 // Currently the unit tests wait for the MediaCodecPlayer destruction by | 105 // Currently the unit tests wait for the MediaCodecPlayer destruction by |
| 99 // watching the demuxer, which is destroyed as one of the member variables. | 106 // watching the demuxer, which is destroyed as one of the member variables. |
| 100 // Release the codecs here, before any member variable is destroyed to make | 107 // Release the codecs here, before any member variable is destroyed to make |
| 101 // the unit tests happy. | 108 // the unit tests happy. |
| 102 | 109 |
| 103 if (video_decoder_) | 110 if (video_decoder_) |
| 104 video_decoder_->ReleaseDecoderResources(); | 111 video_decoder_->ReleaseDecoderResources(); |
| 105 if (audio_decoder_) | 112 if (audio_decoder_) |
| 106 audio_decoder_->ReleaseDecoderResources(); | 113 audio_decoder_->ReleaseDecoderResources(); |
| 114 | |
| 115 if (drm_bridge_) { | |
| 116 DCHECK(cdm_registration_id_); | |
| 117 drm_bridge_->UnregisterPlayer(cdm_registration_id_); | |
| 118 } | |
| 107 } | 119 } |
| 108 | 120 |
| 109 void MediaCodecPlayer::Initialize() { | 121 void MediaCodecPlayer::Initialize() { |
| 110 DVLOG(1) << __FUNCTION__; | 122 DVLOG(1) << __FUNCTION__; |
| 111 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 123 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 112 | 124 |
| 113 interpolator_.SetUpperBound(base::TimeDelta()); | 125 interpolator_.SetUpperBound(base::TimeDelta()); |
| 114 | 126 |
| 115 CreateDecoders(); | 127 CreateDecoders(); |
| 116 | 128 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 } | 228 } |
| 217 break; | 229 break; |
| 218 case kStateStopping: | 230 case kStateStopping: |
| 219 case kStateWaitingForSeek: | 231 case kStateWaitingForSeek: |
| 220 SetPendingStart(true); | 232 SetPendingStart(true); |
| 221 break; | 233 break; |
| 222 case kStateWaitingForConfig: | 234 case kStateWaitingForConfig: |
| 223 case kStatePrefetching: | 235 case kStatePrefetching: |
| 224 case kStatePlaying: | 236 case kStatePlaying: |
| 225 case kStateWaitingForSurface: | 237 case kStateWaitingForSurface: |
| 238 case kStateWaitingForKey: | |
| 239 case kStateWaitingForCrypto: | |
| 226 case kStateError: | 240 case kStateError: |
| 227 break; // Ignore | 241 break; // Ignore |
| 228 default: | 242 default: |
| 229 NOTREACHED(); | 243 NOTREACHED(); |
| 230 break; | 244 break; |
| 231 } | 245 } |
| 232 } | 246 } |
| 233 | 247 |
| 234 void MediaCodecPlayer::Pause(bool is_media_related_action) { | 248 void MediaCodecPlayer::Pause(bool is_media_related_action) { |
| 235 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action); | 249 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action); |
| 236 | 250 |
| 237 DVLOG(1) << __FUNCTION__; | 251 DVLOG(1) << __FUNCTION__; |
| 238 | 252 |
| 239 SetPendingStart(false); | 253 SetPendingStart(false); |
| 240 | 254 |
| 241 switch (state_) { | 255 switch (state_) { |
| 242 case kStateWaitingForConfig: | 256 case kStateWaitingForConfig: |
| 243 case kStatePrefetching: | 257 case kStatePrefetching: |
| 244 case kStateWaitingForSurface: | 258 case kStateWaitingForSurface: |
| 259 case kStateWaitingForKey: | |
| 260 case kStateWaitingForCrypto: | |
| 245 SetState(kStatePaused); | 261 SetState(kStatePaused); |
| 246 StopDecoders(); | 262 StopDecoders(); |
| 247 break; | 263 break; |
| 248 case kStatePlaying: | 264 case kStatePlaying: |
| 249 SetState(kStateStopping); | 265 SetState(kStateStopping); |
| 250 RequestToStopDecoders(); | 266 RequestToStopDecoders(); |
| 251 break; | 267 break; |
| 252 case kStatePaused: | 268 case kStatePaused: |
| 253 case kStateStopping: | 269 case kStateStopping: |
| 254 case kStateWaitingForSeek: | 270 case kStateWaitingForSeek: |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 266 DVLOG(1) << __FUNCTION__ << " " << timestamp; | 282 DVLOG(1) << __FUNCTION__ << " " << timestamp; |
| 267 | 283 |
| 268 switch (state_) { | 284 switch (state_) { |
| 269 case kStatePaused: | 285 case kStatePaused: |
| 270 SetState(kStateWaitingForSeek); | 286 SetState(kStateWaitingForSeek); |
| 271 RequestDemuxerSeek(timestamp); | 287 RequestDemuxerSeek(timestamp); |
| 272 break; | 288 break; |
| 273 case kStateWaitingForConfig: | 289 case kStateWaitingForConfig: |
| 274 case kStatePrefetching: | 290 case kStatePrefetching: |
| 275 case kStateWaitingForSurface: | 291 case kStateWaitingForSurface: |
| 292 case kStateWaitingForKey: | |
| 293 case kStateWaitingForCrypto: | |
| 276 SetState(kStateWaitingForSeek); | 294 SetState(kStateWaitingForSeek); |
| 277 StopDecoders(); | 295 StopDecoders(); |
| 278 SetPendingStart(true); | 296 SetPendingStart(true); |
| 279 RequestDemuxerSeek(timestamp); | 297 RequestDemuxerSeek(timestamp); |
| 280 break; | 298 break; |
| 281 case kStatePlaying: | 299 case kStatePlaying: |
| 282 SetState(kStateStopping); | 300 SetState(kStateStopping); |
| 283 RequestToStopDecoders(); | 301 RequestToStopDecoders(); |
| 284 SetPendingStart(true); | 302 SetPendingStart(true); |
| 285 SetPendingSeek(timestamp); | 303 SetPendingSeek(timestamp); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 306 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser | 324 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser |
| 307 // and renderer processes going. Seek should work across and after Release(). | 325 // and renderer processes going. Seek should work across and after Release(). |
| 308 | 326 |
| 309 ReleaseDecoderResources(); | 327 ReleaseDecoderResources(); |
| 310 | 328 |
| 311 SetPendingStart(false); | 329 SetPendingStart(false); |
| 312 | 330 |
| 313 if (state_ != kStateWaitingForSeek) | 331 if (state_ != kStateWaitingForSeek) |
| 314 SetState(kStatePaused); | 332 SetState(kStatePaused); |
| 315 | 333 |
| 334 // Crear encryption key related flags. | |
| 335 key_is_required_ = false; | |
| 336 key_is_added_ = false; | |
| 337 | |
| 316 base::TimeDelta pending_seek_time = GetPendingSeek(); | 338 base::TimeDelta pending_seek_time = GetPendingSeek(); |
| 317 if (pending_seek_time != kNoTimestamp()) { | 339 if (pending_seek_time != kNoTimestamp()) { |
| 318 SetPendingSeek(kNoTimestamp()); | 340 SetPendingSeek(kNoTimestamp()); |
| 319 SetState(kStateWaitingForSeek); | 341 SetState(kStateWaitingForSeek); |
| 320 RequestDemuxerSeek(pending_seek_time); | 342 RequestDemuxerSeek(pending_seek_time); |
| 321 } | 343 } |
| 322 } | 344 } |
| 323 | 345 |
| 324 void MediaCodecPlayer::SetVolume(double volume) { | 346 void MediaCodecPlayer::SetVolume(double volume) { |
| 325 RUN_ON_MEDIA_THREAD(SetVolume, volume); | 347 RUN_ON_MEDIA_THREAD(SetVolume, volume); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 } | 397 } |
| 376 | 398 |
| 377 bool MediaCodecPlayer::IsPlayerReady() { | 399 bool MediaCodecPlayer::IsPlayerReady() { |
| 378 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 400 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 379 // This method is called to check whether it's safe to release the player when | 401 // This method is called to check whether it's safe to release the player when |
| 380 // the OS needs more resources. This class can be released at any time. | 402 // the OS needs more resources. This class can be released at any time. |
| 381 return true; | 403 return true; |
| 382 } | 404 } |
| 383 | 405 |
| 384 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) { | 406 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) { |
| 385 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 407 RUN_ON_MEDIA_THREAD(SetCdm, cdm); |
| 386 NOTIMPLEMENTED(); | 408 |
| 409 DVLOG(1) << __FUNCTION__; | |
| 410 | |
| 411 // Currently we don't support DRM change during the middle of playback, even | |
| 412 // if the player is paused. There is no current plan to support it, see | |
| 413 // http://crbug.com/253792. | |
| 414 if (state_ != kStatePaused || GetInterpolatedTime() > base::TimeDelta()) { | |
| 415 VLOG(0) << "Setting DRM bridge after playback has started is not supported"; | |
| 416 return; | |
| 417 } | |
| 418 | |
| 419 if (drm_bridge_) { | |
| 420 NOTREACHED() << "Currently we do not support resetting CDM."; | |
| 421 return; | |
| 422 } | |
| 423 | |
| 424 DCHECK(cdm); | |
| 425 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm); | |
| 426 | |
| 427 DCHECK(drm_bridge_); | |
| 428 | |
| 429 DCHECK(audio_decoder_); | |
| 430 DCHECK(video_decoder_); | |
| 431 audio_decoder_->SetDrmBridge(drm_bridge_); | |
| 432 video_decoder_->SetDrmBridge(drm_bridge_); | |
| 433 | |
| 434 cdm_registration_id_ = drm_bridge_->RegisterPlayer( | |
| 435 base::Bind(&MediaCodecPlayer::OnKeyAdded, media_weak_this_), | |
| 436 base::Bind(&MediaCodecPlayer::OnCdmUnset, media_weak_this_)); | |
| 437 | |
| 438 // If the crypto is ready by this time, OnMediaCryptoReady will be posted | |
| 439 // immediately, otherwise it will be posted when the crypro is ready. | |
| 440 drm_bridge_->SetMediaCryptoReadyCB( | |
| 441 base::Bind(&MediaCodecPlayer::OnMediaCryptoReady, media_weak_this_)); | |
| 387 } | 442 } |
| 388 | 443 |
| 389 // Callbacks from Demuxer. | 444 // Callbacks from Demuxer. |
| 390 | 445 |
| 391 void MediaCodecPlayer::OnDemuxerConfigsAvailable( | 446 void MediaCodecPlayer::OnDemuxerConfigsAvailable( |
| 392 const DemuxerConfigs& configs) { | 447 const DemuxerConfigs& configs) { |
| 393 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 448 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 394 | 449 |
| 395 DVLOG(1) << __FUNCTION__; | 450 DVLOG(1) << __FUNCTION__; |
| 396 | 451 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 597 DCHECK(!internal_error_cb_.is_null()); | 652 DCHECK(!internal_error_cb_.is_null()); |
| 598 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); | 653 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); |
| 599 return; | 654 return; |
| 600 } | 655 } |
| 601 | 656 |
| 602 if (HasVideo() && !video_decoder_->HasVideoSurface()) { | 657 if (HasVideo() && !video_decoder_->HasVideoSurface()) { |
| 603 SetState(kStateWaitingForSurface); | 658 SetState(kStateWaitingForSurface); |
| 604 return; | 659 return; |
| 605 } | 660 } |
| 606 | 661 |
| 662 if (key_is_required_ && !key_is_added_) { | |
| 663 SetState(kStateWaitingForKey); | |
| 664 ui_task_runner_->PostTask(FROM_HERE, key_required_cb_); | |
| 665 return; | |
| 666 } | |
| 667 | |
| 607 SetState(kStatePlaying); | 668 SetState(kStatePlaying); |
| 608 StartPlaybackOrBrowserSeek(); | 669 StartPlaybackOrBrowserSeek(); |
| 609 } | 670 } |
| 610 | 671 |
| 611 void MediaCodecPlayer::OnPrerollDone() { | 672 void MediaCodecPlayer::OnPrerollDone() { |
| 612 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 673 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 613 | 674 |
| 614 if (state_ != kStatePlaying) { | 675 if (state_ != kStatePlaying) { |
| 615 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_) | 676 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_) |
| 616 << ", ignoring"; | 677 << ", ignoring"; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 return; | 771 return; |
| 711 } | 772 } |
| 712 | 773 |
| 713 // DetachListener to UI thread | 774 // DetachListener to UI thread |
| 714 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); | 775 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); |
| 715 | 776 |
| 716 if (AudioFinished() && VideoFinished()) | 777 if (AudioFinished() && VideoFinished()) |
| 717 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); | 778 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); |
| 718 } | 779 } |
| 719 | 780 |
| 781 void MediaCodecPlayer::OnKeyRequired(DemuxerStream::Type type) { | |
| 782 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | |
| 783 DVLOG(1) << __FUNCTION__ << " " << type; | |
| 784 | |
| 785 // Request stop and restart to pick up the key. | |
| 786 key_is_required_ = true; | |
| 787 | |
| 788 if (state_ == kStatePlaying) { | |
| 789 SetState(kStateStopping); | |
| 790 RequestToStopDecoders(); | |
| 791 SetPendingStart(true); | |
| 792 } | |
| 793 } | |
| 794 | |
| 720 void MediaCodecPlayer::OnError() { | 795 void MediaCodecPlayer::OnError() { |
| 721 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 796 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 722 DVLOG(1) << __FUNCTION__; | 797 DVLOG(1) << __FUNCTION__; |
| 723 | 798 |
| 724 // kStateError blocks all events | 799 // kStateError blocks all events |
| 725 SetState(kStateError); | 800 SetState(kStateError); |
| 726 | 801 |
| 727 ReleaseDecoderResources(); | 802 ReleaseDecoderResources(); |
| 728 | 803 |
| 729 ui_task_runner_->PostTask(FROM_HERE, | 804 ui_task_runner_->PostTask(FROM_HERE, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 793 void MediaCodecPlayer::OnVideoResolutionChanged(const gfx::Size& size) { | 868 void MediaCodecPlayer::OnVideoResolutionChanged(const gfx::Size& size) { |
| 794 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 869 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 795 | 870 |
| 796 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height(); | 871 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height(); |
| 797 | 872 |
| 798 // Update cache and notify manager on UI thread | 873 // Update cache and notify manager on UI thread |
| 799 ui_task_runner_->PostTask( | 874 ui_task_runner_->PostTask( |
| 800 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size)); | 875 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size)); |
| 801 } | 876 } |
| 802 | 877 |
| 878 // Callbacks from DRM | |
| 879 | |
| 880 void MediaCodecPlayer::OnMediaCryptoReady( | |
| 881 MediaDrmBridge::JavaObjectPtr media_crypto) { | |
| 882 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | |
| 883 DVLOG(1) << __FUNCTION__; | |
| 884 | |
| 885 // We receive the MediaCrypto global reference with this callback and use it | |
| 886 // later for all subsequent configurations. This is possible only if the | |
| 887 // MediaCrypto object remains valid until new SetCdm() is called. | |
| 888 | |
| 889 DCHECK(media_crypto); | |
| 890 DCHECK(!media_crypto->is_null()); | |
| 891 | |
| 892 DCHECK(drm_bridge_); | |
| 893 drm_bridge_->SetMediaCryptoReadyCB(MediaDrmBridge::MediaCryptoReadyCB()); | |
|
Tima Vaisburd
2015/09/22 19:41:23
MediaDrmBridge does ResetAndReturn before sending
| |
| 894 | |
| 895 media_crypto_ = media_crypto.Pass(); | |
| 896 | |
| 897 if (state_ == kStateWaitingForCrypto) { | |
| 898 // Resume start sequence (configure, etc.) | |
| 899 SetState(kStatePlaying); | |
| 900 StartPlaybackOrBrowserSeek(); | |
| 901 } | |
| 902 | |
| 903 DVLOG(1) << __FUNCTION__ << " end"; | |
| 904 } | |
| 905 | |
| 906 void MediaCodecPlayer::OnKeyAdded() { | |
| 907 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | |
| 908 DVLOG(1) << __FUNCTION__; | |
| 909 | |
| 910 key_is_added_ = true; | |
| 911 | |
| 912 if (state_ == kStateWaitingForKey) { | |
| 913 SetState(kStatePlaying); | |
| 914 StartPlaybackOrBrowserSeek(); | |
| 915 } | |
| 916 } | |
| 917 | |
| 918 void MediaCodecPlayer::OnCdmUnset() { | |
| 919 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | |
| 920 DVLOG(1) << __FUNCTION__; | |
| 921 | |
| 922 // This comment is copied from MediaSourcePlayer::OnCdmUnset(). | |
| 923 // TODO(xhwang): Currently this is only called during teardown. Support full | |
| 924 // detachment of CDM during playback. This will be needed when we start to | |
| 925 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release | |
| 926 // MediaDrm when the video is paused, or when the device goes to sleep (see | |
| 927 // http://crbug.com/272421). | |
| 928 | |
| 929 if (audio_decoder_) | |
| 930 audio_decoder_->SetDrmBridge(nullptr); | |
| 931 if (video_decoder_) | |
| 932 video_decoder_->SetDrmBridge(nullptr); | |
| 933 | |
| 934 cdm_registration_id_ = 0; | |
| 935 drm_bridge_ = nullptr; | |
| 936 media_crypto_.reset(); | |
| 937 } | |
| 938 | |
| 803 // State machine operations, called on Media thread | 939 // State machine operations, called on Media thread |
| 804 | 940 |
| 805 void MediaCodecPlayer::SetState(PlayerState new_state) { | 941 void MediaCodecPlayer::SetState(PlayerState new_state) { |
| 806 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 942 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 807 | 943 |
| 808 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); | 944 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); |
| 809 state_ = new_state; | 945 state_ = new_state; |
| 810 } | 946 } |
| 811 | 947 |
| 812 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { | 948 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 892 video_decoder_->Prefetch(prefetch_cb); | 1028 video_decoder_->Prefetch(prefetch_cb); |
| 893 } | 1029 } |
| 894 | 1030 |
| 895 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() { | 1031 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() { |
| 896 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1032 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 897 DVLOG(1) << __FUNCTION__; | 1033 DVLOG(1) << __FUNCTION__; |
| 898 | 1034 |
| 899 // TODO(timav): consider replacing this method with posting a | 1035 // TODO(timav): consider replacing this method with posting a |
| 900 // browser seek task (i.e. generate an event) from StartPlaybackDecoders(). | 1036 // browser seek task (i.e. generate an event) from StartPlaybackDecoders(). |
| 901 | 1037 |
| 1038 // Clear encryption key related flags. | |
| 1039 key_is_required_ = false; | |
| 1040 key_is_added_ = false; | |
| 1041 | |
| 902 StartStatus status = StartPlaybackDecoders(); | 1042 StartStatus status = StartPlaybackDecoders(); |
| 903 | 1043 |
| 904 switch (status) { | 1044 switch (status) { |
| 905 case kStartBrowserSeekRequired: | 1045 case kStartBrowserSeekRequired: |
| 906 // Browser seek | 1046 // Browser seek |
| 907 SetState(kStateWaitingForSeek); | 1047 SetState(kStateWaitingForSeek); |
| 908 SetPendingStart(true); | 1048 SetPendingStart(true); |
| 909 StopDecoders(); | 1049 StopDecoders(); |
| 910 RequestDemuxerSeek(GetInterpolatedTime(), true); | 1050 RequestDemuxerSeek(GetInterpolatedTime(), true); |
| 911 break; | 1051 break; |
| 1052 case kStartCryptoRequired: | |
| 1053 SetState(kStateWaitingForCrypto); | |
| 1054 break; | |
| 912 case kStartFailed: | 1055 case kStartFailed: |
| 913 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); | 1056 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); |
| 914 break; | 1057 break; |
| 915 case kStartOk: | 1058 case kStartOk: |
| 916 break; | 1059 break; |
| 917 } | 1060 } |
| 918 } | 1061 } |
| 919 | 1062 |
| 920 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() { | 1063 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() { |
| 921 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1064 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 939 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1082 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 940 DVLOG(1) << __FUNCTION__; | 1083 DVLOG(1) << __FUNCTION__; |
| 941 | 1084 |
| 942 const bool do_audio = !AudioFinished(); | 1085 const bool do_audio = !AudioFinished(); |
| 943 const bool do_video = !VideoFinished(); | 1086 const bool do_video = !VideoFinished(); |
| 944 | 1087 |
| 945 // If there is nothing to play, the state machine should determine this at the | 1088 // If there is nothing to play, the state machine should determine this at the |
| 946 // prefetch state and never call this method. | 1089 // prefetch state and never call this method. |
| 947 DCHECK(do_audio || do_video); | 1090 DCHECK(do_audio || do_video); |
| 948 | 1091 |
| 949 // Start with video: if browser seek is required it would | 1092 bool need_crypto = (do_audio && audio_decoder_->IsContentEncrypted()) || |
| 950 // not make sense to configure audio. | 1093 (do_video && video_decoder_->IsContentEncrypted()); |
| 951 | 1094 |
| 952 if (do_video) { | 1095 // Do we need to create a local ref from the global ref? |
| 953 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure(); | 1096 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr; |
| 954 switch (status) { | 1097 |
| 955 case MediaCodecDecoder::kConfigOk: | 1098 if (need_crypto) { |
| 956 break; | 1099 DVLOG(1) << (audio_decoder_->IsContentEncrypted() ? " audio" : "") |
| 957 case MediaCodecDecoder::kConfigKeyFrameRequired: | 1100 << (video_decoder_->IsContentEncrypted() ? " video" : "") |
| 958 // TODO(timav): post a task or return the status? | 1101 << " need(s) encryption"; |
| 959 return kStartBrowserSeekRequired; | 1102 if (!media_crypto) { |
| 960 case MediaCodecDecoder::kConfigFailure: | 1103 DVLOG(1) << __FUNCTION__ << ": MediaCrypto is not found, returning"; |
| 961 return kStartFailed; | 1104 return kStartCryptoRequired; |
| 962 } | 1105 } |
| 963 } | 1106 } |
| 964 | 1107 |
| 965 if (do_audio) { | 1108 // Start with video: if browser seek is required it would not make sense to |
| 966 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); | 1109 // configure audio. |
| 967 if (status != MediaCodecDecoder::kConfigOk) { | 1110 |
| 1111 MediaCodecDecoder::ConfigStatus status = MediaCodecDecoder::kConfigOk; | |
| 1112 if (do_video) | |
| 1113 status = video_decoder_->Configure(media_crypto); | |
| 1114 | |
| 1115 if (status == MediaCodecDecoder::kConfigOk && do_audio) | |
| 1116 status = audio_decoder_->Configure(media_crypto); | |
| 1117 | |
| 1118 switch (status) { | |
| 1119 case MediaCodecDecoder::kConfigOk: | |
| 1120 break; | |
| 1121 case MediaCodecDecoder::kConfigKeyFrameRequired: | |
| 1122 return kStartBrowserSeekRequired; | |
| 1123 case MediaCodecDecoder::kConfigNoCrypto: // TODO: delete this | |
| 1124 return kStartCryptoRequired; | |
| 1125 case MediaCodecDecoder::kConfigFailure: | |
| 968 return kStartFailed; | 1126 return kStartFailed; |
| 969 } | |
| 970 } | 1127 } |
| 971 | |
| 972 return kStartOk; | 1128 return kStartOk; |
| 973 } | 1129 } |
| 974 | 1130 |
| 975 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( | 1131 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( |
| 976 bool* preroll_required) { | 1132 bool* preroll_required) { |
| 977 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1133 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 978 | 1134 |
| 979 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime(); | 1135 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime(); |
| 980 | 1136 |
| 981 // If requested, preroll is always done in the beginning of the playback, | 1137 // If requested, preroll is always done in the beginning of the playback, |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1120 | 1276 |
| 1121 audio_decoder_.reset(new MediaCodecAudioDecoder( | 1277 audio_decoder_.reset(new MediaCodecAudioDecoder( |
| 1122 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1278 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
| 1123 media_weak_this_, DemuxerStream::AUDIO), | 1279 media_weak_this_, DemuxerStream::AUDIO), |
| 1124 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1280 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
| 1125 DemuxerStream::AUDIO), | 1281 DemuxerStream::AUDIO), |
| 1126 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, | 1282 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1127 DemuxerStream::AUDIO), | 1283 DemuxerStream::AUDIO), |
| 1128 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, | 1284 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1129 DemuxerStream::AUDIO), | 1285 DemuxerStream::AUDIO), |
| 1286 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, | |
| 1287 DemuxerStream::AUDIO), | |
| 1130 internal_error_cb_, | 1288 internal_error_cb_, |
| 1131 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1289 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
| 1132 DemuxerStream::AUDIO))); | 1290 DemuxerStream::AUDIO))); |
| 1133 | 1291 |
| 1134 video_decoder_.reset(new MediaCodecVideoDecoder( | 1292 video_decoder_.reset(new MediaCodecVideoDecoder( |
| 1135 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1293 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
| 1136 media_weak_this_, DemuxerStream::VIDEO), | 1294 media_weak_this_, DemuxerStream::VIDEO), |
| 1137 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1295 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
| 1138 DemuxerStream::VIDEO), | 1296 DemuxerStream::VIDEO), |
| 1139 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, | 1297 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1140 DemuxerStream::VIDEO), | 1298 DemuxerStream::VIDEO), |
| 1141 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, | 1299 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1142 DemuxerStream::VIDEO), | 1300 DemuxerStream::VIDEO), |
| 1301 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, | |
| 1302 DemuxerStream::VIDEO), | |
| 1143 internal_error_cb_, | 1303 internal_error_cb_, |
| 1144 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1304 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
| 1145 DemuxerStream::VIDEO), | 1305 DemuxerStream::VIDEO), |
| 1146 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), | 1306 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), |
| 1147 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); | 1307 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); |
| 1148 } | 1308 } |
| 1149 | 1309 |
| 1150 bool MediaCodecPlayer::AudioFinished() const { | 1310 bool MediaCodecPlayer::AudioFinished() const { |
| 1151 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); | 1311 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); |
| 1152 } | 1312 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1168 return #x; | 1328 return #x; |
| 1169 | 1329 |
| 1170 const char* MediaCodecPlayer::AsString(PlayerState state) { | 1330 const char* MediaCodecPlayer::AsString(PlayerState state) { |
| 1171 switch (state) { | 1331 switch (state) { |
| 1172 RETURN_STRING(kStatePaused); | 1332 RETURN_STRING(kStatePaused); |
| 1173 RETURN_STRING(kStateWaitingForConfig); | 1333 RETURN_STRING(kStateWaitingForConfig); |
| 1174 RETURN_STRING(kStatePrefetching); | 1334 RETURN_STRING(kStatePrefetching); |
| 1175 RETURN_STRING(kStatePlaying); | 1335 RETURN_STRING(kStatePlaying); |
| 1176 RETURN_STRING(kStateStopping); | 1336 RETURN_STRING(kStateStopping); |
| 1177 RETURN_STRING(kStateWaitingForSurface); | 1337 RETURN_STRING(kStateWaitingForSurface); |
| 1338 RETURN_STRING(kStateWaitingForKey); | |
| 1339 RETURN_STRING(kStateWaitingForCrypto); | |
| 1178 RETURN_STRING(kStateWaitingForSeek); | 1340 RETURN_STRING(kStateWaitingForSeek); |
| 1179 RETURN_STRING(kStateError); | 1341 RETURN_STRING(kStateError); |
| 1180 } | 1342 } |
| 1181 return nullptr; // crash early | 1343 return nullptr; // crash early |
| 1182 } | 1344 } |
| 1183 | 1345 |
| 1184 #undef RETURN_STRING | 1346 #undef RETURN_STRING |
| 1185 | 1347 |
| 1186 } // namespace media | 1348 } // namespace media |
| OLD | NEW |