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

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: comments addressed 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 DCHECK_NE(cdm_registration_id_, 0);
ddorwin 2014/06/02 20:20:29 If you want a DCHECK, it's probably something like
xhwang 2014/06/02 21:41:22 Done.
71 drm_bridge_->UnregisterPlayer(cdm_registration_id_);
72 cdm_registration_id_ = 0;
73 }
67 } 74 }
68 75
69 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { 76 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
70 // For an empty surface, always pass it to the decoder job so that it 77 // 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 78 // can detach from the current one. Otherwise, don't pass an unprotected
72 // surface if the video content requires a protected one. 79 // surface if the video content requires a protected one.
73 if (!surface.IsEmpty() && 80 if (!surface.IsEmpty() &&
74 IsProtectedSurfaceRequired() && !surface.is_protected()) { 81 IsProtectedSurfaceRequired() && !surface.is_protected()) {
75 return; 82 return;
76 } 83 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing"; 239 DVLOG(1) << __FUNCTION__ << " : Resuming seek or config change processing";
233 ProcessPendingEvents(); 240 ProcessPendingEvents();
234 } 241 }
235 } 242 }
236 243
237 void MediaSourcePlayer::SetVolume(double volume) { 244 void MediaSourcePlayer::SetVolume(double volume) {
238 volume_ = volume; 245 volume_ = volume;
239 SetVolumeInternal(); 246 SetVolumeInternal();
240 } 247 }
241 248
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 { 249 bool MediaSourcePlayer::IsSurfaceInUse() const {
253 return is_surface_in_use_; 250 return is_surface_in_use_;
254 } 251 }
255 252
256 bool MediaSourcePlayer::CanPause() { 253 bool MediaSourcePlayer::CanPause() {
257 return Seekable(); 254 return Seekable();
258 } 255 }
259 256
260 bool MediaSourcePlayer::CanSeekForward() { 257 bool MediaSourcePlayer::CanSeekForward() {
261 return Seekable(); 258 return Seekable();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 345 }
349 346
350 void MediaSourcePlayer::OnMediaCryptoReady() { 347 void MediaSourcePlayer::OnMediaCryptoReady() {
351 DCHECK(!drm_bridge_->GetMediaCrypto().is_null()); 348 DCHECK(!drm_bridge_->GetMediaCrypto().is_null());
352 drm_bridge_->SetMediaCryptoReadyCB(base::Closure()); 349 drm_bridge_->SetMediaCryptoReadyCB(base::Closure());
353 350
354 if (playing_) 351 if (playing_)
355 StartInternal(); 352 StartInternal();
356 } 353 }
357 354
358 void MediaSourcePlayer::SetCdm(MediaKeys* cdm) { 355 void MediaSourcePlayer::SetCdm(BrowserCdm* cdm) {
359 // Currently we don't support DRM change during the middle of playback, even 356 // Currently we don't support DRM change during the middle of playback, even
360 // if the player is paused. 357 // if the player is paused.
361 // TODO(qinmin): support DRM change after playback has started. 358 // TODO(qinmin): support DRM change after playback has started.
362 // http://crbug.com/253792. 359 // http://crbug.com/253792.
363 if (GetCurrentTime() > base::TimeDelta()) { 360 if (GetCurrentTime() > base::TimeDelta()) {
364 VLOG(0) << "Setting DRM bridge after playback has started. " 361 VLOG(0) << "Setting DRM bridge after playback has started. "
365 << "This is not well supported!"; 362 << "This is not well supported!";
366 } 363 }
367 364
365 if (drm_bridge_) {
366 NOTREACHED() << "Currently we do not support resetting CDM.";
367 return;
368 }
369
368 // Only MediaDrmBridge will be set on MediaSourcePlayer. 370 // Only MediaDrmBridge will be set on MediaSourcePlayer.
369 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm); 371 drm_bridge_ = static_cast<MediaDrmBridge*>(cdm);
370 372
373 cdm_registration_id_ = drm_bridge_->RegisterPlayer(
374 base::Bind(&MediaSourcePlayer::OnKeyAdded, weak_this_),
375 base::Bind(&MediaSourcePlayer::OnCdmUnset, weak_this_));
376
371 if (drm_bridge_->GetMediaCrypto().is_null()) { 377 if (drm_bridge_->GetMediaCrypto().is_null()) {
372 drm_bridge_->SetMediaCryptoReadyCB(base::Bind( 378 drm_bridge_->SetMediaCryptoReadyCB(
373 &MediaSourcePlayer::OnMediaCryptoReady, weak_factory_.GetWeakPtr())); 379 base::Bind(&MediaSourcePlayer::OnMediaCryptoReady, weak_this_));
374 return; 380 return;
375 } 381 }
376 382
377 if (playing_) 383 if (playing_)
378 StartInternal(); 384 StartInternal();
379 } 385 }
380 386
381 void MediaSourcePlayer::OnDemuxerSeekDone( 387 void MediaSourcePlayer::OnDemuxerSeekDone(
382 base::TimeDelta actual_browser_seek_time) { 388 base::TimeDelta actual_browser_seek_time) {
383 DVLOG(1) << __FUNCTION__; 389 DVLOG(1) << __FUNCTION__;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); 523 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
518 524
519 // It is possible that all streams have finished decode, yet starvation 525 // 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 526 // occurred during the last stream's EOS decode. In this case, prefetch is a
521 // no-op. 527 // no-op.
522 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 528 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
523 if (count == 0) 529 if (count == 0)
524 return; 530 return;
525 531
526 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); 532 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
527 base::Closure barrier = 533 base::Closure barrier = BarrierClosure(
528 BarrierClosure(count, 534 count, base::Bind(&MediaSourcePlayer::OnPrefetchDone, weak_this_));
529 base::Bind(&MediaSourcePlayer::OnPrefetchDone,
530 weak_factory_.GetWeakPtr()));
531 535
532 if (!AudioFinished()) 536 if (!AudioFinished())
533 audio_decoder_job_->Prefetch(barrier); 537 audio_decoder_job_->Prefetch(barrier);
534 538
535 if (!VideoFinished()) 539 if (!VideoFinished())
536 video_decoder_job_->Prefetch(barrier); 540 video_decoder_job_->Prefetch(barrier);
537 541
538 return; 542 return;
539 } 543 }
540 544
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 652 }
649 653
650 void MediaSourcePlayer::DecodeMoreAudio() { 654 void MediaSourcePlayer::DecodeMoreAudio() {
651 DVLOG(1) << __FUNCTION__; 655 DVLOG(1) << __FUNCTION__;
652 DCHECK(!audio_decoder_job_->is_decoding()); 656 DCHECK(!audio_decoder_job_->is_decoding());
653 DCHECK(!AudioFinished()); 657 DCHECK(!AudioFinished());
654 658
655 scoped_ptr<DemuxerConfigs> configs(audio_decoder_job_->Decode( 659 scoped_ptr<DemuxerConfigs> configs(audio_decoder_job_->Decode(
656 start_time_ticks_, 660 start_time_ticks_,
657 start_presentation_timestamp_, 661 start_presentation_timestamp_,
658 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 662 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, true)));
659 weak_factory_.GetWeakPtr(),
660 true)));
661 if (!configs) { 663 if (!configs) {
662 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", 664 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
663 audio_decoder_job_.get()); 665 audio_decoder_job_.get());
664 return; 666 return;
665 } 667 }
666 668
667 // Failed to start the next decode. 669 // Failed to start the next decode.
668 DCHECK(!reconfig_audio_decoder_); 670 DCHECK(!reconfig_audio_decoder_);
669 reconfig_audio_decoder_ = true; 671 reconfig_audio_decoder_ = true;
670 SetDemuxerConfigs(*configs, true); 672 SetDemuxerConfigs(*configs, true);
671 673
672 // Config change may have just been detected on the other stream. If so, 674 // Config change may have just been detected on the other stream. If so,
673 // don't send a duplicate demuxer config request. 675 // don't send a duplicate demuxer config request.
674 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 676 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
675 DCHECK(reconfig_video_decoder_); 677 DCHECK(reconfig_video_decoder_);
676 return; 678 return;
677 } 679 }
678 680
679 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); 681 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
680 } 682 }
681 683
682 void MediaSourcePlayer::DecodeMoreVideo() { 684 void MediaSourcePlayer::DecodeMoreVideo() {
683 DVLOG(1) << __FUNCTION__; 685 DVLOG(1) << __FUNCTION__;
684 DCHECK(!video_decoder_job_->is_decoding()); 686 DCHECK(!video_decoder_job_->is_decoding());
685 DCHECK(!VideoFinished()); 687 DCHECK(!VideoFinished());
686 688
687 scoped_ptr<DemuxerConfigs> configs(video_decoder_job_->Decode( 689 scoped_ptr<DemuxerConfigs> configs(video_decoder_job_->Decode(
688 start_time_ticks_, 690 start_time_ticks_,
689 start_presentation_timestamp_, 691 start_presentation_timestamp_,
690 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 692 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, weak_this_, false)));
691 weak_factory_.GetWeakPtr(),
692 false)));
693 if (!configs) { 693 if (!configs) {
694 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", 694 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
695 video_decoder_job_.get()); 695 video_decoder_job_.get());
696 return; 696 return;
697 } 697 }
698 698
699 // Failed to start the next decode. 699 // Failed to start the next decode.
700 // After this detection of video config change, next video data received 700 // After this detection of video config change, next video data received
701 // will begin with I-frame. 701 // will begin with I-frame.
702 next_video_data_is_iframe_ = true; 702 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 907 // For video only streams, fps can be estimated from the difference
908 // between the previous and current presentation timestamps. The 908 // between the previous and current presentation timestamps. The
909 // previous presentation timestamp is equal to current_timestamp. 909 // previous presentation timestamp is equal to current_timestamp.
910 // TODO(qinmin): determine whether 2 is a good coefficient for estimating 910 // TODO(qinmin): determine whether 2 is a good coefficient for estimating
911 // video frame timeout. 911 // video frame timeout.
912 timeout = 2 * (current_presentation_timestamp - current_timestamp); 912 timeout = 2 * (current_presentation_timestamp - current_timestamp);
913 } 913 }
914 914
915 timeout = std::max(timeout, kMinStarvationTimeout); 915 timeout = std::max(timeout, kMinStarvationTimeout);
916 916
917 decoder_starvation_callback_.Reset(base::Bind( 917 decoder_starvation_callback_.Reset(
918 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr())); 918 base::Bind(&MediaSourcePlayer::OnDecoderStarved, weak_this_));
919 base::MessageLoop::current()->PostDelayedTask( 919 base::MessageLoop::current()->PostDelayedTask(
920 FROM_HERE, decoder_starvation_callback_.callback(), timeout); 920 FROM_HERE, decoder_starvation_callback_.callback(), timeout);
921 } 921 }
922 922
923 void MediaSourcePlayer::SetVolumeInternal() { 923 void MediaSourcePlayer::SetVolumeInternal() {
924 if (audio_decoder_job_ && volume_ >= 0) 924 if (audio_decoder_job_ && volume_ >= 0)
925 audio_decoder_job_->SetVolume(volume_); 925 audio_decoder_job_->SetVolume(volume_);
926 } 926 }
927 927
928 bool MediaSourcePlayer::IsProtectedSurfaceRequired() { 928 bool MediaSourcePlayer::IsProtectedSurfaceRequired() {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 is_audio_encrypted_ = configs.is_audio_encrypted; 1015 is_audio_encrypted_ = configs.is_audio_encrypted;
1016 audio_extra_data_ = configs.audio_extra_data; 1016 audio_extra_data_ = configs.audio_extra_data;
1017 } else { 1017 } else {
1018 video_codec_ = configs.video_codec; 1018 video_codec_ = configs.video_codec;
1019 width_ = configs.video_size.width(); 1019 width_ = configs.video_size.width();
1020 height_ = configs.video_size.height(); 1020 height_ = configs.video_size.height();
1021 is_video_encrypted_ = configs.is_video_encrypted; 1021 is_video_encrypted_ = configs.is_video_encrypted;
1022 } 1022 }
1023 } 1023 }
1024 1024
1025 void MediaSourcePlayer::OnKeyAdded() {
1026 DVLOG(1) << __FUNCTION__;
1027 if (!is_waiting_for_key_)
1028 return;
1029
1030 is_waiting_for_key_ = false;
1031 if (playing_)
1032 StartInternal();
1033 }
1034
1035 void MediaSourcePlayer::OnCdmUnset() {
1036 DVLOG(1) << __FUNCTION__;
1037 DCHECK(drm_bridge_);
1038 // TODO(xhwang): Support detachment of CDM.
1039 DVLOG(1) << "CDM detachment not supported.";
1040 }
1041
1025 } // namespace media 1042 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698