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

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: Rebased Created 5 years, 2 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/android/media_task_runner.h" 17 #include "media/base/android/media_task_runner.h"
17 #include "media/base/timestamp_constants.h" 18 #include "media/base/timestamp_constants.h"
18 19
19 #define RUN_ON_MEDIA_THREAD(METHOD, ...) \ 20 #define RUN_ON_MEDIA_THREAD(METHOD, ...) \
20 do { \ 21 do { \
21 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \ 22 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \
22 DCHECK(ui_task_runner_->BelongsToCurrentThread()); \ 23 DCHECK(ui_task_runner_->BelongsToCurrentThread()); \
23 GetMediaTaskRunner()->PostTask( \ 24 GetMediaTaskRunner()->PostTask( \
24 FROM_HERE, base::Bind(&MediaCodecPlayer::METHOD, media_weak_this_, \ 25 FROM_HERE, base::Bind(&MediaCodecPlayer::METHOD, media_weak_this_, \
(...skipping 15 matching lines...) Expand all
40 : MediaPlayerAndroid(player_id, 41 : MediaPlayerAndroid(player_id,
41 manager.get(), 42 manager.get(),
42 request_media_resources_cb, 43 request_media_resources_cb,
43 frame_url), 44 frame_url),
44 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), 45 ui_task_runner_(base::ThreadTaskRunnerHandle::Get()),
45 demuxer_(demuxer.Pass()), 46 demuxer_(demuxer.Pass()),
46 state_(kStatePaused), 47 state_(kStatePaused),
47 interpolator_(&default_tick_clock_), 48 interpolator_(&default_tick_clock_),
48 pending_start_(false), 49 pending_start_(false),
49 pending_seek_(kNoTimestamp()), 50 pending_seek_(kNoTimestamp()),
51 drm_bridge_(nullptr),
52 cdm_registration_id_(0),
53 key_is_required_(false),
54 key_is_added_(false),
50 media_weak_factory_(this) { 55 media_weak_factory_(this) {
51 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 56 DCHECK(ui_task_runner_->BelongsToCurrentThread());
52 57
53 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; 58 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id;
54 59
55 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id); 60 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id);
56 61
57 completion_cb_ = 62 completion_cb_ =
58 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); 63 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id);
64 key_required_cb_ = base::Bind(&MediaPlayerManager::OnWaitingForDecryptionKey,
65 manager, player_id);
59 seek_done_cb_ = 66 seek_done_cb_ =
60 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id); 67 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id);
61 error_cb_ = base::Bind(&MediaPlayerManager::OnError, manager, player_id); 68 error_cb_ = base::Bind(&MediaPlayerManager::OnError, manager, player_id);
62 69
63 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener, 70 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener,
64 WeakPtrForUIThread(), nullptr); 71 WeakPtrForUIThread(), nullptr);
65 detach_listener_cb_ = 72 detach_listener_cb_ =
66 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread()); 73 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread());
67 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged, 74 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged,
68 WeakPtrForUIThread()); 75 WeakPtrForUIThread());
(...skipping 14 matching lines...) Expand all
83 90
84 // Currently the unit tests wait for the MediaCodecPlayer destruction by 91 // Currently the unit tests wait for the MediaCodecPlayer destruction by
85 // watching the demuxer, which is destroyed as one of the member variables. 92 // watching the demuxer, which is destroyed as one of the member variables.
86 // Release the codecs here, before any member variable is destroyed to make 93 // Release the codecs here, before any member variable is destroyed to make
87 // the unit tests happy. 94 // the unit tests happy.
88 95
89 if (video_decoder_) 96 if (video_decoder_)
90 video_decoder_->ReleaseDecoderResources(); 97 video_decoder_->ReleaseDecoderResources();
91 if (audio_decoder_) 98 if (audio_decoder_)
92 audio_decoder_->ReleaseDecoderResources(); 99 audio_decoder_->ReleaseDecoderResources();
100
101 if (drm_bridge_) {
102 DCHECK(cdm_registration_id_);
103 drm_bridge_->UnregisterPlayer(cdm_registration_id_);
104 }
93 } 105 }
94 106
95 void MediaCodecPlayer::Initialize() { 107 void MediaCodecPlayer::Initialize() {
96 DVLOG(1) << __FUNCTION__; 108 DVLOG(1) << __FUNCTION__;
97 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 109 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
98 110
99 interpolator_.SetUpperBound(base::TimeDelta()); 111 interpolator_.SetUpperBound(base::TimeDelta());
100 112
101 CreateDecoders(); 113 CreateDecoders();
102 114
(...skipping 27 matching lines...) Expand all
130 // Save the empty-ness before we pass the surface to the decoder. 142 // Save the empty-ness before we pass the surface to the decoder.
131 bool surface_is_empty = surface.IsEmpty(); 143 bool surface_is_empty = surface.IsEmpty();
132 144
133 // Apparently RemoveVideoSurface() can be called several times in a row, 145 // Apparently RemoveVideoSurface() can be called several times in a row,
134 // ignore the second and subsequent calls. 146 // ignore the second and subsequent calls.
135 if (surface_is_empty && !video_decoder_->HasVideoSurface()) { 147 if (surface_is_empty && !video_decoder_->HasVideoSurface()) {
136 DVLOG(1) << __FUNCTION__ << ": surface already removed, ignoring"; 148 DVLOG(1) << __FUNCTION__ << ": surface already removed, ignoring";
137 return; 149 return;
138 } 150 }
139 151
152 // Do not set unprotected surface if we know that we need a protected one.
153 // Empty surface means the surface removal and we always allow for it.
154 if (!surface_is_empty && video_decoder_->IsProtectedSurfaceRequired() &&
155 !surface.is_protected()) {
156 DVLOG(0) << __FUNCTION__ << ": surface is not protected, ignoring";
157 return;
158 }
159
140 video_decoder_->SetVideoSurface(surface.Pass()); 160 video_decoder_->SetVideoSurface(surface.Pass());
141 161
142 if (surface_is_empty) { 162 if (surface_is_empty) {
143 // Remove video surface. 163 // Remove video surface.
144 switch (state_) { 164 switch (state_) {
145 case kStatePlaying: 165 case kStatePlaying:
146 if (VideoFinished()) 166 if (VideoFinished())
147 break; 167 break;
148 168
149 DVLOG(1) << __FUNCTION__ << ": stopping and restarting"; 169 DVLOG(1) << __FUNCTION__ << ": stopping and restarting";
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 break; 223 break;
204 case kStateStopping: 224 case kStateStopping:
205 case kStateWaitingForSeek: 225 case kStateWaitingForSeek:
206 SetPendingStart(true); 226 SetPendingStart(true);
207 break; 227 break;
208 case kStateWaitingForConfig: 228 case kStateWaitingForConfig:
209 case kStateWaitingForPermission: 229 case kStateWaitingForPermission:
210 case kStatePrefetching: 230 case kStatePrefetching:
211 case kStatePlaying: 231 case kStatePlaying:
212 case kStateWaitingForSurface: 232 case kStateWaitingForSurface:
233 case kStateWaitingForKey:
234 case kStateWaitingForCrypto:
213 case kStateError: 235 case kStateError:
214 break; // Ignore 236 break; // Ignore
215 default: 237 default:
216 NOTREACHED(); 238 NOTREACHED();
217 break; 239 break;
218 } 240 }
219 } 241 }
220 242
221 void MediaCodecPlayer::Pause(bool is_media_related_action) { 243 void MediaCodecPlayer::Pause(bool is_media_related_action) {
222 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action); 244 RUN_ON_MEDIA_THREAD(Pause, is_media_related_action);
223 245
224 DVLOG(1) << __FUNCTION__; 246 DVLOG(1) << __FUNCTION__;
225 247
226 SetPendingStart(false); 248 SetPendingStart(false);
227 249
228 switch (state_) { 250 switch (state_) {
229 case kStateWaitingForConfig: 251 case kStateWaitingForConfig:
230 case kStateWaitingForPermission: 252 case kStateWaitingForPermission:
231 case kStatePrefetching: 253 case kStatePrefetching:
232 case kStateWaitingForSurface: 254 case kStateWaitingForSurface:
255 case kStateWaitingForKey:
256 case kStateWaitingForCrypto:
233 SetState(kStatePaused); 257 SetState(kStatePaused);
234 StopDecoders(); 258 StopDecoders();
235 break; 259 break;
236 case kStatePlaying: 260 case kStatePlaying:
237 SetState(kStateStopping); 261 SetState(kStateStopping);
238 RequestToStopDecoders(); 262 RequestToStopDecoders();
239 break; 263 break;
240 case kStatePaused: 264 case kStatePaused:
241 case kStateStopping: 265 case kStateStopping:
242 case kStateWaitingForSeek: 266 case kStateWaitingForSeek:
(...skipping 12 matching lines...) Expand all
255 279
256 switch (state_) { 280 switch (state_) {
257 case kStatePaused: 281 case kStatePaused:
258 SetState(kStateWaitingForSeek); 282 SetState(kStateWaitingForSeek);
259 RequestDemuxerSeek(timestamp); 283 RequestDemuxerSeek(timestamp);
260 break; 284 break;
261 case kStateWaitingForConfig: 285 case kStateWaitingForConfig:
262 case kStateWaitingForPermission: 286 case kStateWaitingForPermission:
263 case kStatePrefetching: 287 case kStatePrefetching:
264 case kStateWaitingForSurface: 288 case kStateWaitingForSurface:
289 case kStateWaitingForKey:
290 case kStateWaitingForCrypto:
265 SetState(kStateWaitingForSeek); 291 SetState(kStateWaitingForSeek);
266 StopDecoders(); 292 StopDecoders();
267 SetPendingStart(true); 293 SetPendingStart(true);
268 RequestDemuxerSeek(timestamp); 294 RequestDemuxerSeek(timestamp);
269 break; 295 break;
270 case kStatePlaying: 296 case kStatePlaying:
271 SetState(kStateStopping); 297 SetState(kStateStopping);
272 RequestToStopDecoders(); 298 RequestToStopDecoders();
273 SetPendingStart(true); 299 SetPendingStart(true);
274 SetPendingSeek(timestamp); 300 SetPendingSeek(timestamp);
(...skipping 20 matching lines...) Expand all
295 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser 321 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser
296 // and renderer processes going. Seek should work across and after Release(). 322 // and renderer processes going. Seek should work across and after Release().
297 323
298 ReleaseDecoderResources(); 324 ReleaseDecoderResources();
299 325
300 SetPendingStart(false); 326 SetPendingStart(false);
301 327
302 if (state_ != kStateWaitingForSeek) 328 if (state_ != kStateWaitingForSeek)
303 SetState(kStatePaused); 329 SetState(kStatePaused);
304 330
331 // Crear encryption key related flags.
332 key_is_required_ = false;
333 key_is_added_ = false;
334
305 base::TimeDelta pending_seek_time = GetPendingSeek(); 335 base::TimeDelta pending_seek_time = GetPendingSeek();
306 if (pending_seek_time != kNoTimestamp()) { 336 if (pending_seek_time != kNoTimestamp()) {
307 SetPendingSeek(kNoTimestamp()); 337 SetPendingSeek(kNoTimestamp());
308 SetState(kStateWaitingForSeek); 338 SetState(kStateWaitingForSeek);
309 RequestDemuxerSeek(pending_seek_time); 339 RequestDemuxerSeek(pending_seek_time);
310 } 340 }
311 } 341 }
312 342
313 void MediaCodecPlayer::SetVolume(double volume) { 343 void MediaCodecPlayer::SetVolume(double volume) {
314 RUN_ON_MEDIA_THREAD(SetVolume, volume); 344 RUN_ON_MEDIA_THREAD(SetVolume, volume);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 394 }
365 395
366 bool MediaCodecPlayer::IsPlayerReady() { 396 bool MediaCodecPlayer::IsPlayerReady() {
367 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 397 DCHECK(ui_task_runner_->BelongsToCurrentThread());
368 // This method is called to check whether it's safe to release the player when 398 // This method is called to check whether it's safe to release the player when
369 // the OS needs more resources. This class can be released at any time. 399 // the OS needs more resources. This class can be released at any time.
370 return true; 400 return true;
371 } 401 }
372 402
373 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) { 403 void MediaCodecPlayer::SetCdm(BrowserCdm* cdm) {
374 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 404 RUN_ON_MEDIA_THREAD(SetCdm, cdm);
375 NOTIMPLEMENTED(); 405
406 DVLOG(1) << __FUNCTION__;
407
408 // Currently we don't support DRM change during the middle of playback, even
409 // if the player is paused. There is no current plan to support it, see
410 // http://crbug.com/253792.
411 if (state_ != kStatePaused || GetInterpolatedTime() > base::TimeDelta()) {
412 VLOG(0) << "Setting DRM bridge after playback has started is not supported";
413 return;
414 }
415
416 if (drm_bridge_) {
417 NOTREACHED() << "Currently we do not support resetting CDM.";
418 return;
419 }
420
421 DCHECK(cdm);
422 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm);
423
424 DCHECK(drm_bridge_);
425
426 cdm_registration_id_ = drm_bridge_->RegisterPlayer(
427 base::Bind(&MediaCodecPlayer::OnKeyAdded, media_weak_this_),
428 base::Bind(&MediaCodecPlayer::OnCdmUnset, media_weak_this_));
429
430 MediaDrmBridge::MediaCryptoReadyCB cb =
431 base::Bind(&MediaCodecPlayer::OnMediaCryptoReady, media_weak_this_);
432
433 // Post back to UI thread?
434 ui_task_runner_->PostTask(FROM_HERE,
435 base::Bind(&MediaDrmBridge::SetMediaCryptoReadyCB,
436 drm_bridge_->WeakPtrForUIThread(), cb));
376 } 437 }
377 438
378 // Callbacks from Demuxer. 439 // Callbacks from Demuxer.
379 440
380 void MediaCodecPlayer::OnDemuxerConfigsAvailable( 441 void MediaCodecPlayer::OnDemuxerConfigsAvailable(
381 const DemuxerConfigs& configs) { 442 const DemuxerConfigs& configs) {
382 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 443 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
383 444
384 DVLOG(1) << __FUNCTION__; 445 DVLOG(1) << __FUNCTION__;
385 446
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 DCHECK(!internal_error_cb_.is_null()); 687 DCHECK(!internal_error_cb_.is_null());
627 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); 688 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
628 return; 689 return;
629 } 690 }
630 691
631 if (HasVideo() && !video_decoder_->HasVideoSurface()) { 692 if (HasVideo() && !video_decoder_->HasVideoSurface()) {
632 SetState(kStateWaitingForSurface); 693 SetState(kStateWaitingForSurface);
633 return; 694 return;
634 } 695 }
635 696
697 if (key_is_required_ && !key_is_added_) {
698 SetState(kStateWaitingForKey);
699 ui_task_runner_->PostTask(FROM_HERE, key_required_cb_);
700 return;
701 }
702
636 SetState(kStatePlaying); 703 SetState(kStatePlaying);
637 StartPlaybackOrBrowserSeek(); 704 StartPlaybackOrBrowserSeek();
638 } 705 }
639 706
640 void MediaCodecPlayer::OnPrerollDone() { 707 void MediaCodecPlayer::OnPrerollDone() {
641 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 708 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
642 709
643 if (state_ != kStatePlaying) { 710 if (state_ != kStatePlaying) {
644 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_) 711 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_)
645 << ", ignoring"; 712 << ", ignoring";
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 return; 806 return;
740 } 807 }
741 808
742 // DetachListener to UI thread 809 // DetachListener to UI thread
743 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); 810 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_);
744 811
745 if (AudioFinished() && VideoFinished()) 812 if (AudioFinished() && VideoFinished())
746 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); 813 ui_task_runner_->PostTask(FROM_HERE, completion_cb_);
747 } 814 }
748 815
816 void MediaCodecPlayer::OnKeyRequired(DemuxerStream::Type type) {
817 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
818 DVLOG(1) << __FUNCTION__ << " " << type;
819
820 // Request stop and restart to pick up the key.
821 key_is_required_ = true;
822
823 if (state_ == kStatePlaying) {
824 SetState(kStateStopping);
825 RequestToStopDecoders();
826 SetPendingStart(true);
827 }
xhwang 2015/09/30 18:07:53 It seems to me whenever a key is required we'll st
Tima Vaisburd 2015/09/30 21:24:51 Yes.
xhwang 2015/10/01 00:04:39 In that case I think your impl is good.
Tima Vaisburd 2015/10/01 00:36:06 It seems it would be not that hard to try again se
xhwang 2015/10/01 00:50:05 Try until there's no new key available. New key is
828 }
829
749 void MediaCodecPlayer::OnError() { 830 void MediaCodecPlayer::OnError() {
750 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 831 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
751 DVLOG(1) << __FUNCTION__; 832 DVLOG(1) << __FUNCTION__;
752 833
753 // kStateError blocks all events 834 // kStateError blocks all events
754 SetState(kStateError); 835 SetState(kStateError);
755 836
756 ReleaseDecoderResources(); 837 ReleaseDecoderResources();
757 838
758 ui_task_runner_->PostTask(FROM_HERE, 839 ui_task_runner_->PostTask(FROM_HERE,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 void MediaCodecPlayer::OnVideoResolutionChanged(const gfx::Size& size) { 903 void MediaCodecPlayer::OnVideoResolutionChanged(const gfx::Size& size) {
823 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 904 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
824 905
825 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height(); 906 DVLOG(1) << __FUNCTION__ << " " << size.width() << "x" << size.height();
826 907
827 // Update cache and notify manager on UI thread 908 // Update cache and notify manager on UI thread
828 ui_task_runner_->PostTask( 909 ui_task_runner_->PostTask(
829 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size)); 910 FROM_HERE, base::Bind(metadata_changed_cb_, kNoTimestamp(), size));
830 } 911 }
831 912
913 // Callbacks from DRM
xhwang 2015/09/30 18:07:53 s/DRM/MediaDrmBridge.
Tima Vaisburd 2015/09/30 23:00:50 Done.
914
915 void MediaCodecPlayer::OnMediaCryptoReady(
916 MediaDrmBridge::JavaObjectPtr media_crypto,
917 bool needs_protected_surface) {
918 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
919 DVLOG(1) << __FUNCTION__ << " protected surface is "
920 << (needs_protected_surface ? "required" : "not required");
921
922 // We use the parameters that come with this callback every time we call
923 // Configure(). This is possible only if the MediaCrypto object remains valid
924 // and the surface requirement does not change until new SetCdm() is called.
925
926 DCHECK(media_crypto);
927 DCHECK(!media_crypto->is_null());
928
929 media_crypto_ = media_crypto.Pass();
930
931 if (audio_decoder_) {
932 audio_decoder_->SetNeedsReconfigure();
933 }
934
935 if (video_decoder_) {
936 video_decoder_->SetNeedsReconfigure();
937 video_decoder_->SetProtectedSurfaceRequired(needs_protected_surface);
938 }
939
940 if (state_ == kStateWaitingForCrypto) {
941 // Resume start sequence (configure, etc.)
942 SetState(kStatePlaying);
943 StartPlaybackOrBrowserSeek();
944 }
945
946 DVLOG(1) << __FUNCTION__ << " end";
947 }
948
949 void MediaCodecPlayer::OnKeyAdded() {
950 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
951 DVLOG(1) << __FUNCTION__;
952
953 key_is_added_ = true;
954
955 if (state_ == kStateWaitingForKey) {
956 SetState(kStatePlaying);
957 StartPlaybackOrBrowserSeek();
958 }
959 }
960
961 void MediaCodecPlayer::OnCdmUnset() {
962 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
963 DVLOG(1) << __FUNCTION__;
964
965 // This comment is copied from MediaSourcePlayer::OnCdmUnset().
966 // TODO(xhwang): Currently this is only called during teardown. Support full
967 // detachment of CDM during playback. This will be needed when we start to
968 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release
969 // MediaDrm when the video is paused, or when the device goes to sleep (see
970 // http://crbug.com/272421).
971
972 if (audio_decoder_) {
973 audio_decoder_->SetNeedsReconfigure();
974 }
975
976 if (video_decoder_) {
977 video_decoder_->SetProtectedSurfaceRequired(false);
978 video_decoder_->SetNeedsReconfigure();
979 }
980
981 cdm_registration_id_ = 0;
982 drm_bridge_ = nullptr;
983 media_crypto_.reset();
984 }
985
832 // State machine operations, called on Media thread 986 // State machine operations, called on Media thread
833 987
834 void MediaCodecPlayer::SetState(PlayerState new_state) { 988 void MediaCodecPlayer::SetState(PlayerState new_state) {
835 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 989 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
836 990
837 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); 991 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state);
838 state_ = new_state; 992 state_ = new_state;
839 } 993 }
840 994
841 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { 995 void MediaCodecPlayer::SetPendingStart(bool need_to_start) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 video_decoder_->Prefetch(prefetch_cb); 1087 video_decoder_->Prefetch(prefetch_cb);
934 } 1088 }
935 1089
936 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() { 1090 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() {
937 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1091 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
938 DVLOG(1) << __FUNCTION__; 1092 DVLOG(1) << __FUNCTION__;
939 1093
940 // TODO(timav): consider replacing this method with posting a 1094 // TODO(timav): consider replacing this method with posting a
941 // browser seek task (i.e. generate an event) from StartPlaybackDecoders(). 1095 // browser seek task (i.e. generate an event) from StartPlaybackDecoders().
942 1096
1097 // Clear encryption key related flags.
1098 key_is_required_ = false;
1099 key_is_added_ = false;
1100
943 StartStatus status = StartPlaybackDecoders(); 1101 StartStatus status = StartPlaybackDecoders();
944 1102
945 switch (status) { 1103 switch (status) {
946 case kStartBrowserSeekRequired: 1104 case kStartBrowserSeekRequired:
947 // Browser seek 1105 // Browser seek
948 SetState(kStateWaitingForSeek); 1106 SetState(kStateWaitingForSeek);
949 SetPendingStart(true); 1107 SetPendingStart(true);
950 StopDecoders(); 1108 StopDecoders();
951 RequestDemuxerSeek(GetInterpolatedTime(), true); 1109 RequestDemuxerSeek(GetInterpolatedTime(), true);
952 break; 1110 break;
1111 case kStartCryptoRequired:
1112 SetState(kStateWaitingForCrypto);
1113 break;
953 case kStartFailed: 1114 case kStartFailed:
954 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); 1115 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
955 break; 1116 break;
956 case kStartOk: 1117 case kStartOk:
957 break; 1118 break;
958 } 1119 }
959 } 1120 }
960 1121
961 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() { 1122 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() {
962 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1123 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
(...skipping 17 matching lines...) Expand all
980 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1141 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
981 DVLOG(1) << __FUNCTION__; 1142 DVLOG(1) << __FUNCTION__;
982 1143
983 const bool do_audio = !AudioFinished(); 1144 const bool do_audio = !AudioFinished();
984 const bool do_video = !VideoFinished(); 1145 const bool do_video = !VideoFinished();
985 1146
986 // If there is nothing to play, the state machine should determine this at the 1147 // If there is nothing to play, the state machine should determine this at the
987 // prefetch state and never call this method. 1148 // prefetch state and never call this method.
988 DCHECK(do_audio || do_video); 1149 DCHECK(do_audio || do_video);
989 1150
990 // Start with video: if browser seek is required it would 1151 bool need_crypto = (do_audio && audio_decoder_->IsContentEncrypted()) ||
991 // not make sense to configure audio. 1152 (do_video && video_decoder_->IsContentEncrypted());
992 1153
993 if (do_video) { 1154 // Do we need to create a local ref from the global ref?
994 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure(); 1155 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr;
995 switch (status) { 1156
996 case MediaCodecDecoder::kConfigOk: 1157 if (need_crypto) {
997 break; 1158 DVLOG(1) << (audio_decoder_->IsContentEncrypted() ? " audio" : "")
998 case MediaCodecDecoder::kConfigKeyFrameRequired: 1159 << (video_decoder_->IsContentEncrypted() ? " video" : "")
999 // TODO(timav): post a task or return the status? 1160 << " need(s) encryption";
1000 return kStartBrowserSeekRequired; 1161 if (!media_crypto) {
1001 case MediaCodecDecoder::kConfigFailure: 1162 DVLOG(1) << __FUNCTION__ << ": MediaCrypto is not found, returning";
1002 return kStartFailed; 1163 return kStartCryptoRequired;
1003 } 1164 }
1004 } 1165 }
1005 1166
1006 if (do_audio) { 1167 // Start with video: if browser seek is required it would not make sense to
1007 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); 1168 // configure audio.
1008 if (status != MediaCodecDecoder::kConfigOk) { 1169
1170 MediaCodecDecoder::ConfigStatus status = MediaCodecDecoder::kConfigOk;
1171 if (do_video)
1172 status = video_decoder_->Configure(media_crypto);
1173
1174 if (status == MediaCodecDecoder::kConfigOk && do_audio)
1175 status = audio_decoder_->Configure(media_crypto);
1176
1177 switch (status) {
1178 case MediaCodecDecoder::kConfigOk:
1179 break;
1180 case MediaCodecDecoder::kConfigKeyFrameRequired:
1181 return kStartBrowserSeekRequired;
1182 case MediaCodecDecoder::kConfigNoCrypto: // TODO: delete this
1183 return kStartCryptoRequired;
1184 case MediaCodecDecoder::kConfigFailure:
1009 return kStartFailed; 1185 return kStartFailed;
1010 }
1011 } 1186 }
1012
1013 return kStartOk; 1187 return kStartOk;
1014 } 1188 }
1015 1189
1016 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( 1190 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders(
1017 bool* preroll_required) { 1191 bool* preroll_required) {
1018 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1192 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
1019 1193
1020 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime(); 1194 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime();
1021 1195
1022 // If requested, preroll is always done in the beginning of the playback, 1196 // If requested, preroll is always done in the beginning of the playback,
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 1335
1162 audio_decoder_.reset(new MediaCodecAudioDecoder( 1336 audio_decoder_.reset(new MediaCodecAudioDecoder(
1163 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 1337 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
1164 media_weak_this_, DemuxerStream::AUDIO), 1338 media_weak_this_, DemuxerStream::AUDIO),
1165 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 1339 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
1166 DemuxerStream::AUDIO), 1340 DemuxerStream::AUDIO),
1167 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, 1341 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_,
1168 DemuxerStream::AUDIO), 1342 DemuxerStream::AUDIO),
1169 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, 1343 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_,
1170 DemuxerStream::AUDIO), 1344 DemuxerStream::AUDIO),
1345 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_,
1346 DemuxerStream::AUDIO),
1171 internal_error_cb_, 1347 internal_error_cb_,
1172 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 1348 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
1173 DemuxerStream::AUDIO))); 1349 DemuxerStream::AUDIO)));
1174 1350
1175 video_decoder_.reset(new MediaCodecVideoDecoder( 1351 video_decoder_.reset(new MediaCodecVideoDecoder(
1176 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 1352 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
1177 media_weak_this_, DemuxerStream::VIDEO), 1353 media_weak_this_, DemuxerStream::VIDEO),
1178 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 1354 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
1179 DemuxerStream::VIDEO), 1355 DemuxerStream::VIDEO),
1180 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, 1356 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_,
1181 DemuxerStream::VIDEO), 1357 DemuxerStream::VIDEO),
1182 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, 1358 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_,
1183 DemuxerStream::VIDEO), 1359 DemuxerStream::VIDEO),
1360 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_,
1361 DemuxerStream::VIDEO),
1184 internal_error_cb_, 1362 internal_error_cb_,
1185 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 1363 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
1186 DemuxerStream::VIDEO), 1364 DemuxerStream::VIDEO),
1187 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), 1365 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_),
1188 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); 1366 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_)));
1189 } 1367 }
1190 1368
1191 bool MediaCodecPlayer::AudioFinished() const { 1369 bool MediaCodecPlayer::AudioFinished() const {
1192 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); 1370 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream();
1193 } 1371 }
(...skipping 16 matching lines...) Expand all
1210 1388
1211 const char* MediaCodecPlayer::AsString(PlayerState state) { 1389 const char* MediaCodecPlayer::AsString(PlayerState state) {
1212 switch (state) { 1390 switch (state) {
1213 RETURN_STRING(kStatePaused); 1391 RETURN_STRING(kStatePaused);
1214 RETURN_STRING(kStateWaitingForConfig); 1392 RETURN_STRING(kStateWaitingForConfig);
1215 RETURN_STRING(kStateWaitingForPermission); 1393 RETURN_STRING(kStateWaitingForPermission);
1216 RETURN_STRING(kStatePrefetching); 1394 RETURN_STRING(kStatePrefetching);
1217 RETURN_STRING(kStatePlaying); 1395 RETURN_STRING(kStatePlaying);
1218 RETURN_STRING(kStateStopping); 1396 RETURN_STRING(kStateStopping);
1219 RETURN_STRING(kStateWaitingForSurface); 1397 RETURN_STRING(kStateWaitingForSurface);
1398 RETURN_STRING(kStateWaitingForKey);
1399 RETURN_STRING(kStateWaitingForCrypto);
1220 RETURN_STRING(kStateWaitingForSeek); 1400 RETURN_STRING(kStateWaitingForSeek);
1221 RETURN_STRING(kStateError); 1401 RETURN_STRING(kStateError);
1222 } 1402 }
1223 return nullptr; // crash early 1403 return nullptr; // crash early
1224 } 1404 }
1225 1405
1226 #undef RETURN_STRING 1406 #undef RETURN_STRING
1227 1407
1228 } // namespace media 1408 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698