Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: media/base/android/media_codec_player.cc

Issue 1344133002: MediaCodecPlayer implementation - stage 7 (DRM) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-drm-prepare
Patch Set: Use MediaCrypto received with callback, never get it directly from MediaDrmBridge Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/android/media_codec_player.h ('k') | media/base/android/media_codec_video_decoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/base/android/media_codec_player.h ('k') | media/base/android/media_codec_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698