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

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