| 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" |
| 16 #include "media/base/android/media_drm_proxy.h" |
| 15 #include "media/base/android/media_player_manager.h" | 17 #include "media/base/android/media_player_manager.h" |
| 16 #include "media/base/timestamp_constants.h" | 18 #include "media/base/timestamp_constants.h" |
| 17 | 19 |
| 18 #define RUN_ON_MEDIA_THREAD(METHOD, ...) \ | 20 #define RUN_ON_MEDIA_THREAD(METHOD, ...) \ |
| 19 do { \ | 21 do { \ |
| 20 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \ | 22 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \ |
| 21 DCHECK(ui_task_runner_->BelongsToCurrentThread()); \ | 23 DCHECK(ui_task_runner_->BelongsToCurrentThread()); \ |
| 22 GetMediaTaskRunner()->PostTask( \ | 24 GetMediaTaskRunner()->PostTask( \ |
| 23 FROM_HERE, base::Bind(&MediaCodecPlayer::METHOD, media_weak_this_, \ | 25 FROM_HERE, base::Bind(&MediaCodecPlayer::METHOD, media_weak_this_, \ |
| 24 ##__VA_ARGS__)); \ | 26 ##__VA_ARGS__)); \ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 55 : MediaPlayerAndroid(player_id, | 57 : MediaPlayerAndroid(player_id, |
| 56 manager.get(), | 58 manager.get(), |
| 57 request_media_resources_cb, | 59 request_media_resources_cb, |
| 58 frame_url), | 60 frame_url), |
| 59 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 61 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 60 demuxer_(demuxer.Pass()), | 62 demuxer_(demuxer.Pass()), |
| 61 state_(kStatePaused), | 63 state_(kStatePaused), |
| 62 interpolator_(&default_tick_clock_), | 64 interpolator_(&default_tick_clock_), |
| 63 pending_start_(false), | 65 pending_start_(false), |
| 64 pending_seek_(kNoTimestamp()), | 66 pending_seek_(kNoTimestamp()), |
| 67 drm_bridge_(nullptr), |
| 68 cdm_registration_id_(0), |
| 69 key_is_required_(false), |
| 70 key_is_added_(false), |
| 65 media_weak_factory_(this) { | 71 media_weak_factory_(this) { |
| 66 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 72 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 67 | 73 |
| 68 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; | 74 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; |
| 69 | 75 |
| 70 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id); | 76 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id); |
| 71 | 77 |
| 72 completion_cb_ = | 78 completion_cb_ = |
| 73 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); | 79 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); |
| 74 seek_done_cb_ = | 80 seek_done_cb_ = |
| (...skipping 22 matching lines...) Expand all Loading... |
| 97 | 103 |
| 98 // Currently the unit tests wait for the MediaCodecPlayer destruction by | 104 // Currently the unit tests wait for the MediaCodecPlayer destruction by |
| 99 // watching the demuxer, which is destroyed as one of the member variables. | 105 // 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 | 106 // Release the codecs here, before any member variable is destroyed to make |
| 101 // the unit tests happy. | 107 // the unit tests happy. |
| 102 | 108 |
| 103 if (video_decoder_) | 109 if (video_decoder_) |
| 104 video_decoder_->ReleaseDecoderResources(); | 110 video_decoder_->ReleaseDecoderResources(); |
| 105 if (audio_decoder_) | 111 if (audio_decoder_) |
| 106 audio_decoder_->ReleaseDecoderResources(); | 112 audio_decoder_->ReleaseDecoderResources(); |
| 113 |
| 114 if (drm_bridge_) { |
| 115 DCHECK(cdm_registration_id_); |
| 116 drm_bridge_->UnregisterPlayer(cdm_registration_id_); |
| 117 } |
| 107 } | 118 } |
| 108 | 119 |
| 109 void MediaCodecPlayer::Initialize() { | 120 void MediaCodecPlayer::Initialize() { |
| 110 DVLOG(1) << __FUNCTION__; | 121 DVLOG(1) << __FUNCTION__; |
| 111 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 122 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 112 | 123 |
| 113 interpolator_.SetUpperBound(base::TimeDelta()); | 124 interpolator_.SetUpperBound(base::TimeDelta()); |
| 114 | 125 |
| 115 CreateDecoders(); | 126 CreateDecoders(); |
| 116 | 127 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 } | 227 } |
| 217 break; | 228 break; |
| 218 case kStateStopping: | 229 case kStateStopping: |
| 219 case kStateWaitingForSeek: | 230 case kStateWaitingForSeek: |
| 220 SetPendingStart(true); | 231 SetPendingStart(true); |
| 221 break; | 232 break; |
| 222 case kStateWaitingForConfig: | 233 case kStateWaitingForConfig: |
| 223 case kStatePrefetching: | 234 case kStatePrefetching: |
| 224 case kStatePlaying: | 235 case kStatePlaying: |
| 225 case kStateWaitingForSurface: | 236 case kStateWaitingForSurface: |
| 237 case kStateWaitingForKey: |
| 238 case kStateWaitingForCrypto: |
| 226 case kStateError: | 239 case kStateError: |
| 227 break; // Ignore | 240 break; // Ignore |
| 228 default: | 241 default: |
| 229 NOTREACHED(); | 242 NOTREACHED(); |
| 230 break; | 243 break; |
| 231 } | 244 } |
| 232 } | 245 } |
| 233 | 246 |
| 234 void MediaCodecPlayer::Pause(bool is_media_related_action) { | 247 void MediaCodecPlayer::Pause(bool is_media_related_action) { |
| 235 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action); | 248 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action); |
| 236 | 249 |
| 237 DVLOG(1) << __FUNCTION__; | 250 DVLOG(1) << __FUNCTION__; |
| 238 | 251 |
| 239 SetPendingStart(false); | 252 SetPendingStart(false); |
| 240 | 253 |
| 241 switch (state_) { | 254 switch (state_) { |
| 242 case kStateWaitingForConfig: | 255 case kStateWaitingForConfig: |
| 243 case kStatePrefetching: | 256 case kStatePrefetching: |
| 244 case kStateWaitingForSurface: | 257 case kStateWaitingForSurface: |
| 258 case kStateWaitingForKey: |
| 259 case kStateWaitingForCrypto: |
| 245 SetState(kStatePaused); | 260 SetState(kStatePaused); |
| 246 StopDecoders(); | 261 StopDecoders(); |
| 247 break; | 262 break; |
| 248 case kStatePlaying: | 263 case kStatePlaying: |
| 249 SetState(kStateStopping); | 264 SetState(kStateStopping); |
| 250 RequestToStopDecoders(); | 265 RequestToStopDecoders(); |
| 251 break; | 266 break; |
| 252 case kStatePaused: | 267 case kStatePaused: |
| 253 case kStateStopping: | 268 case kStateStopping: |
| 254 case kStateWaitingForSeek: | 269 case kStateWaitingForSeek: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 266 DVLOG(1) << __FUNCTION__ << " " << timestamp; | 281 DVLOG(1) << __FUNCTION__ << " " << timestamp; |
| 267 | 282 |
| 268 switch (state_) { | 283 switch (state_) { |
| 269 case kStatePaused: | 284 case kStatePaused: |
| 270 SetState(kStateWaitingForSeek); | 285 SetState(kStateWaitingForSeek); |
| 271 RequestDemuxerSeek(timestamp); | 286 RequestDemuxerSeek(timestamp); |
| 272 break; | 287 break; |
| 273 case kStateWaitingForConfig: | 288 case kStateWaitingForConfig: |
| 274 case kStatePrefetching: | 289 case kStatePrefetching: |
| 275 case kStateWaitingForSurface: | 290 case kStateWaitingForSurface: |
| 291 case kStateWaitingForKey: |
| 292 case kStateWaitingForCrypto: |
| 276 SetState(kStateWaitingForSeek); | 293 SetState(kStateWaitingForSeek); |
| 277 StopDecoders(); | 294 StopDecoders(); |
| 278 SetPendingStart(true); | 295 SetPendingStart(true); |
| 279 RequestDemuxerSeek(timestamp); | 296 RequestDemuxerSeek(timestamp); |
| 280 break; | 297 break; |
| 281 case kStatePlaying: | 298 case kStatePlaying: |
| 282 SetState(kStateStopping); | 299 SetState(kStateStopping); |
| 283 RequestToStopDecoders(); | 300 RequestToStopDecoders(); |
| 284 SetPendingStart(true); | 301 SetPendingStart(true); |
| 285 SetPendingSeek(timestamp); | 302 SetPendingSeek(timestamp); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 306 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser | 323 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser |
| 307 // and renderer processes going. Seek should work across and after Release(). | 324 // and renderer processes going. Seek should work across and after Release(). |
| 308 | 325 |
| 309 ReleaseDecoderResources(); | 326 ReleaseDecoderResources(); |
| 310 | 327 |
| 311 SetPendingStart(false); | 328 SetPendingStart(false); |
| 312 | 329 |
| 313 if (state_ != kStateWaitingForSeek) | 330 if (state_ != kStateWaitingForSeek) |
| 314 SetState(kStatePaused); | 331 SetState(kStatePaused); |
| 315 | 332 |
| 333 // Crear encryption key related flags. |
| 334 key_is_required_ = false; |
| 335 key_is_added_ = false; |
| 336 |
| 316 base::TimeDelta pending_seek_time = GetPendingSeek(); | 337 base::TimeDelta pending_seek_time = GetPendingSeek(); |
| 317 if (pending_seek_time != kNoTimestamp()) { | 338 if (pending_seek_time != kNoTimestamp()) { |
| 318 SetPendingSeek(kNoTimestamp()); | 339 SetPendingSeek(kNoTimestamp()); |
| 319 SetState(kStateWaitingForSeek); | 340 SetState(kStateWaitingForSeek); |
| 320 RequestDemuxerSeek(pending_seek_time); | 341 RequestDemuxerSeek(pending_seek_time); |
| 321 } | 342 } |
| 322 } | 343 } |
| 323 | 344 |
| 324 void MediaCodecPlayer::SetVolume(double volume) { | 345 void MediaCodecPlayer::SetVolume(double volume) { |
| 325 RUN_ON_MEDIA_THREAD(SetVolume, volume); | 346 RUN_ON_MEDIA_THREAD(SetVolume, volume); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 } | 396 } |
| 376 | 397 |
| 377 bool MediaCodecPlayer::IsPlayerReady() { | 398 bool MediaCodecPlayer::IsPlayerReady() { |
| 378 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 399 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 379 // This method is called to check whether it's safe to release the player when | 400 // 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. | 401 // the OS needs more resources. This class can be released at any time. |
| 381 return true; | 402 return true; |
| 382 } | 403 } |
| 383 | 404 |
| 384 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) { | 405 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) { |
| 385 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 406 RUN_ON_MEDIA_THREAD(SetCdm, cdm); |
| 386 NOTIMPLEMENTED(); | 407 |
| 408 DVLOG(1) << __FUNCTION__; |
| 409 |
| 410 // Currently we don't support DRM change during the middle of playback, even |
| 411 // if the player is paused. There is no current plan to support it, see |
| 412 // http://crbug.com/253792. |
| 413 if (state_ != kStatePaused || GetInterpolatedTime() > base::TimeDelta()) { |
| 414 VLOG(0) << "Setting DRM bridge after playback has started is not supported"; |
| 415 return; |
| 416 } |
| 417 |
| 418 if (drm_bridge_) { |
| 419 NOTREACHED() << "Currently we do not support resetting CDM."; |
| 420 return; |
| 421 } |
| 422 |
| 423 DCHECK(cdm); |
| 424 MediaDrmProxy* drm_proxy = static_cast<MediaDrmProxy*>(cdm); |
| 425 drm_bridge_ = drm_proxy->GetDrmBridge(); |
| 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 return; |
| 665 } |
| 666 |
| 607 SetState(kStatePlaying); | 667 SetState(kStatePlaying); |
| 608 StartPlaybackOrBrowserSeek(); | 668 StartPlaybackOrBrowserSeek(); |
| 609 } | 669 } |
| 610 | 670 |
| 611 void MediaCodecPlayer::OnPrerollDone() { | 671 void MediaCodecPlayer::OnPrerollDone() { |
| 612 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 672 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 613 | 673 |
| 614 if (state_ != kStatePlaying) { | 674 if (state_ != kStatePlaying) { |
| 615 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_) | 675 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_) |
| 616 << ", ignoring"; | 676 << ", ignoring"; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 return; | 770 return; |
| 711 } | 771 } |
| 712 | 772 |
| 713 // DetachListener to UI thread | 773 // DetachListener to UI thread |
| 714 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); | 774 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); |
| 715 | 775 |
| 716 if (AudioFinished() && VideoFinished()) | 776 if (AudioFinished() && VideoFinished()) |
| 717 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); | 777 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); |
| 718 } | 778 } |
| 719 | 779 |
| 780 void MediaCodecPlayer::OnKeyRequired(DemuxerStream::Type type) { |
| 781 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 782 DVLOG(1) << __FUNCTION__ << " " << type; |
| 783 |
| 784 // Request stop and restart to pick up the key. |
| 785 key_is_required_ = true; |
| 786 |
| 787 if (state_ == kStatePlaying) { |
| 788 SetState(kStateStopping); |
| 789 RequestToStopDecoders(); |
| 790 SetPendingStart(true); |
| 791 } |
| 792 } |
| 793 |
| 720 void MediaCodecPlayer::OnError() { | 794 void MediaCodecPlayer::OnError() { |
| 721 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 795 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 722 DVLOG(1) << __FUNCTION__; | 796 DVLOG(1) << __FUNCTION__; |
| 723 | 797 |
| 724 // kStateError blocks all events | 798 // kStateError blocks all events |
| 725 SetState(kStateError); | 799 SetState(kStateError); |
| 726 | 800 |
| 727 ReleaseDecoderResources(); | 801 ReleaseDecoderResources(); |
| 728 | 802 |
| 729 ui_task_runner_->PostTask(FROM_HERE, | 803 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) { | 867 void MediaCodecPlayer::OnVideoResolutionChanged(const gfx::Size& size) { |
| 794 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 868 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 795 | 869 |
| 796 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height(); | 870 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height(); |
| 797 | 871 |
| 798 // Update cache and notify manager on UI thread | 872 // Update cache and notify manager on UI thread |
| 799 ui_task_runner_->PostTask( | 873 ui_task_runner_->PostTask( |
| 800 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size)); | 874 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size)); |
| 801 } | 875 } |
| 802 | 876 |
| 877 // Callbacks from DRM |
| 878 |
| 879 void MediaCodecPlayer::OnMediaCryptoReady() { |
| 880 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 881 DVLOG(1) << __FUNCTION__; |
| 882 |
| 883 DCHECK(drm_bridge_); |
| 884 DCHECK(!drm_bridge_->GetMediaCrypto().is_null()); |
| 885 drm_bridge_->SetMediaCryptoReadyCB(base::Closure()); |
| 886 |
| 887 if (state_ == kStateWaitingForCrypto) { |
| 888 // Resume decoders creation. |
| 889 SetState(kStatePlaying); |
| 890 StartPlaybackOrBrowserSeek(); |
| 891 } |
| 892 |
| 893 DVLOG(1) << __FUNCTION__ << " end"; |
| 894 } |
| 895 |
| 896 void MediaCodecPlayer::OnKeyAdded() { |
| 897 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 898 DVLOG(1) << __FUNCTION__; |
| 899 |
| 900 key_is_added_ = true; |
| 901 |
| 902 if (state_ == kStateWaitingForKey) { |
| 903 SetState(kStatePlaying); |
| 904 StartPlaybackOrBrowserSeek(); |
| 905 } |
| 906 } |
| 907 |
| 908 void MediaCodecPlayer::OnCdmUnset() { |
| 909 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 910 DVLOG(1) << __FUNCTION__; |
| 911 |
| 912 // This comment is copied from MediaSourcePlayer::OnCdmUnset(). |
| 913 // TODO(xhwang): Currently this is only called during teardown. Support full |
| 914 // detachment of CDM during playback. This will be needed when we start to |
| 915 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release |
| 916 // MediaDrm when the video is paused, or when the device goes to sleep (see |
| 917 // http://crbug.com/272421). |
| 918 |
| 919 if (audio_decoder_) |
| 920 audio_decoder_->SetDrmBridge(nullptr); |
| 921 if (video_decoder_) |
| 922 video_decoder_->SetDrmBridge(nullptr); |
| 923 |
| 924 cdm_registration_id_ = 0; |
| 925 drm_bridge_ = nullptr; |
| 926 } |
| 927 |
| 803 // State machine operations, called on Media thread | 928 // State machine operations, called on Media thread |
| 804 | 929 |
| 805 void MediaCodecPlayer::SetState(PlayerState new_state) { | 930 void MediaCodecPlayer::SetState(PlayerState new_state) { |
| 806 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 931 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 807 | 932 |
| 808 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); | 933 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); |
| 809 state_ = new_state; | 934 state_ = new_state; |
| 810 } | 935 } |
| 811 | 936 |
| 812 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { | 937 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); | 1017 video_decoder_->Prefetch(prefetch_cb); |
| 893 } | 1018 } |
| 894 | 1019 |
| 895 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() { | 1020 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() { |
| 896 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1021 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 897 DVLOG(1) << __FUNCTION__; | 1022 DVLOG(1) << __FUNCTION__; |
| 898 | 1023 |
| 899 // TODO(timav): consider replacing this method with posting a | 1024 // TODO(timav): consider replacing this method with posting a |
| 900 // browser seek task (i.e. generate an event) from StartPlaybackDecoders(). | 1025 // browser seek task (i.e. generate an event) from StartPlaybackDecoders(). |
| 901 | 1026 |
| 1027 // Clear encryption key related flags. |
| 1028 key_is_required_ = false; |
| 1029 key_is_added_ = false; |
| 1030 |
| 902 StartStatus status = StartPlaybackDecoders(); | 1031 StartStatus status = StartPlaybackDecoders(); |
| 903 | 1032 |
| 904 switch (status) { | 1033 switch (status) { |
| 905 case kStartBrowserSeekRequired: | 1034 case kStartBrowserSeekRequired: |
| 906 // Browser seek | 1035 // Browser seek |
| 907 SetState(kStateWaitingForSeek); | 1036 SetState(kStateWaitingForSeek); |
| 908 SetPendingStart(true); | 1037 SetPendingStart(true); |
| 909 StopDecoders(); | 1038 StopDecoders(); |
| 910 RequestDemuxerSeek(GetInterpolatedTime(), true); | 1039 RequestDemuxerSeek(GetInterpolatedTime(), true); |
| 911 break; | 1040 break; |
| 1041 case kStartCryptoRequired: |
| 1042 SetState(kStateWaitingForCrypto); |
| 1043 break; |
| 912 case kStartFailed: | 1044 case kStartFailed: |
| 913 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); | 1045 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); |
| 914 break; | 1046 break; |
| 915 case kStartOk: | 1047 case kStartOk: |
| 916 break; | 1048 break; |
| 917 } | 1049 } |
| 918 } | 1050 } |
| 919 | 1051 |
| 920 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() { | 1052 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() { |
| 921 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1053 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 939 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1071 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 940 DVLOG(1) << __FUNCTION__; | 1072 DVLOG(1) << __FUNCTION__; |
| 941 | 1073 |
| 942 const bool do_audio = !AudioFinished(); | 1074 const bool do_audio = !AudioFinished(); |
| 943 const bool do_video = !VideoFinished(); | 1075 const bool do_video = !VideoFinished(); |
| 944 | 1076 |
| 945 // If there is nothing to play, the state machine should determine this at the | 1077 // If there is nothing to play, the state machine should determine this at the |
| 946 // prefetch state and never call this method. | 1078 // prefetch state and never call this method. |
| 947 DCHECK(do_audio || do_video); | 1079 DCHECK(do_audio || do_video); |
| 948 | 1080 |
| 949 // Start with video: if browser seek is required it would | 1081 // Start with video: if browser seek is required it would not make sense to |
| 950 // not make sense to configure audio. | 1082 // configure audio. |
| 951 | 1083 |
| 952 if (do_video) { | 1084 MediaCodecDecoder::ConfigStatus status = MediaCodecDecoder::kConfigOk; |
| 953 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure(); | 1085 if (do_video) |
| 954 switch (status) { | 1086 status = video_decoder_->Configure(); |
| 955 case MediaCodecDecoder::kConfigOk: | 1087 |
| 956 break; | 1088 if (status == MediaCodecDecoder::kConfigOk && do_audio) |
| 957 case MediaCodecDecoder::kConfigKeyFrameRequired: | 1089 status = audio_decoder_->Configure(); |
| 958 // TODO(timav): post a task or return the status? | 1090 |
| 959 return kStartBrowserSeekRequired; | 1091 switch (status) { |
| 960 case MediaCodecDecoder::kConfigFailure: | 1092 case MediaCodecDecoder::kConfigOk: |
| 961 return kStartFailed; | 1093 break; |
| 962 } | 1094 case MediaCodecDecoder::kConfigKeyFrameRequired: |
| 1095 return kStartBrowserSeekRequired; |
| 1096 case MediaCodecDecoder::kConfigNoCrypto: |
| 1097 return kStartCryptoRequired; |
| 1098 case MediaCodecDecoder::kConfigFailure: |
| 1099 return kStartFailed; |
| 963 } | 1100 } |
| 964 | |
| 965 if (do_audio) { | |
| 966 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); | |
| 967 if (status != MediaCodecDecoder::kConfigOk) { | |
| 968 return kStartFailed; | |
| 969 } | |
| 970 } | |
| 971 | |
| 972 return kStartOk; | 1101 return kStartOk; |
| 973 } | 1102 } |
| 974 | 1103 |
| 975 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( | 1104 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( |
| 976 bool* preroll_required) { | 1105 bool* preroll_required) { |
| 977 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1106 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 978 | 1107 |
| 979 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime(); | 1108 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime(); |
| 980 | 1109 |
| 981 // If requested, preroll is always done in the beginning of the playback, | 1110 // 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 | 1249 |
| 1121 audio_decoder_.reset(new MediaCodecAudioDecoder( | 1250 audio_decoder_.reset(new MediaCodecAudioDecoder( |
| 1122 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1251 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
| 1123 media_weak_this_, DemuxerStream::AUDIO), | 1252 media_weak_this_, DemuxerStream::AUDIO), |
| 1124 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1253 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
| 1125 DemuxerStream::AUDIO), | 1254 DemuxerStream::AUDIO), |
| 1126 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, | 1255 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1127 DemuxerStream::AUDIO), | 1256 DemuxerStream::AUDIO), |
| 1128 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, | 1257 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1129 DemuxerStream::AUDIO), | 1258 DemuxerStream::AUDIO), |
| 1259 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, |
| 1260 DemuxerStream::AUDIO), |
| 1130 internal_error_cb_, | 1261 internal_error_cb_, |
| 1131 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1262 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
| 1132 DemuxerStream::AUDIO))); | 1263 DemuxerStream::AUDIO))); |
| 1133 | 1264 |
| 1134 video_decoder_.reset(new MediaCodecVideoDecoder( | 1265 video_decoder_.reset(new MediaCodecVideoDecoder( |
| 1135 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1266 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
| 1136 media_weak_this_, DemuxerStream::VIDEO), | 1267 media_weak_this_, DemuxerStream::VIDEO), |
| 1137 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1268 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
| 1138 DemuxerStream::VIDEO), | 1269 DemuxerStream::VIDEO), |
| 1139 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, | 1270 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1140 DemuxerStream::VIDEO), | 1271 DemuxerStream::VIDEO), |
| 1141 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, | 1272 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1142 DemuxerStream::VIDEO), | 1273 DemuxerStream::VIDEO), |
| 1274 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, |
| 1275 DemuxerStream::VIDEO), |
| 1143 internal_error_cb_, | 1276 internal_error_cb_, |
| 1144 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1277 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
| 1145 DemuxerStream::VIDEO), | 1278 DemuxerStream::VIDEO), |
| 1146 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), | 1279 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), |
| 1147 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); | 1280 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); |
| 1148 } | 1281 } |
| 1149 | 1282 |
| 1150 bool MediaCodecPlayer::AudioFinished() const { | 1283 bool MediaCodecPlayer::AudioFinished() const { |
| 1151 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); | 1284 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); |
| 1152 } | 1285 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1168 return #x; | 1301 return #x; |
| 1169 | 1302 |
| 1170 const char* MediaCodecPlayer::AsString(PlayerState state) { | 1303 const char* MediaCodecPlayer::AsString(PlayerState state) { |
| 1171 switch (state) { | 1304 switch (state) { |
| 1172 RETURN_STRING(kStatePaused); | 1305 RETURN_STRING(kStatePaused); |
| 1173 RETURN_STRING(kStateWaitingForConfig); | 1306 RETURN_STRING(kStateWaitingForConfig); |
| 1174 RETURN_STRING(kStatePrefetching); | 1307 RETURN_STRING(kStatePrefetching); |
| 1175 RETURN_STRING(kStatePlaying); | 1308 RETURN_STRING(kStatePlaying); |
| 1176 RETURN_STRING(kStateStopping); | 1309 RETURN_STRING(kStateStopping); |
| 1177 RETURN_STRING(kStateWaitingForSurface); | 1310 RETURN_STRING(kStateWaitingForSurface); |
| 1311 RETURN_STRING(kStateWaitingForKey); |
| 1312 RETURN_STRING(kStateWaitingForCrypto); |
| 1178 RETURN_STRING(kStateWaitingForSeek); | 1313 RETURN_STRING(kStateWaitingForSeek); |
| 1179 RETURN_STRING(kStateError); | 1314 RETURN_STRING(kStateError); |
| 1180 } | 1315 } |
| 1181 return nullptr; // crash early | 1316 return nullptr; // crash early |
| 1182 } | 1317 } |
| 1183 | 1318 |
| 1184 #undef RETURN_STRING | 1319 #undef RETURN_STRING |
| 1185 | 1320 |
| 1186 } // namespace media | 1321 } // namespace media |
| OLD | NEW |