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 |