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

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

Issue 1008093002: Determine the audible state in MediaSourcePlayer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor fixes Created 5 years, 9 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 (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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 void MediaSourcePlayer::Release() { 187 void MediaSourcePlayer::Release() {
188 DVLOG(1) << __FUNCTION__; 188 DVLOG(1) << __FUNCTION__;
189 189
190 audio_decoder_job_->ReleaseDecoderResources(); 190 audio_decoder_job_->ReleaseDecoderResources();
191 video_decoder_job_->ReleaseDecoderResources(); 191 video_decoder_job_->ReleaseDecoderResources();
192 192
193 // Prevent player restart, including job re-creation attempts. 193 // Prevent player restart, including job re-creation attempts.
194 playing_ = false; 194 playing_ = false;
195 195
196 decoder_starvation_callback_.Cancel(); 196 decoder_starvation_callback_.Cancel();
197
198 SetAudible(false);
197 DetachListener(); 199 DetachListener();
198 } 200 }
199 201
200 void MediaSourcePlayer::SetVolume(double volume) { 202 void MediaSourcePlayer::SetVolume(double volume) {
201 audio_decoder_job_->SetVolume(volume); 203 audio_decoder_job_->SetVolume(volume);
202 } 204 }
203 205
204 bool MediaSourcePlayer::CanPause() { 206 bool MediaSourcePlayer::CanPause() {
205 return Seekable(); 207 return Seekable();
206 } 208 }
(...skipping 24 matching lines...) Expand all
231 AttachListener(NULL); 233 AttachListener(NULL);
232 234
233 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 235 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
234 ProcessPendingEvents(); 236 ProcessPendingEvents();
235 } 237 }
236 238
237 void MediaSourcePlayer::OnDemuxerConfigsAvailable( 239 void MediaSourcePlayer::OnDemuxerConfigsAvailable(
238 const DemuxerConfigs& configs) { 240 const DemuxerConfigs& configs) {
239 DVLOG(1) << __FUNCTION__; 241 DVLOG(1) << __FUNCTION__;
240 DCHECK(!HasAudio() && !HasVideo()); 242 DCHECK(!HasAudio() && !HasVideo());
243
241 duration_ = configs.duration; 244 duration_ = configs.duration;
242 245
243 audio_decoder_job_->SetDemuxerConfigs(configs); 246 audio_decoder_job_->SetDemuxerConfigs(configs);
244 video_decoder_job_->SetDemuxerConfigs(configs); 247 video_decoder_job_->SetDemuxerConfigs(configs);
245 OnDemuxerConfigsChanged(); 248 OnDemuxerConfigsChanged();
246 } 249 }
247 250
248 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) { 251 void MediaSourcePlayer::OnDemuxerDataAvailable(const DemuxerData& data) {
249 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")"; 252 DVLOG(1) << __FUNCTION__ << "(" << data.type << ")";
250 DCHECK_LT(0u, data.access_units.size()); 253 DCHECK_LT(0u, data.access_units.size());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 395
393 if (IsEventPending(DECODER_CREATION_EVENT_PENDING)) { 396 if (IsEventPending(DECODER_CREATION_EVENT_PENDING)) {
394 // Don't continue if one of the decoder is not created. 397 // Don't continue if one of the decoder is not created.
395 if (is_waiting_for_audio_decoder_ || is_waiting_for_video_decoder_) 398 if (is_waiting_for_audio_decoder_ || is_waiting_for_video_decoder_)
396 return; 399 return;
397 ClearPendingEvent(DECODER_CREATION_EVENT_PENDING); 400 ClearPendingEvent(DECODER_CREATION_EVENT_PENDING);
398 } 401 }
399 402
400 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { 403 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
401 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT."; 404 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
405
402 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1); 406 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
403 407
404 // It is possible that all streams have finished decode, yet starvation 408 // It is possible that all streams have finished decode, yet starvation
405 // occurred during the last stream's EOS decode. In this case, prefetch is a 409 // occurred during the last stream's EOS decode. In this case, prefetch is a
406 // no-op. 410 // no-op.
407 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 411 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
408 if (count == 0) 412 if (count == 0)
409 return; 413 return;
410 414
411 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); 415 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 PlaybackCompleted(is_audio); 490 PlaybackCompleted(is_audio);
487 if (is_clock_manager) 491 if (is_clock_manager)
488 interpolator_.StopInterpolating(); 492 interpolator_.StopInterpolating();
489 } 493 }
490 494
491 if (pending_event_ != NO_EVENT_PENDING) { 495 if (pending_event_ != NO_EVENT_PENDING) {
492 ProcessPendingEvents(); 496 ProcessPendingEvents();
493 return; 497 return;
494 } 498 }
495 499
496 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 500 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
501 if (is_audio)
502 SetAudible(false);
497 return; 503 return;
504 }
498 505
499 if (!playing_) { 506 if (!playing_) {
500 if (is_clock_manager) 507 if (is_clock_manager)
501 interpolator_.StopInterpolating(); 508 interpolator_.StopInterpolating();
509
510 if (is_audio)
511 SetAudible(false);
502 return; 512 return;
503 } 513 }
504 514
505 if (status == MEDIA_CODEC_NO_KEY) { 515 if (status == MEDIA_CODEC_NO_KEY) {
506 if (key_added_while_decode_pending_) { 516 if (key_added_while_decode_pending_) {
507 DVLOG(2) << __FUNCTION__ << ": Key was added during decoding."; 517 DVLOG(2) << __FUNCTION__ << ": Key was added during decoding.";
508 ResumePlaybackAfterKeyAdded(); 518 ResumePlaybackAfterKeyAdded();
509 } else { 519 } else {
520 if (is_audio)
521 SetAudible(false);
522
510 is_waiting_for_key_ = true; 523 is_waiting_for_key_ = true;
511 manager()->OnWaitingForDecryptionKey(player_id()); 524 manager()->OnWaitingForDecryptionKey(player_id());
512 } 525 }
513 return; 526 return;
514 } 527 }
515 528
516 // If |key_added_while_decode_pending_| is true and both audio and video 529 // If |key_added_while_decode_pending_| is true and both audio and video
517 // decoding succeeded, we should clear |key_added_while_decode_pending_| here. 530 // decoding succeeded, we should clear |key_added_while_decode_pending_| here.
518 // But that would add more complexity into this function. If we don't clear it 531 // But that would add more complexity into this function. If we don't clear it
519 // here, the worst case would be we call ResumePlaybackAfterKeyAdded() when 532 // here, the worst case would be we call ResumePlaybackAfterKeyAdded() when
520 // we don't really have a new key. This should rarely happen and the 533 // we don't really have a new key. This should rarely happen and the
521 // performance impact should be pretty small. 534 // performance impact should be pretty small.
522 // TODO(qinmin/xhwang): This class is complicated because we handle both audio 535 // TODO(qinmin/xhwang): This class is complicated because we handle both audio
523 // and video in one file. If we separate them, we should be able to remove a 536 // and video in one file. If we separate them, we should be able to remove a
524 // lot of duplication. 537 // lot of duplication.
525 538
526 // If the status is MEDIA_CODEC_ABORT, stop decoding new data. The player is 539 // If the status is MEDIA_CODEC_ABORT, stop decoding new data. The player is
527 // in the middle of a seek or stop event and needs to wait for the IPCs to 540 // in the middle of a seek or stop event and needs to wait for the IPCs to
528 // come. 541 // come.
529 if (status == MEDIA_CODEC_ABORT) 542 if (status == MEDIA_CODEC_ABORT) {
543 if (is_audio)
544 SetAudible(false);
530 return; 545 return;
546 }
531 547
532 if (prerolling_ && IsPrerollFinished(is_audio)) { 548 if (prerolling_ && IsPrerollFinished(is_audio)) {
533 if (IsPrerollFinished(!is_audio)) { 549 if (IsPrerollFinished(!is_audio)) {
534 prerolling_ = false; 550 prerolling_ = false;
535 StartInternal(); 551 StartInternal();
536 } 552 }
537 return; 553 return;
538 } 554 }
539 555
556 // We successfully decoded a frame and going to the next one.
557 // Set the audible state.
558 if (is_audio) {
559 bool is_audible = !prerolling_ && audio_decoder_job_->volume() > 0;
560 SetAudible(is_audible);
561 }
562
540 if (is_clock_manager) { 563 if (is_clock_manager) {
541 // If we have a valid timestamp, start the starvation callback. Otherwise, 564 // If we have a valid timestamp, start the starvation callback. Otherwise,
542 // reset the |start_time_ticks_| so that the next frame will not suffer 565 // reset the |start_time_ticks_| so that the next frame will not suffer
543 // from the decoding delay caused by the current frame. 566 // from the decoding delay caused by the current frame.
544 if (current_presentation_timestamp != kNoTimestamp()) 567 if (current_presentation_timestamp != kNoTimestamp())
545 StartStarvationCallback(current_presentation_timestamp, 568 StartStarvationCallback(current_presentation_timestamp,
546 max_presentation_timestamp); 569 max_presentation_timestamp);
547 else 570 else
548 start_time_ticks_ = base::TimeTicks::Now(); 571 start_time_ticks_ = base::TimeTicks::Now();
549 } 572 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 bool MediaSourcePlayer::AudioFinished() { 664 bool MediaSourcePlayer::AudioFinished() {
642 return audio_decoder_job_->OutputEOSReached() || !HasAudio(); 665 return audio_decoder_job_->OutputEOSReached() || !HasAudio();
643 } 666 }
644 667
645 bool MediaSourcePlayer::VideoFinished() { 668 bool MediaSourcePlayer::VideoFinished() {
646 return video_decoder_job_->OutputEOSReached() || !HasVideo(); 669 return video_decoder_job_->OutputEOSReached() || !HasVideo();
647 } 670 }
648 671
649 void MediaSourcePlayer::OnDecoderStarved() { 672 void MediaSourcePlayer::OnDecoderStarved() {
650 DVLOG(1) << __FUNCTION__; 673 DVLOG(1) << __FUNCTION__;
674
675 if (HasAudio()) {
676 // If the starvation timer fired but there are no encoded frames
677 // in the queue we believe the demuxer (i.e. renderer process) froze.
678 if (!audio_decoder_job_->HasData())
679 SetAudible(false);
680 }
681
651 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 682 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
652 ProcessPendingEvents(); 683 ProcessPendingEvents();
653 } 684 }
654 685
655 void MediaSourcePlayer::StartStarvationCallback( 686 void MediaSourcePlayer::StartStarvationCallback(
656 base::TimeDelta current_presentation_timestamp, 687 base::TimeDelta current_presentation_timestamp,
657 base::TimeDelta max_presentation_timestamp) { 688 base::TimeDelta max_presentation_timestamp) {
658 // 20ms was chosen because it is the typical size of a compressed audio frame. 689 // 20ms was chosen because it is the typical size of a compressed audio frame.
659 // Anything smaller than this would likely cause unnecessary cycling in and 690 // Anything smaller than this would likely cause unnecessary cycling in and
660 // out of the prefetch state. 691 // out of the prefetch state.
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release 847 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release
817 // MediaDrm when the video is paused, or when the device goes to sleep (see 848 // MediaDrm when the video is paused, or when the device goes to sleep (see
818 // http://crbug.com/272421). 849 // http://crbug.com/272421).
819 audio_decoder_job_->SetDrmBridge(NULL); 850 audio_decoder_job_->SetDrmBridge(NULL);
820 video_decoder_job_->SetDrmBridge(NULL); 851 video_decoder_job_->SetDrmBridge(NULL);
821 cdm_registration_id_ = 0; 852 cdm_registration_id_ = 0;
822 drm_bridge_ = NULL; 853 drm_bridge_ = NULL;
823 } 854 }
824 855
825 } // namespace media 856 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_decoder_job.h ('k') | media/base/android/media_source_player_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698