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 |