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

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

Issue 308073004: Add PlayerTracker and BrowserCdm interfaces. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: minor fix Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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_source_player.h" 5 #include "media/base/android/media_source_player.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 is_audio_encrypted_(false), 47 is_audio_encrypted_(false),
48 is_video_encrypted_(false), 48 is_video_encrypted_(false),
49 volume_(-1.0), 49 volume_(-1.0),
50 clock_(&default_tick_clock_), 50 clock_(&default_tick_clock_),
51 next_video_data_is_iframe_(true), 51 next_video_data_is_iframe_(true),
52 doing_browser_seek_(false), 52 doing_browser_seek_(false),
53 pending_seek_(false), 53 pending_seek_(false),
54 reconfig_audio_decoder_(false), 54 reconfig_audio_decoder_(false),
55 reconfig_video_decoder_(false), 55 reconfig_video_decoder_(false),
56 drm_bridge_(NULL), 56 drm_bridge_(NULL),
57 cdm_registration_id_(0),
57 is_waiting_for_key_(false), 58 is_waiting_for_key_(false),
58 has_pending_audio_data_request_(false), 59 has_pending_audio_data_request_(false),
59 has_pending_video_data_request_(false), 60 has_pending_video_data_request_(false),
60 weak_factory_(this) { 61 weak_factory_(this) {
61 demuxer_->Initialize(this); 62 demuxer_->Initialize(this);
62 clock_.SetMaxTime(base::TimeDelta()); 63 clock_.SetMaxTime(base::TimeDelta());
64 weak_this_ = weak_factory_.GetWeakPtr();
63 } 65 }
64 66
65 MediaSourcePlayer::~MediaSourcePlayer() { 67 MediaSourcePlayer::~MediaSourcePlayer() {
66 Release(); 68 Release();
69 if (drm_bridge_)
70 drm_bridge_->UnregisterPlayer(cdm_registration_id_);
ddorwin 2014/05/30 20:50:05 Should this be called even if cdm_registration_id_
xhwang 2014/06/02 20:11:43 Done.
71 cdm_registration_id_ = 0;
67 } 72 }
68 73
69 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { 74 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
70 // For an empty surface, always pass it to the decoder job so that it 75 // For an empty surface, always pass it to the decoder job so that it
71 // can detach from the current one. Otherwise, don't pass an unprotected 76 // can detach from the current one. Otherwise, don't pass an unprotected
72 // surface if the video content requires a protected one. 77 // surface if the video content requires a protected one.
73 if (!surface.IsEmpty() && 78 if (!surface.IsEmpty() &&
74 IsProtectedSurfaceRequired() && !surface.is_protected()) { 79 IsProtectedSurfaceRequired() && !surface.is_protected()) {
75 return; 80 return;
76 } 81 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing"; 237 DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing";
233 ProcessPendingEvents(); 238 ProcessPendingEvents();
234 } 239 }
235 } 240 }
236 241
237 void MediaSourcePlayer::SetVolume(double volume) { 242 void MediaSourcePlayer::SetVolume(double volume) {
238 volume_ = volume; 243 volume_ = volume;
239 SetVolumeInternal(); 244 SetVolumeInternal();
240 } 245 }
241 246
242 void MediaSourcePlayer::OnKeyAdded() {
243 DVLOG(1) << __FUNCTION__;
244 if (!is_waiting_for_key_)
245 return;
246
247 is_waiting_for_key_ = false;
248 if (playing_)
249 StartInternal();
250 }
251
252 bool MediaSourcePlayer::IsSurfaceInUse() const { 247 bool MediaSourcePlayer::IsSurfaceInUse() const {
253 return is_surface_in_use_; 248 return is_surface_in_use_;
254 } 249 }
255 250
256 bool MediaSourcePlayer::CanPause() { 251 bool MediaSourcePlayer::CanPause() {
257 return Seekable(); 252 return Seekable();
258 } 253 }
259 254
260 bool MediaSourcePlayer::CanSeekForward() { 255 bool MediaSourcePlayer::CanSeekForward() {
261 return Seekable(); 256 return Seekable();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 343 }
349 344
350 void MediaSourcePlayer::OnMediaCryptoReady() { 345 void MediaSourcePlayer::OnMediaCryptoReady() {
351 DCHECK(!drm_bridge_->GetMediaCrypto().is_null()); 346 DCHECK(!drm_bridge_->GetMediaCrypto().is_null());
352 drm_bridge_->SetMediaCryptoReadyCB(base::Closure()); 347 drm_bridge_->SetMediaCryptoReadyCB(base::Closure());
353 348
354 if (playing_) 349 if (playing_)
355 StartInternal(); 350 StartInternal();
356 } 351 }
357 352
358 void MediaSourcePlayer::SetCdm(MediaKeys* cdm) { 353 void MediaSourcePlayer::SetCdm(BrowserCdm* cdm) {
359 // Currently we don't support DRM change during the middle of playback, even 354 // Currently we don't support DRM change during the middle of playback, even
360 // if the player is paused. 355 // if the player is paused.
361 // TODO(qinmin): support DRM change after playback has started. 356 // TODO(qinmin): support DRM change after playback has started.
362 // http://crbug.com/253792. 357 // http://crbug.com/253792.
363 if (GetCurrentTime() > base::TimeDelta()) { 358 if (GetCurrentTime() > base::TimeDelta()) {
364 VLOG(0) << "Setting DRM bridge after playback has started. " 359 VLOG(0) << "Setting DRM bridge after playback has started. "
365 << "This is not well supported!"; 360 << "This is not well supported!";
366 } 361 }
367 362
363 // Currently we don't support resetting |drm_bridge_|.
ddorwin 2014/05/30 20:50:05 Ditto about DCHECK and error reporting.
xhwang 2014/06/02 20:11:43 Done.
364 if (drm_bridge_)
365 return;
366
368 // Only MediaDrmBridge will be set on MediaSourcePlayer. 367 // Only MediaDrmBridge will be set on MediaSourcePlayer.
369 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm); 368 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm);
370 369
370 cdm_registration_id_ = cdm->RegisterPlayer(
ddorwin 2014/05/30 20:50:05 A bit odd to cast then use the previous pointer (c
xhwang 2014/06/02 20:11:43 Done.
371 base::Bind(&MediaSourcePlayer::OnKeyAdded, weak_this_),
372 base::Bind(&MediaSourcePlayer::OnCdmDestroyed, weak_this_));
373
371 if (drm_bridge_->GetMediaCrypto().is_null()) { 374 if (drm_bridge_->GetMediaCrypto().is_null()) {
ddorwin 2014/05/30 20:50:05 Should this logic be made generic as well? Some ty
xhwang 2014/06/02 20:11:43 Not sure whether there's a general need for this.
372 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( 375 drm_bridge_->SetMediaCryptoReadyCB(
373 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr())); 376 base::Bind(&MediaSourcePlayer::OnMediaCryptoReady, weak_this_));
374 return; 377 return;
375 } 378 }
376 379
377 if (playing_) 380 if (playing_)
378 StartInternal(); 381 StartInternal();
379 } 382 }
380 383
381 void MediaSourcePlayer::OnDemuxerSeekDone( 384 void MediaSourcePlayer::OnDemuxerSeekDone(
382 base::TimeDelta actual_browser_seek_time) { 385 base::TimeDelta actual_browser_seek_time) {
383 DVLOG(1) << __FUNCTION__; 386 DVLOG(1) << __FUNCTION__;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); 520 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
518 521
519 // It is possible that all streams have finished decode, yet starvation 522 // It is possible that all streams have finished decode, yet starvation
520 // occurred during the last stream's EOS decode. In this case, prefetch is a 523 // occurred during the last stream's EOS decode. In this case, prefetch is a
521 // no-op. 524 // no-op.
522 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 525 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
523 if (count == 0) 526 if (count == 0)
524 return; 527 return;
525 528
526 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); 529 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
527 base::Closure barrier = 530 base::Closure barrier = BarrierClosure(
528 BarrierClosure(count, 531 count, base::Bind(&MediaSourcePlayer::OnPrefetchDone, weak_this_));
529 base::Bind(&MediaSourcePlayer::OnPrefetchDone,
530 weak_factory_.GetWeakPtr()));
531 532
532 if (!AudioFinished()) 533 if (!AudioFinished())
533 audio_decoder_job_->Prefetch(barrier); 534 audio_decoder_job_->Prefetch(barrier);
534 535
535 if (!VideoFinished()) 536 if (!VideoFinished())
536 video_decoder_job_->Prefetch(barrier); 537 video_decoder_job_->Prefetch(barrier);
537 538
538 return; 539 return;
539 } 540 }
540 541
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 649 }
649 650
650 void MediaSourcePlayer::DecodeMoreAudio() { 651 void MediaSourcePlayer::DecodeMoreAudio() {
651 DVLOG(1) << __FUNCTION__; 652 DVLOG(1) << __FUNCTION__;
652 DCHECK(!audio_decoder_job_->is_decoding()); 653 DCHECK(!audio_decoder_job_->is_decoding());
653 DCHECK(!AudioFinished()); 654 DCHECK(!AudioFinished());
654 655
655 scoped_ptr<DemuxerConfigs> configs(audio_decoder_job_->Decode( 656 scoped_ptr<DemuxerConfigs> configs(audio_decoder_job_->Decode(
656 start_time_ticks_, 657 start_time_ticks_,
657 start_presentation_timestamp_, 658 start_presentation_timestamp_,
658 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 659 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, true)));
659 weak_factory_.GetWeakPtr(),
660 true)));
661 if (!configs) { 660 if (!configs) {
662 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", 661 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
663 audio_decoder_job_.get()); 662 audio_decoder_job_.get());
664 return; 663 return;
665 } 664 }
666 665
667 // Failed to start the next decode. 666 // Failed to start the next decode.
668 DCHECK(!reconfig_audio_decoder_); 667 DCHECK(!reconfig_audio_decoder_);
669 reconfig_audio_decoder_ = true; 668 reconfig_audio_decoder_ = true;
670 SetDemuxerConfigs(*configs, true); 669 SetDemuxerConfigs(*configs, true);
671 670
672 // Config change may have just been detected on the other stream. If so, 671 // Config change may have just been detected on the other stream. If so,
673 // don't send a duplicate demuxer config request. 672 // don't send a duplicate demuxer config request.
674 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 673 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
675 DCHECK(reconfig_video_decoder_); 674 DCHECK(reconfig_video_decoder_);
676 return; 675 return;
677 } 676 }
678 677
679 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); 678 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
680 } 679 }
681 680
682 void MediaSourcePlayer::DecodeMoreVideo() { 681 void MediaSourcePlayer::DecodeMoreVideo() {
683 DVLOG(1) << __FUNCTION__; 682 DVLOG(1) << __FUNCTION__;
684 DCHECK(!video_decoder_job_->is_decoding()); 683 DCHECK(!video_decoder_job_->is_decoding());
685 DCHECK(!VideoFinished()); 684 DCHECK(!VideoFinished());
686 685
687 scoped_ptr<DemuxerConfigs> configs(video_decoder_job_->Decode( 686 scoped_ptr<DemuxerConfigs> configs(video_decoder_job_->Decode(
688 start_time_ticks_, 687 start_time_ticks_,
689 start_presentation_timestamp_, 688 start_presentation_timestamp_,
690 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 689 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, false)));
691 weak_factory_.GetWeakPtr(),
692 false)));
693 if (!configs) { 690 if (!configs) {
694 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", 691 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
695 video_decoder_job_.get()); 692 video_decoder_job_.get());
696 return; 693 return;
697 } 694 }
698 695
699 // Failed to start the next decode. 696 // Failed to start the next decode.
700 // After this detection of video config change, next video data received 697 // After this detection of video config change, next video data received
701 // will begin with I-frame. 698 // will begin with I-frame.
702 next_video_data_is_iframe_ = true; 699 next_video_data_is_iframe_ = true;
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 // For video only streams, fps can be estimated from the difference 904 // For video only streams, fps can be estimated from the difference
908 // between the previous and current presentation timestamps. The 905 // between the previous and current presentation timestamps. The
909 // previous presentation timestamp is equal to current_timestamp. 906 // previous presentation timestamp is equal to current_timestamp.
910 // TODO(qinmin): determine whether 2 is a good coefficient for estimating 907 // TODO(qinmin): determine whether 2 is a good coefficient for estimating
911 // video frame timeout. 908 // video frame timeout.
912 timeout = 2 * (current_presentation_timestamp - current_timestamp); 909 timeout = 2 * (current_presentation_timestamp - current_timestamp);
913 } 910 }
914 911
915 timeout = std::max(timeout, kMinStarvationTimeout); 912 timeout = std::max(timeout, kMinStarvationTimeout);
916 913
917 decoder_starvation_callback_.Reset(base::Bind( 914 decoder_starvation_callback_.Reset(
918 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr())); 915 base::Bind(&MediaSourcePlayer::OnDecoderStarved, weak_this_));
919 base::MessageLoop::current()->PostDelayedTask( 916 base::MessageLoop::current()->PostDelayedTask(
920 FROM_HERE, decoder_starvation_callback_.callback(), timeout); 917 FROM_HERE, decoder_starvation_callback_.callback(), timeout);
921 } 918 }
922 919
923 void MediaSourcePlayer::SetVolumeInternal() { 920 void MediaSourcePlayer::SetVolumeInternal() {
924 if (audio_decoder_job_ && volume_ >= 0) 921 if (audio_decoder_job_ && volume_ >= 0)
925 audio_decoder_job_->SetVolume(volume_); 922 audio_decoder_job_->SetVolume(volume_);
926 } 923 }
927 924
928 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { 925 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 is_audio_encrypted_ = configs.is_audio_encrypted; 1012 is_audio_encrypted_ = configs.is_audio_encrypted;
1016 audio_extra_data_ = configs.audio_extra_data; 1013 audio_extra_data_ = configs.audio_extra_data;
1017 } else { 1014 } else {
1018 video_codec_ = configs.video_codec; 1015 video_codec_ = configs.video_codec;
1019 width_ = configs.video_size.width(); 1016 width_ = configs.video_size.width();
1020 height_ = configs.video_size.height(); 1017 height_ = configs.video_size.height();
1021 is_video_encrypted_ = configs.is_video_encrypted; 1018 is_video_encrypted_ = configs.is_video_encrypted;
1022 } 1019 }
1023 } 1020 }
1024 1021
1022 void MediaSourcePlayer::OnKeyAdded() {
1023 DVLOG(1) << __FUNCTION__;
1024 if (!is_waiting_for_key_)
1025 return;
1026
1027 is_waiting_for_key_ = false;
1028 if (playing_)
1029 StartInternal();
1030 }
1031
1032 void MediaSourcePlayer::OnCdmDestroyed() {
1033 DVLOG(1) << __FUNCTION__;
1034 DCHECK(drm_bridge_);
1035 // TODO(xhwang): Support detachment of CDM.
ddorwin 2014/05/30 20:50:05 Don't you need to handle the platform-driven case
xhwang 2014/06/02 20:11:43 That'll be a non-trivial change. I'll probably do
ddorwin 2014/06/02 20:20:29 But does this break existing prefixed API behavior
xhwang 2014/06/02 21:41:22 Currently we are not releasing MediaDrm when the d
1036 DVLOG(1) << "CDM detachment not supported.";
1037 }
1038
1025 } // namespace media 1039 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698