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

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

Issue 643703009: MediaSourcePlayer: Handle the case where key is added during decoding. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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_source_player.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
11 #include "base/barrier_closure.h" 11 #include "base/barrier_closure.h"
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/debug/trace_event.h" 15 #include "base/debug/trace_event.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "media/base/android/audio_decoder_job.h" 18 #include "media/base/android/audio_decoder_job.h"
19 #include "media/base/android/media_drm_bridge.h" 19 #include "media/base/android/media_drm_bridge.h"
20 #include "media/base/android/media_player_manager.h" 20 #include "media/base/android/media_player_manager.h"
21 #include "media/base/android/video_decoder_job.h" 21 #include "media/base/android/video_decoder_job.h"
22 22
23
24 namespace media { 23 namespace media {
25 24
26 MediaSourcePlayer::MediaSourcePlayer( 25 MediaSourcePlayer::MediaSourcePlayer(
27 int player_id, 26 int player_id,
28 MediaPlayerManager* manager, 27 MediaPlayerManager* manager,
29 const RequestMediaResourcesCB& request_media_resources_cb, 28 const RequestMediaResourcesCB& request_media_resources_cb,
30 scoped_ptr<DemuxerAndroid> demuxer, 29 scoped_ptr<DemuxerAndroid> demuxer,
31 const GURL& frame_url) 30 const GURL& frame_url)
32 : MediaPlayerAndroid(player_id, 31 : MediaPlayerAndroid(player_id,
33 manager, 32 manager,
34 request_media_resources_cb, 33 request_media_resources_cb,
35 frame_url), 34 frame_url),
36 demuxer_(demuxer.Pass()), 35 demuxer_(demuxer.Pass()),
37 pending_event_(NO_EVENT_PENDING), 36 pending_event_(NO_EVENT_PENDING),
38 playing_(false), 37 playing_(false),
39 interpolator_(&default_tick_clock_), 38 interpolator_(&default_tick_clock_),
40 doing_browser_seek_(false), 39 doing_browser_seek_(false),
41 pending_seek_(false), 40 pending_seek_(false),
42 drm_bridge_(NULL), 41 drm_bridge_(NULL),
43 cdm_registration_id_(0), 42 cdm_registration_id_(0),
44 is_waiting_for_key_(false), 43 is_waiting_for_key_(false),
44 key_added_while_decode_pending_(false),
45 is_waiting_for_audio_decoder_(false), 45 is_waiting_for_audio_decoder_(false),
46 is_waiting_for_video_decoder_(false), 46 is_waiting_for_video_decoder_(false),
47 prerolling_(true), 47 prerolling_(true),
48 weak_factory_(this) { 48 weak_factory_(this) {
49 audio_decoder_job_.reset(new AudioDecoderJob( 49 audio_decoder_job_.reset(new AudioDecoderJob(
50 base::Bind(&DemuxerAndroid::RequestDemuxerData, 50 base::Bind(&DemuxerAndroid::RequestDemuxerData,
51 base::Unretained(demuxer_.get()), 51 base::Unretained(demuxer_.get()),
52 DemuxerStream::AUDIO), 52 DemuxerStream::AUDIO),
53 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, 53 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
54 weak_factory_.GetWeakPtr()))); 54 weak_factory_.GetWeakPtr())));
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 bool MediaSourcePlayer::IsPlayerReady() { 216 bool MediaSourcePlayer::IsPlayerReady() {
217 return audio_decoder_job_ || video_decoder_job_; 217 return audio_decoder_job_ || video_decoder_job_;
218 } 218 }
219 219
220 void MediaSourcePlayer::StartInternal() { 220 void MediaSourcePlayer::StartInternal() {
221 DVLOG(1) << __FUNCTION__; 221 DVLOG(1) << __FUNCTION__;
222 // If there are pending events, wait for them finish. 222 // If there are pending events, wait for them finish.
223 if (pending_event_ != NO_EVENT_PENDING) 223 if (pending_event_ != NO_EVENT_PENDING)
224 return; 224 return;
225 225
226 // When we start, we'll have new demuxed data coming in. This new data could 226 // When we start, we could have new demuxed data coming in. This new data
227 // be clear (not encrypted) or encrypted with different keys. So 227 // could be clear (not encrypted) or encrypted with different keys. So key
228 // |is_waiting_for_key_| condition may not be true anymore. 228 // related info should all be cleared.
229 is_waiting_for_key_ = false; 229 is_waiting_for_key_ = false;
230 key_added_while_decode_pending_ = false;
230 AttachListener(NULL); 231 AttachListener(NULL);
231 232
232 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 233 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
233 ProcessPendingEvents(); 234 ProcessPendingEvents();
234 } 235 }
235 236
236 void MediaSourcePlayer::OnDemuxerConfigsAvailable( 237 void MediaSourcePlayer::OnDemuxerConfigsAvailable(
237 const DemuxerConfigs& configs) { 238 const DemuxerConfigs& configs) {
238 DVLOG(1) << __FUNCTION__; 239 DVLOG(1) << __FUNCTION__;
239 DCHECK(!HasAudio() && !HasVideo()); 240 DCHECK(!HasAudio() && !HasVideo());
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 496 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
496 return; 497 return;
497 498
498 if (!playing_) { 499 if (!playing_) {
499 if (is_clock_manager) 500 if (is_clock_manager)
500 interpolator_.StopInterpolating(); 501 interpolator_.StopInterpolating();
501 return; 502 return;
502 } 503 }
503 504
504 if (status == MEDIA_CODEC_NO_KEY) { 505 if (status == MEDIA_CODEC_NO_KEY) {
505 is_waiting_for_key_ = true; 506 if (key_added_while_decode_pending_) {
507 DVLOG(2) << __FUNCTION__ << ": Key was added during decoding.";
508 ResumePlaybackAfterKeyAdded();
509 } else {
510 is_waiting_for_key_ = true;
511 }
506 return; 512 return;
507 } 513 }
508 514
515 // If |key_added_while_decode_pending_| is true and both audio and video
516 // decoding succeeded, we should clear |key_added_while_decode_pending_| here.
517 // But that would add more complexity into this function. If we don't clear it
518 // here, the worst case would be we call ResumePlaybackAfterKeyAdded() when
519 // we don't really have a new key. This should rarely happen and the
520 // performance impact should be pretty small.
521 // TODO(qinmin/xhwang): This class is complicated because we handle both audio
522 // and video in one file. If we separate them, we should be able to remove a
523 // lot of duplication.
524
509 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is 525 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
510 // in the middle of a seek or stop event and needs to wait for the IPCs to 526 // in the middle of a seek or stop event and needs to wait for the IPCs to
511 // come. 527 // come.
512 if (status == MEDIA_CODEC_STOPPED) 528 if (status == MEDIA_CODEC_STOPPED)
513 return; 529 return;
514 530
515 if (prerolling_ && IsPrerollFinished(is_audio)) { 531 if (prerolling_ && IsPrerollFinished(is_audio)) {
516 if (IsPrerollFinished(!is_audio)) { 532 if (IsPrerollFinished(!is_audio)) {
517 prerolling_ = false; 533 prerolling_ = false;
518 StartInternal(); 534 StartInternal();
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 if (audio) 764 if (audio)
749 is_waiting_for_audio_decoder_ = false; 765 is_waiting_for_audio_decoder_ = false;
750 if (video) 766 if (video)
751 is_waiting_for_video_decoder_ = false; 767 is_waiting_for_video_decoder_ = false;
752 if (IsEventPending(DECODER_CREATION_EVENT_PENDING)) 768 if (IsEventPending(DECODER_CREATION_EVENT_PENDING))
753 ProcessPendingEvents(); 769 ProcessPendingEvents();
754 } 770 }
755 771
756 void MediaSourcePlayer::OnKeyAdded() { 772 void MediaSourcePlayer::OnKeyAdded() {
757 DVLOG(1) << __FUNCTION__; 773 DVLOG(1) << __FUNCTION__;
758 if (!is_waiting_for_key_) 774
775 if (is_waiting_for_key_) {
776 ResumePlaybackAfterKeyAdded();
759 return; 777 return;
778 }
779
780 if ((audio_decoder_job_->is_content_encrypted() &&
781 audio_decoder_job_->is_decoding()) ||
782 (video_decoder_job_->is_content_encrypted() &&
783 video_decoder_job_->is_decoding())) {
784 DVLOG(1) << __FUNCTION__ << ": " << "Key added during pending decode.";
785 key_added_while_decode_pending_ = true;
786 }
787 }
788
789 void MediaSourcePlayer::ResumePlaybackAfterKeyAdded() {
790 DVLOG(1) << __FUNCTION__;
791 DCHECK(is_waiting_for_key_ || key_added_while_decode_pending_);
760 792
761 is_waiting_for_key_ = false; 793 is_waiting_for_key_ = false;
794 key_added_while_decode_pending_ = false;
795
796 // StartInternal() will trigger a prefetch, where in most cases we'll just
797 // use previously received data.
762 if (playing_) 798 if (playing_)
763 StartInternal(); 799 StartInternal();
764 } 800 }
765 801
766 void MediaSourcePlayer::OnCdmUnset() { 802 void MediaSourcePlayer::OnCdmUnset() {
767 DVLOG(1) << __FUNCTION__; 803 DVLOG(1) << __FUNCTION__;
768 DCHECK(drm_bridge_); 804 DCHECK(drm_bridge_);
769 // TODO(xhwang): Currently this is only called during teardown. Support full 805 // TODO(xhwang): Currently this is only called during teardown. Support full
770 // detachment of CDM during playback. This will be needed when we start to 806 // detachment of CDM during playback. This will be needed when we start to
771 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release 807 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release
772 // MediaDrm when the video is paused, or when the device goes to sleep (see 808 // MediaDrm when the video is paused, or when the device goes to sleep (see
773 // http://crbug.com/272421). 809 // http://crbug.com/272421).
774 audio_decoder_job_->SetDrmBridge(NULL); 810 audio_decoder_job_->SetDrmBridge(NULL);
775 video_decoder_job_->SetDrmBridge(NULL); 811 video_decoder_job_->SetDrmBridge(NULL);
776 cdm_registration_id_ = 0; 812 cdm_registration_id_ = 0;
777 drm_bridge_ = NULL; 813 drm_bridge_ = NULL;
778 } 814 }
779 815
780 } // namespace media 816 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698