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

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: Repost SetMediaCryptoReadyCB on UI thread, further cleanup 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
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 is_protected_surface_required_(false),
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);
80 key_required_cb_ = base::Bind(&MediaPlayerManager::OnWaitingForDecryptionKey,
81 manager, player_id);
74 seek_done_cb_ = 82 seek_done_cb_ =
75 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id); 83 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id);
76 error_cb_ = base::Bind(&MediaPlayerManager::OnError, manager, player_id); 84 error_cb_ = base::Bind(&MediaPlayerManager::OnError, manager, player_id);
77 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener, 85 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener,
78 WeakPtrForUIThread(), nullptr); 86 WeakPtrForUIThread(), nullptr);
79 detach_listener_cb_ = 87 detach_listener_cb_ =
80 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread()); 88 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread());
81 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged, 89 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged,
82 WeakPtrForUIThread()); 90 WeakPtrForUIThread());
83 time_update_cb_ = 91 time_update_cb_ =
(...skipping 13 matching lines...) Expand all
97 105
98 // Currently the unit tests wait for the MediaCodecPlayer destruction by 106 // Currently the unit tests wait for the MediaCodecPlayer destruction by
99 // watching the demuxer, which is destroyed as one of the member variables. 107 // 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 108 // Release the codecs here, before any member variable is destroyed to make
101 // the unit tests happy. 109 // the unit tests happy.
102 110
103 if (video_decoder_) 111 if (video_decoder_)
104 video_decoder_->ReleaseDecoderResources(); 112 video_decoder_->ReleaseDecoderResources();
105 if (audio_decoder_) 113 if (audio_decoder_)
106 audio_decoder_->ReleaseDecoderResources(); 114 audio_decoder_->ReleaseDecoderResources();
115
116 if (drm_bridge_) {
117 DCHECK(cdm_registration_id_);
118 drm_bridge_->UnregisterPlayer(cdm_registration_id_);
119 }
107 } 120 }
108 121
109 void MediaCodecPlayer::Initialize() { 122 void MediaCodecPlayer::Initialize() {
110 DVLOG(1) << __FUNCTION__; 123 DVLOG(1) << __FUNCTION__;
111 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 124 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
112 125
113 interpolator_.SetUpperBound(base::TimeDelta()); 126 interpolator_.SetUpperBound(base::TimeDelta());
114 127
115 CreateDecoders(); 128 CreateDecoders();
116 129
(...skipping 27 matching lines...) Expand all
144 // Save the empty-ness before we pass the surface to the decoder. 157 // Save the empty-ness before we pass the surface to the decoder.
145 bool surface_is_empty = surface.IsEmpty(); 158 bool surface_is_empty = surface.IsEmpty();
146 159
147 // Apparently RemoveVideoSurface() can be called several times in a row, 160 // Apparently RemoveVideoSurface() can be called several times in a row,
148 // ignore the second and subsequent calls. 161 // ignore the second and subsequent calls.
149 if (surface_is_empty && !video_decoder_->HasVideoSurface()) { 162 if (surface_is_empty && !video_decoder_->HasVideoSurface()) {
150 DVLOG(1) << __FUNCTION__ << ": surface already removed, ignoring"; 163 DVLOG(1) << __FUNCTION__ << ": surface already removed, ignoring";
151 return; 164 return;
152 } 165 }
153 166
167 // Do not set unprotected surface if we know that we need a protected one.
168 // Empty surface means the surface removal and we always allow for it.
169 if (!surface_is_empty && is_protected_surface_required_ &&
170 !surface.is_protected()) {
171 DVLOG(0) << __FUNCTION__ << ": surface is not protected, ignoring";
172 return;
173 }
174
154 video_decoder_->SetVideoSurface(surface.Pass()); 175 video_decoder_->SetVideoSurface(surface.Pass());
155 176
156 if (surface_is_empty) { 177 if (surface_is_empty) {
157 // Remove video surface. 178 // Remove video surface.
158 switch (state_) { 179 switch (state_) {
159 case kStatePlaying: 180 case kStatePlaying:
160 if (VideoFinished()) 181 if (VideoFinished())
161 break; 182 break;
162 183
163 DVLOG(1) << __FUNCTION__ << ": stopping and restarting"; 184 DVLOG(1) << __FUNCTION__ << ": stopping and restarting";
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } 237 }
217 break; 238 break;
218 case kStateStopping: 239 case kStateStopping:
219 case kStateWaitingForSeek: 240 case kStateWaitingForSeek:
220 SetPendingStart(true); 241 SetPendingStart(true);
221 break; 242 break;
222 case kStateWaitingForConfig: 243 case kStateWaitingForConfig:
223 case kStatePrefetching: 244 case kStatePrefetching:
224 case kStatePlaying: 245 case kStatePlaying:
225 case kStateWaitingForSurface: 246 case kStateWaitingForSurface:
247 case kStateWaitingForKey:
248 case kStateWaitingForCrypto:
226 case kStateError: 249 case kStateError:
227 break; // Ignore 250 break; // Ignore
228 default: 251 default:
229 NOTREACHED(); 252 NOTREACHED();
230 break; 253 break;
231 } 254 }
232 } 255 }
233 256
234 void MediaCodecPlayer::Pause(bool is_media_related_action) { 257 void MediaCodecPlayer::Pause(bool is_media_related_action) {
235 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action); 258 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action);
236 259
237 DVLOG(1) << __FUNCTION__; 260 DVLOG(1) << __FUNCTION__;
238 261
239 SetPendingStart(false); 262 SetPendingStart(false);
240 263
241 switch (state_) { 264 switch (state_) {
242 case kStateWaitingForConfig: 265 case kStateWaitingForConfig:
243 case kStatePrefetching: 266 case kStatePrefetching:
244 case kStateWaitingForSurface: 267 case kStateWaitingForSurface:
268 case kStateWaitingForKey:
269 case kStateWaitingForCrypto:
245 SetState(kStatePaused); 270 SetState(kStatePaused);
246 StopDecoders(); 271 StopDecoders();
247 break; 272 break;
248 case kStatePlaying: 273 case kStatePlaying:
249 SetState(kStateStopping); 274 SetState(kStateStopping);
250 RequestToStopDecoders(); 275 RequestToStopDecoders();
251 break; 276 break;
252 case kStatePaused: 277 case kStatePaused:
253 case kStateStopping: 278 case kStateStopping:
254 case kStateWaitingForSeek: 279 case kStateWaitingForSeek:
(...skipping 11 matching lines...) Expand all
266 DVLOG(1) << __FUNCTION__ << " " << timestamp; 291 DVLOG(1) << __FUNCTION__ << " " << timestamp;
267 292
268 switch (state_) { 293 switch (state_) {
269 case kStatePaused: 294 case kStatePaused:
270 SetState(kStateWaitingForSeek); 295 SetState(kStateWaitingForSeek);
271 RequestDemuxerSeek(timestamp); 296 RequestDemuxerSeek(timestamp);
272 break; 297 break;
273 case kStateWaitingForConfig: 298 case kStateWaitingForConfig:
274 case kStatePrefetching: 299 case kStatePrefetching:
275 case kStateWaitingForSurface: 300 case kStateWaitingForSurface:
301 case kStateWaitingForKey:
302 case kStateWaitingForCrypto:
276 SetState(kStateWaitingForSeek); 303 SetState(kStateWaitingForSeek);
277 StopDecoders(); 304 StopDecoders();
278 SetPendingStart(true); 305 SetPendingStart(true);
279 RequestDemuxerSeek(timestamp); 306 RequestDemuxerSeek(timestamp);
280 break; 307 break;
281 case kStatePlaying: 308 case kStatePlaying:
282 SetState(kStateStopping); 309 SetState(kStateStopping);
283 RequestToStopDecoders(); 310 RequestToStopDecoders();
284 SetPendingStart(true); 311 SetPendingStart(true);
285 SetPendingSeek(timestamp); 312 SetPendingSeek(timestamp);
(...skipping 20 matching lines...) Expand all
306 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser 333 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser
307 // and renderer processes going. Seek should work across and after Release(). 334 // and renderer processes going. Seek should work across and after Release().
308 335
309 ReleaseDecoderResources(); 336 ReleaseDecoderResources();
310 337
311 SetPendingStart(false); 338 SetPendingStart(false);
312 339
313 if (state_ != kStateWaitingForSeek) 340 if (state_ != kStateWaitingForSeek)
314 SetState(kStatePaused); 341 SetState(kStatePaused);
315 342
343 // Crear encryption key related flags.
344 key_is_required_ = false;
345 key_is_added_ = false;
346
316 base::TimeDelta pending_seek_time = GetPendingSeek(); 347 base::TimeDelta pending_seek_time = GetPendingSeek();
317 if (pending_seek_time != kNoTimestamp()) { 348 if (pending_seek_time != kNoTimestamp()) {
318 SetPendingSeek(kNoTimestamp()); 349 SetPendingSeek(kNoTimestamp());
319 SetState(kStateWaitingForSeek); 350 SetState(kStateWaitingForSeek);
320 RequestDemuxerSeek(pending_seek_time); 351 RequestDemuxerSeek(pending_seek_time);
321 } 352 }
322 } 353 }
323 354
324 void MediaCodecPlayer::SetVolume(double volume) { 355 void MediaCodecPlayer::SetVolume(double volume) {
325 RUN_ON_MEDIA_THREAD(SetVolume, volume); 356 RUN_ON_MEDIA_THREAD(SetVolume, volume);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 406 }
376 407
377 bool MediaCodecPlayer::IsPlayerReady() { 408 bool MediaCodecPlayer::IsPlayerReady() {
378 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 409 DCHECK(ui_task_runner_->BelongsToCurrentThread());
379 // This method is called to check whether it's safe to release the player when 410 // 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. 411 // the OS needs more resources. This class can be released at any time.
381 return true; 412 return true;
382 } 413 }
383 414
384 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) { 415 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) {
385 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 416 RUN_ON_MEDIA_THREAD(SetCdm, cdm);
386 NOTIMPLEMENTED(); 417
418 DVLOG(1) << __FUNCTION__;
419
420 // Currently we don't support DRM change during the middle of playback, even
421 // if the player is paused. There is no current plan to support it, see
422 // http://crbug.com/253792.
423 if (state_ != kStatePaused || GetInterpolatedTime() > base::TimeDelta()) {
424 VLOG(0) << "Setting DRM bridge after playback has started is not supported";
425 return;
426 }
427
428 if (drm_bridge_) {
429 NOTREACHED() << "Currently we do not support resetting CDM.";
430 return;
431 }
432
433 DCHECK(cdm);
434 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm);
435
436 DCHECK(drm_bridge_);
437
438 cdm_registration_id_ = drm_bridge_->RegisterPlayer(
439 base::Bind(&MediaCodecPlayer::OnKeyAdded, media_weak_this_),
440 base::Bind(&MediaCodecPlayer::OnCdmUnset, media_weak_this_));
441
442 // We assume this property never changes so we can ask it here and use later.
443 // TODO(timav): This value can be passed with MediaCryptoReadyCB.
444 is_protected_surface_required_ = drm_bridge_->IsProtectedSurfaceRequired();
445
446 // If the crypto is ready by this time, OnMediaCryptoReady will be posted
447 // right away.
448 // drm_bridge_->SetMediaCryptoReadyCB(
449 // base::Bind(&MediaCodecPlayer::OnMediaCryptoReady, media_weak_this_));
450
451 MediaDrmBridge::MediaCryptoReadyCB cb =
452 base::Bind(&MediaCodecPlayer::OnMediaCryptoReady, media_weak_this_);
453
454 // Post back to UI thread?
455 // TODO(timav): We need weak ptr for UI thread.
456 ui_task_runner_->PostTask(FROM_HERE,
457 base::Bind(&MediaDrmBridge::SetMediaCryptoReadyCB,
458 base::Unretained(drm_bridge_), cb));
387 } 459 }
388 460
389 // Callbacks from Demuxer. 461 // Callbacks from Demuxer.
390 462
391 void MediaCodecPlayer::OnDemuxerConfigsAvailable( 463 void MediaCodecPlayer::OnDemuxerConfigsAvailable(
392 const DemuxerConfigs& configs) { 464 const DemuxerConfigs& configs) {
393 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 465 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
394 466
395 DVLOG(1) << __FUNCTION__; 467 DVLOG(1) << __FUNCTION__;
396 468
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 DCHECK(!internal_error_cb_.is_null()); 669 DCHECK(!internal_error_cb_.is_null());
598 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); 670 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
599 return; 671 return;
600 } 672 }
601 673
602 if (HasVideo() && !video_decoder_->HasVideoSurface()) { 674 if (HasVideo() && !video_decoder_->HasVideoSurface()) {
603 SetState(kStateWaitingForSurface); 675 SetState(kStateWaitingForSurface);
604 return; 676 return;
605 } 677 }
606 678
679 if (key_is_required_ && !key_is_added_) {
680 SetState(kStateWaitingForKey);
681 ui_task_runner_->PostTask(FROM_HERE, key_required_cb_);
682 return;
683 }
684
607 SetState(kStatePlaying); 685 SetState(kStatePlaying);
608 StartPlaybackOrBrowserSeek(); 686 StartPlaybackOrBrowserSeek();
609 } 687 }
610 688
611 void MediaCodecPlayer::OnPrerollDone() { 689 void MediaCodecPlayer::OnPrerollDone() {
612 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 690 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
613 691
614 if (state_ != kStatePlaying) { 692 if (state_ != kStatePlaying) {
615 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_) 693 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_)
616 << ", ignoring"; 694 << ", ignoring";
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 return; 788 return;
711 } 789 }
712 790
713 // DetachListener to UI thread 791 // DetachListener to UI thread
714 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); 792 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_);
715 793
716 if (AudioFinished() && VideoFinished()) 794 if (AudioFinished() && VideoFinished())
717 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); 795 ui_task_runner_->PostTask(FROM_HERE, completion_cb_);
718 } 796 }
719 797
798 void MediaCodecPlayer::OnKeyRequired(DemuxerStream::Type type) {
799 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
800 DVLOG(1) << __FUNCTION__ << " " << type;
801
802 // Request stop and restart to pick up the key.
803 key_is_required_ = true;
804
805 if (state_ == kStatePlaying) {
806 SetState(kStateStopping);
807 RequestToStopDecoders();
808 SetPendingStart(true);
809 }
810 }
811
720 void MediaCodecPlayer::OnError() { 812 void MediaCodecPlayer::OnError() {
721 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 813 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
722 DVLOG(1) << __FUNCTION__; 814 DVLOG(1) << __FUNCTION__;
723 815
724 // kStateError blocks all events 816 // kStateError blocks all events
725 SetState(kStateError); 817 SetState(kStateError);
726 818
727 ReleaseDecoderResources(); 819 ReleaseDecoderResources();
728 820
729 ui_task_runner_->PostTask(FROM_HERE, 821 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) { 885 void MediaCodecPlayer::OnVideoResolutionChanged(const gfx::Size& size) {
794 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 886 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
795 887
796 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height(); 888 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height();
797 889
798 // Update cache and notify manager on UI thread 890 // Update cache and notify manager on UI thread
799 ui_task_runner_->PostTask( 891 ui_task_runner_->PostTask(
800 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size)); 892 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size));
801 } 893 }
802 894
895 // Callbacks from DRM
896
897 void MediaCodecPlayer::OnMediaCryptoReady(
898 MediaDrmBridge::JavaObjectPtr media_crypto) {
899 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
900 DVLOG(1) << __FUNCTION__;
901
902 // We receive the MediaCrypto global reference with this callback and use it
903 // later for all subsequent configurations. This is possible only if the
904 // MediaCrypto object remains valid until new SetCdm() is called.
905
906 DCHECK(media_crypto);
907 DCHECK(!media_crypto->is_null());
908
909 media_crypto_ = media_crypto.Pass();
910
911 if (audio_decoder_) {
912 audio_decoder_->SetNeedsReconfigure();
913 }
914
915 if (video_decoder_) {
916 video_decoder_->SetNeedsReconfigure();
917 video_decoder_->SetProtectedSurfaceRequired(is_protected_surface_required_);
918 }
919
920 if (state_ == kStateWaitingForCrypto) {
921 // Resume start sequence (configure, etc.)
922 SetState(kStatePlaying);
923 StartPlaybackOrBrowserSeek();
924 }
925
926 DVLOG(1) << __FUNCTION__ << " end";
927 }
928
929 void MediaCodecPlayer::OnKeyAdded() {
930 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
931 DVLOG(1) << __FUNCTION__;
932
933 key_is_added_ = true;
934
935 if (state_ == kStateWaitingForKey) {
936 SetState(kStatePlaying);
937 StartPlaybackOrBrowserSeek();
938 }
939 }
940
941 void MediaCodecPlayer::OnCdmUnset() {
942 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
943 DVLOG(1) << __FUNCTION__;
944
945 // This comment is copied from MediaSourcePlayer::OnCdmUnset().
946 // TODO(xhwang): Currently this is only called during teardown. Support full
947 // detachment of CDM during playback. This will be needed when we start to
948 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release
949 // MediaDrm when the video is paused, or when the device goes to sleep (see
950 // http://crbug.com/272421).
951
952 if (audio_decoder_) {
953 audio_decoder_->SetNeedsReconfigure();
954 }
955
956 if (video_decoder_) {
957 video_decoder_->SetProtectedSurfaceRequired(false);
958 video_decoder_->SetNeedsReconfigure();
959 }
960
961 cdm_registration_id_ = 0;
962 is_protected_surface_required_ = false;
963 drm_bridge_ = nullptr;
964 media_crypto_.reset();
965 }
966
803 // State machine operations, called on Media thread 967 // State machine operations, called on Media thread
804 968
805 void MediaCodecPlayer::SetState(PlayerState new_state) { 969 void MediaCodecPlayer::SetState(PlayerState new_state) {
806 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 970 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
807 971
808 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); 972 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state);
809 state_ = new_state; 973 state_ = new_state;
810 } 974 }
811 975
812 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { 976 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); 1056 video_decoder_->Prefetch(prefetch_cb);
893 } 1057 }
894 1058
895 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() { 1059 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() {
896 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1060 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
897 DVLOG(1) << __FUNCTION__; 1061 DVLOG(1) << __FUNCTION__;
898 1062
899 // TODO(timav): consider replacing this method with posting a 1063 // TODO(timav): consider replacing this method with posting a
900 // browser seek task (i.e. generate an event) from StartPlaybackDecoders(). 1064 // browser seek task (i.e. generate an event) from StartPlaybackDecoders().
901 1065
1066 // Clear encryption key related flags.
1067 key_is_required_ = false;
1068 key_is_added_ = false;
1069
902 StartStatus status = StartPlaybackDecoders(); 1070 StartStatus status = StartPlaybackDecoders();
903 1071
904 switch (status) { 1072 switch (status) {
905 case kStartBrowserSeekRequired: 1073 case kStartBrowserSeekRequired:
906 // Browser seek 1074 // Browser seek
907 SetState(kStateWaitingForSeek); 1075 SetState(kStateWaitingForSeek);
908 SetPendingStart(true); 1076 SetPendingStart(true);
909 StopDecoders(); 1077 StopDecoders();
910 RequestDemuxerSeek(GetInterpolatedTime(), true); 1078 RequestDemuxerSeek(GetInterpolatedTime(), true);
911 break; 1079 break;
1080 case kStartCryptoRequired:
1081 SetState(kStateWaitingForCrypto);
1082 break;
912 case kStartFailed: 1083 case kStartFailed:
913 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); 1084 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
914 break; 1085 break;
915 case kStartOk: 1086 case kStartOk:
916 break; 1087 break;
917 } 1088 }
918 } 1089 }
919 1090
920 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() { 1091 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() {
921 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1092 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
(...skipping 17 matching lines...) Expand all
939 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1110 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
940 DVLOG(1) << __FUNCTION__; 1111 DVLOG(1) << __FUNCTION__;
941 1112
942 const bool do_audio = !AudioFinished(); 1113 const bool do_audio = !AudioFinished();
943 const bool do_video = !VideoFinished(); 1114 const bool do_video = !VideoFinished();
944 1115
945 // If there is nothing to play, the state machine should determine this at the 1116 // If there is nothing to play, the state machine should determine this at the
946 // prefetch state and never call this method. 1117 // prefetch state and never call this method.
947 DCHECK(do_audio || do_video); 1118 DCHECK(do_audio || do_video);
948 1119
949 // Start with video: if browser seek is required it would 1120 bool need_crypto = (do_audio && audio_decoder_->IsContentEncrypted()) ||
950 // not make sense to configure audio. 1121 (do_video && video_decoder_->IsContentEncrypted());
951 1122
952 if (do_video) { 1123 // Do we need to create a local ref from the global ref?
953 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure(); 1124 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr;
954 switch (status) { 1125
955 case MediaCodecDecoder::kConfigOk: 1126 if (need_crypto) {
956 break; 1127 DVLOG(1) << (audio_decoder_->IsContentEncrypted() ? " audio" : "")
957 case MediaCodecDecoder::kConfigKeyFrameRequired: 1128 << (video_decoder_->IsContentEncrypted() ? " video" : "")
958 // TODO(timav): post a task or return the status? 1129 << " need(s) encryption";
959 return kStartBrowserSeekRequired; 1130 if (!media_crypto) {
960 case MediaCodecDecoder::kConfigFailure: 1131 DVLOG(1) << __FUNCTION__ << ": MediaCrypto is not found, returning";
961 return kStartFailed; 1132 return kStartCryptoRequired;
962 } 1133 }
963 } 1134 }
964 1135
965 if (do_audio) { 1136 // Start with video: if browser seek is required it would not make sense to
966 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); 1137 // configure audio.
967 if (status != MediaCodecDecoder::kConfigOk) { 1138
1139 MediaCodecDecoder::ConfigStatus status = MediaCodecDecoder::kConfigOk;
1140 if (do_video)
1141 status = video_decoder_->Configure(media_crypto);
1142
1143 if (status == MediaCodecDecoder::kConfigOk && do_audio)
1144 status = audio_decoder_->Configure(media_crypto);
1145
1146 switch (status) {
1147 case MediaCodecDecoder::kConfigOk:
1148 break;
1149 case MediaCodecDecoder::kConfigKeyFrameRequired:
1150 return kStartBrowserSeekRequired;
1151 case MediaCodecDecoder::kConfigNoCrypto: // TODO: delete this
1152 return kStartCryptoRequired;
1153 case MediaCodecDecoder::kConfigFailure:
968 return kStartFailed; 1154 return kStartFailed;
969 }
970 } 1155 }
971
972 return kStartOk; 1156 return kStartOk;
973 } 1157 }
974 1158
975 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( 1159 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders(
976 bool* preroll_required) { 1160 bool* preroll_required) {
977 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1161 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
978 1162
979 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime(); 1163 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime();
980 1164
981 // If requested, preroll is always done in the beginning of the playback, 1165 // 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 1304
1121 audio_decoder_.reset(new MediaCodecAudioDecoder( 1305 audio_decoder_.reset(new MediaCodecAudioDecoder(
1122 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 1306 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
1123 media_weak_this_, DemuxerStream::AUDIO), 1307 media_weak_this_, DemuxerStream::AUDIO),
1124 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 1308 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
1125 DemuxerStream::AUDIO), 1309 DemuxerStream::AUDIO),
1126 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, 1310 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_,
1127 DemuxerStream::AUDIO), 1311 DemuxerStream::AUDIO),
1128 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, 1312 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_,
1129 DemuxerStream::AUDIO), 1313 DemuxerStream::AUDIO),
1314 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_,
1315 DemuxerStream::AUDIO),
1130 internal_error_cb_, 1316 internal_error_cb_,
1131 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 1317 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
1132 DemuxerStream::AUDIO))); 1318 DemuxerStream::AUDIO)));
1133 1319
1134 video_decoder_.reset(new MediaCodecVideoDecoder( 1320 video_decoder_.reset(new MediaCodecVideoDecoder(
1135 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 1321 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
1136 media_weak_this_, DemuxerStream::VIDEO), 1322 media_weak_this_, DemuxerStream::VIDEO),
1137 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 1323 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
1138 DemuxerStream::VIDEO), 1324 DemuxerStream::VIDEO),
1139 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, 1325 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_,
1140 DemuxerStream::VIDEO), 1326 DemuxerStream::VIDEO),
1141 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, 1327 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_,
1142 DemuxerStream::VIDEO), 1328 DemuxerStream::VIDEO),
1329 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_,
1330 DemuxerStream::VIDEO),
1143 internal_error_cb_, 1331 internal_error_cb_,
1144 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 1332 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
1145 DemuxerStream::VIDEO), 1333 DemuxerStream::VIDEO),
1146 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), 1334 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_),
1147 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); 1335 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_)));
1148 } 1336 }
1149 1337
1150 bool MediaCodecPlayer::AudioFinished() const { 1338 bool MediaCodecPlayer::AudioFinished() const {
1151 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); 1339 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream();
1152 } 1340 }
(...skipping 15 matching lines...) Expand all
1168 return #x; 1356 return #x;
1169 1357
1170 const char* MediaCodecPlayer::AsString(PlayerState state) { 1358 const char* MediaCodecPlayer::AsString(PlayerState state) {
1171 switch (state) { 1359 switch (state) {
1172 RETURN_STRING(kStatePaused); 1360 RETURN_STRING(kStatePaused);
1173 RETURN_STRING(kStateWaitingForConfig); 1361 RETURN_STRING(kStateWaitingForConfig);
1174 RETURN_STRING(kStatePrefetching); 1362 RETURN_STRING(kStatePrefetching);
1175 RETURN_STRING(kStatePlaying); 1363 RETURN_STRING(kStatePlaying);
1176 RETURN_STRING(kStateStopping); 1364 RETURN_STRING(kStateStopping);
1177 RETURN_STRING(kStateWaitingForSurface); 1365 RETURN_STRING(kStateWaitingForSurface);
1366 RETURN_STRING(kStateWaitingForKey);
1367 RETURN_STRING(kStateWaitingForCrypto);
1178 RETURN_STRING(kStateWaitingForSeek); 1368 RETURN_STRING(kStateWaitingForSeek);
1179 RETURN_STRING(kStateError); 1369 RETURN_STRING(kStateError);
1180 } 1370 }
1181 return nullptr; // crash early 1371 return nullptr; // crash early
1182 } 1372 }
1183 1373
1184 #undef RETURN_STRING 1374 #undef RETURN_STRING
1185 1375
1186 } // namespace media 1376 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698