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

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

Issue 215783002: Fix an issue that audio and video may run out of sync (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressing acolwell's comments Created 6 years, 8 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"
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 #include "media/base/audio_timestamp_helper.h"
23 #include "media/base/buffers.h" 22 #include "media/base/buffers.h"
24 23
25 namespace {
26
27 // Use 16bit PCM for audio output. Keep this value in sync with the output
28 // format we passed to AudioTrack in MediaCodecBridge.
29 const int kBytesPerAudioOutputSample = 2;
30 }
31
32 namespace media { 24 namespace media {
33 25
34 MediaSourcePlayer::MediaSourcePlayer( 26 MediaSourcePlayer::MediaSourcePlayer(
35 int player_id, 27 int player_id,
36 MediaPlayerManager* manager, 28 MediaPlayerManager* manager,
37 const RequestMediaResourcesCB& request_media_resources_cb, 29 const RequestMediaResourcesCB& request_media_resources_cb,
38 const ReleaseMediaResourcesCB& release_media_resources_cb, 30 const ReleaseMediaResourcesCB& release_media_resources_cb,
39 scoped_ptr<DemuxerAndroid> demuxer) 31 scoped_ptr<DemuxerAndroid> demuxer)
40 : MediaPlayerAndroid(player_id, 32 : MediaPlayerAndroid(player_id,
41 manager, 33 manager,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 } 102 }
111 103
112 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding( 104 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding(
113 base::TimeDelta seek_time) { 105 base::TimeDelta seek_time) {
114 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")"; 106 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")";
115 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); 107 DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
116 108
117 pending_seek_ = false; 109 pending_seek_ = false;
118 110
119 clock_.SetTime(seek_time, seek_time); 111 clock_.SetTime(seek_time, seek_time);
120 if (audio_timestamp_helper_)
121 audio_timestamp_helper_->SetBaseTimestamp(seek_time);
122 112
123 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) 113 if (audio_decoder_job_ && audio_decoder_job_->is_decoding())
124 audio_decoder_job_->StopDecode(); 114 audio_decoder_job_->StopDecode();
125 if (video_decoder_job_ && video_decoder_job_->is_decoding()) 115 if (video_decoder_job_ && video_decoder_job_->is_decoding())
126 video_decoder_job_->StopDecode(); 116 video_decoder_job_->StopDecode();
127 117
128 SetPendingEvent(SEEK_EVENT_PENDING); 118 SetPendingEvent(SEEK_EVENT_PENDING);
129 ProcessPendingEvents(); 119 ProcessPendingEvents();
130 } 120 }
131 121
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 const DemuxerConfigs& configs) { 298 const DemuxerConfigs& configs) {
309 DVLOG(1) << __FUNCTION__; 299 DVLOG(1) << __FUNCTION__;
310 duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms); 300 duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms);
311 clock_.SetDuration(duration_); 301 clock_.SetDuration(duration_);
312 302
313 audio_codec_ = configs.audio_codec; 303 audio_codec_ = configs.audio_codec;
314 num_channels_ = configs.audio_channels; 304 num_channels_ = configs.audio_channels;
315 sampling_rate_ = configs.audio_sampling_rate; 305 sampling_rate_ = configs.audio_sampling_rate;
316 is_audio_encrypted_ = configs.is_audio_encrypted; 306 is_audio_encrypted_ = configs.is_audio_encrypted;
317 audio_extra_data_ = configs.audio_extra_data; 307 audio_extra_data_ = configs.audio_extra_data;
318 if (HasAudio()) {
319 DCHECK_GT(num_channels_, 0);
320 audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_));
321 audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime());
322 } else {
323 audio_timestamp_helper_.reset();
324 }
325
326 video_codec_ = configs.video_codec; 308 video_codec_ = configs.video_codec;
327 width_ = configs.video_size.width(); 309 width_ = configs.video_size.width();
328 height_ = configs.video_size.height(); 310 height_ = configs.video_size.height();
329 is_video_encrypted_ = configs.is_video_encrypted; 311 is_video_encrypted_ = configs.is_video_encrypted;
330 312
331 manager()->OnMediaMetadataChanged( 313 manager()->OnMediaMetadataChanged(
332 player_id(), duration_, width_, height_, true); 314 player_id(), duration_, width_, height_, true);
333 315
334 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 316 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
335 if (reconfig_audio_decoder_) 317 if (reconfig_audio_decoder_)
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 // player clock to the actual seek target. 419 // player clock to the actual seek target.
438 if (doing_browser_seek_) { 420 if (doing_browser_seek_) {
439 DCHECK(actual_browser_seek_time != kNoTimestamp()); 421 DCHECK(actual_browser_seek_time != kNoTimestamp());
440 base::TimeDelta seek_time = actual_browser_seek_time; 422 base::TimeDelta seek_time = actual_browser_seek_time;
441 // A browser seek must not jump into the past. Ideally, it seeks to the 423 // A browser seek must not jump into the past. Ideally, it seeks to the
442 // requested time, but it might jump into the future. 424 // requested time, but it might jump into the future.
443 DCHECK(seek_time >= GetCurrentTime()); 425 DCHECK(seek_time >= GetCurrentTime());
444 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " 426 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
445 << seek_time.InSecondsF(); 427 << seek_time.InSecondsF();
446 clock_.SetTime(seek_time, seek_time); 428 clock_.SetTime(seek_time, seek_time);
447 if (audio_timestamp_helper_) 429 if (audio_decoder_job_)
448 audio_timestamp_helper_->SetBaseTimestamp(seek_time); 430 audio_decoder_job_->SetBaseTimestamp(seek_time);
449 } else { 431 } else {
450 DCHECK(actual_browser_seek_time == kNoTimestamp()); 432 DCHECK(actual_browser_seek_time == kNoTimestamp());
451 } 433 }
452 434
453 reached_audio_eos_ = false; 435 reached_audio_eos_ = false;
454 reached_video_eos_ = false; 436 reached_video_eos_ = false;
455 437
456 base::TimeDelta current_time = GetCurrentTime(); 438 base::TimeDelta current_time = GetCurrentTime();
457 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| 439 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
458 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| 440 // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
459 // is calculated from decoder output, while preroll relies on the access 441 // is calculated from decoder output, while preroll relies on the access
460 // unit's timestamp. There are some differences between the two. 442 // unit's timestamp. There are some differences between the two.
461 preroll_timestamp_ = current_time; 443 preroll_timestamp_ = current_time;
462 if (audio_decoder_job_) 444 if (audio_decoder_job_)
463 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 445 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
464 if (video_decoder_job_) 446 if (video_decoder_job_)
465 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 447 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
466 448
467 if (!doing_browser_seek_) 449 if (!doing_browser_seek_)
468 manager()->OnSeekComplete(player_id(), current_time); 450 manager()->OnSeekComplete(player_id(), current_time);
469 451
470 ProcessPendingEvents(); 452 ProcessPendingEvents();
471 } 453 }
472 454
473 void MediaSourcePlayer::UpdateTimestamps( 455 void MediaSourcePlayer::UpdateTimestamps(
474 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) { 456 base::TimeDelta current_presentation_timestamp,
475 base::TimeDelta new_max_time = presentation_timestamp; 457 base::TimeDelta max_presentation_timestamp) {
458 clock_.SetTime(current_presentation_timestamp, max_presentation_timestamp);
476 459
477 if (audio_output_bytes > 0) {
478 audio_timestamp_helper_->AddFrames(
479 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_));
480 new_max_time = audio_timestamp_helper_->GetTimestamp();
481 }
482
483 clock_.SetMaxTime(new_max_time);
484 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); 460 manager()->OnTimeUpdate(player_id(), GetCurrentTime());
485 } 461 }
486 462
487 void MediaSourcePlayer::ProcessPendingEvents() { 463 void MediaSourcePlayer::ProcessPendingEvents() {
488 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; 464 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
489 // Wait for all the decoding jobs to finish before processing pending tasks. 465 // Wait for all the decoding jobs to finish before processing pending tasks.
490 if (video_decoder_job_ && video_decoder_job_->is_decoding()) { 466 if (video_decoder_job_ && video_decoder_job_->is_decoding()) {
491 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; 467 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
492 return; 468 return;
493 } 469 }
494 470
495 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) { 471 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) {
496 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding."; 472 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
497 return; 473 return;
498 } 474 }
499 475
500 if (has_pending_audio_data_request_ || has_pending_video_data_request_) { 476 if (has_pending_audio_data_request_ || has_pending_video_data_request_) {
501 DVLOG(1) << __FUNCTION__ << " : has pending data request."; 477 DVLOG(1) << __FUNCTION__ << " : has pending data request.";
502 return; 478 return;
503 } 479 }
504 480
505 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { 481 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
506 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; 482 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
507 return; 483 return;
508 } 484 }
509 485
510 if (IsEventPending(SEEK_EVENT_PENDING)) { 486 if (IsEventPending(SEEK_EVENT_PENDING)) {
511 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT"; 487 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT";
512 ClearDecodingData(); 488 ClearDecodingData();
489 if (audio_decoder_job_)
490 audio_decoder_job_->SetBaseTimestamp(GetCurrentTime());
513 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_); 491 demuxer_->RequestDemuxerSeek(GetCurrentTime(), doing_browser_seek_);
514 return; 492 return;
515 } 493 }
516 494
517 start_time_ticks_ = base::TimeTicks(); 495 start_time_ticks_ = base::TimeTicks();
518 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 496 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
519 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT."; 497 DVLOG(1) << __FUNCTION__ << " : Handling CONFIG_CHANGE_EVENT.";
520 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_); 498 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_);
521 demuxer_->RequestDemuxerConfigs(); 499 demuxer_->RequestDemuxerConfigs();
522 return; 500 return;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); 552 DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
575 553
576 // Now that all pending events have been handled, resume decoding if we are 554 // Now that all pending events have been handled, resume decoding if we are
577 // still playing. 555 // still playing.
578 if (playing_) 556 if (playing_)
579 StartInternal(); 557 StartInternal();
580 } 558 }
581 559
582 void MediaSourcePlayer::MediaDecoderCallback( 560 void MediaSourcePlayer::MediaDecoderCallback(
583 bool is_audio, MediaCodecStatus status, 561 bool is_audio, MediaCodecStatus status,
584 base::TimeDelta presentation_timestamp, size_t audio_output_bytes) { 562 base::TimeDelta current_presentation_timestamp,
563 base::TimeDelta max_presentation_timestamp) {
585 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; 564 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status;
586 565
587 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed. 566 // TODO(xhwang): Drop IntToString() when http://crbug.com/303899 is fixed.
588 if (is_audio) { 567 if (is_audio) {
589 TRACE_EVENT_ASYNC_END1("media", 568 TRACE_EVENT_ASYNC_END1("media",
590 "MediaSourcePlayer::DecodeMoreAudio", 569 "MediaSourcePlayer::DecodeMoreAudio",
591 audio_decoder_job_.get(), 570 audio_decoder_job_.get(),
592 "MediaCodecStatus", 571 "MediaCodecStatus",
593 base::IntToString(status)); 572 base::IntToString(status));
594 } else { 573 } else {
(...skipping 23 matching lines...) Expand all
618 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING)); 597 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
619 598
620 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of 599 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
621 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process 600 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
622 // any other pending events only after handling EOS detection. 601 // any other pending events only after handling EOS detection.
623 if (IsEventPending(SEEK_EVENT_PENDING)) { 602 if (IsEventPending(SEEK_EVENT_PENDING)) {
624 ProcessPendingEvents(); 603 ProcessPendingEvents();
625 return; 604 return;
626 } 605 }
627 606
607 if (status == MEDIA_CODEC_OK && is_clock_manager &&
608 current_presentation_timestamp != kNoTimestamp()) {
609 UpdateTimestamps(
610 current_presentation_timestamp, max_presentation_timestamp);
611 }
612
628 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 613 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
629 PlaybackCompleted(is_audio); 614 PlaybackCompleted(is_audio);
630 615
631 if (pending_event_ != NO_EVENT_PENDING) { 616 if (pending_event_ != NO_EVENT_PENDING) {
632 ProcessPendingEvents(); 617 ProcessPendingEvents();
633 return; 618 return;
634 } 619 }
635 620
636 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 621 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
637 return; 622 return;
638 623
639 if (status == MEDIA_CODEC_OK && is_clock_manager &&
640 presentation_timestamp != kNoTimestamp()) {
641 UpdateTimestamps(presentation_timestamp, audio_output_bytes);
642 }
643
644 if (!playing_) { 624 if (!playing_) {
645 if (is_clock_manager) 625 if (is_clock_manager)
646 clock_.Pause(); 626 clock_.Pause();
647 return; 627 return;
648 } 628 }
649 629
650 if (status == MEDIA_CODEC_NO_KEY) { 630 if (status == MEDIA_CODEC_NO_KEY) {
651 is_waiting_for_key_ = true; 631 is_waiting_for_key_ = true;
652 return; 632 return;
653 } 633 }
654 634
655 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is 635 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
656 // in the middle of a seek or stop event and needs to wait for the IPCs to 636 // in the middle of a seek or stop event and needs to wait for the IPCs to
657 // come. 637 // come.
658 if (status == MEDIA_CODEC_STOPPED) 638 if (status == MEDIA_CODEC_STOPPED)
659 return; 639 return;
660 640
661 if (is_clock_manager) { 641 if (is_clock_manager) {
662 // If we have a valid timestamp, start the starvation callback. Otherwise, 642 // If we have a valid timestamp, start the starvation callback. Otherwise,
663 // reset the |start_time_ticks_| so that the next frame will not suffer 643 // reset the |start_time_ticks_| so that the next frame will not suffer
664 // from the decoding delay caused by the current frame. 644 // from the decoding delay caused by the current frame.
665 if (presentation_timestamp != kNoTimestamp()) 645 if (current_presentation_timestamp != kNoTimestamp())
666 StartStarvationCallback(presentation_timestamp); 646 StartStarvationCallback(current_presentation_timestamp,
647 max_presentation_timestamp);
667 else 648 else
668 start_time_ticks_ = base::TimeTicks::Now(); 649 start_time_ticks_ = base::TimeTicks::Now();
669 } 650 }
670 651
671 if (is_audio) { 652 if (is_audio) {
672 DecodeMoreAudio(); 653 DecodeMoreAudio();
673 return; 654 return;
674 } 655 }
675 656
676 DecodeMoreVideo(); 657 DecodeMoreVideo();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 ResetAudioDecoderJob(); 785 ResetAudioDecoderJob();
805 DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job"; 786 DVLOG(1) << __FUNCTION__ << " : creating new audio decoder job";
806 audio_decoder_job_.reset(AudioDecoderJob::Create( 787 audio_decoder_job_.reset(AudioDecoderJob::Create(
807 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0], 788 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
808 audio_extra_data_.size(), media_crypto.obj(), 789 audio_extra_data_.size(), media_crypto.obj(),
809 base::Bind(&DemuxerAndroid::RequestDemuxerData, 790 base::Bind(&DemuxerAndroid::RequestDemuxerData,
810 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO))); 791 base::Unretained(demuxer_.get()), DemuxerStream::AUDIO)));
811 792
812 if (audio_decoder_job_) { 793 if (audio_decoder_job_) {
813 SetVolumeInternal(); 794 SetVolumeInternal();
795 // Need to reset the base timestamp in |audio_decoder_job_|.
796 // TODO(qinmin): When reconfiguring the |audio_decoder_job_|, there might
797 // still be some audio frames in the decoder or in AudioTrack. Therefore,
798 // we are losing some time here. http://crbug.com/357726.
799 base::TimeDelta current_time = GetCurrentTime();
800 audio_decoder_job_->SetBaseTimestamp(current_time);
801 clock_.SetTime(current_time, current_time);
814 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 802 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
815 reconfig_audio_decoder_ = false; 803 reconfig_audio_decoder_ = false;
816 } 804 }
817 } 805 }
818 806
819 void MediaSourcePlayer::ResetVideoDecoderJob() { 807 void MediaSourcePlayer::ResetVideoDecoderJob() {
820 if (video_decoder_job_) { 808 if (video_decoder_job_) {
821 has_pending_video_data_request_ = 809 has_pending_video_data_request_ =
822 video_decoder_job_->is_requesting_demuxer_data(); 810 video_decoder_job_->is_requesting_demuxer_data();
823 } 811 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 player_id(), duration_, width_, height_, true); 893 player_id(), duration_, width_, height_, true);
906 } 894 }
907 895
908 void MediaSourcePlayer::OnDecoderStarved() { 896 void MediaSourcePlayer::OnDecoderStarved() {
909 DVLOG(1) << __FUNCTION__; 897 DVLOG(1) << __FUNCTION__;
910 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 898 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
911 ProcessPendingEvents(); 899 ProcessPendingEvents();
912 } 900 }
913 901
914 void MediaSourcePlayer::StartStarvationCallback( 902 void MediaSourcePlayer::StartStarvationCallback(
915 base::TimeDelta presentation_timestamp) { 903 base::TimeDelta current_presentation_timestamp,
904 base::TimeDelta max_presentation_timestamp) {
916 // 20ms was chosen because it is the typical size of a compressed audio frame. 905 // 20ms was chosen because it is the typical size of a compressed audio frame.
917 // Anything smaller than this would likely cause unnecessary cycling in and 906 // Anything smaller than this would likely cause unnecessary cycling in and
918 // out of the prefetch state. 907 // out of the prefetch state.
919 const base::TimeDelta kMinStarvationTimeout = 908 const base::TimeDelta kMinStarvationTimeout =
920 base::TimeDelta::FromMilliseconds(20); 909 base::TimeDelta::FromMilliseconds(20);
921 910
922 base::TimeDelta current_timestamp = GetCurrentTime(); 911 base::TimeDelta current_timestamp = GetCurrentTime();
923 base::TimeDelta timeout; 912 base::TimeDelta timeout;
924 if (HasAudio()) { 913 if (HasAudio()) {
925 timeout = audio_timestamp_helper_->GetTimestamp() - current_timestamp; 914 timeout = max_presentation_timestamp - current_timestamp;
926 } else { 915 } else {
927 DCHECK(current_timestamp <= presentation_timestamp); 916 DCHECK(current_timestamp <= current_presentation_timestamp);
928 917
929 // For video only streams, fps can be estimated from the difference 918 // For video only streams, fps can be estimated from the difference
930 // between the previous and current presentation timestamps. The 919 // between the previous and current presentation timestamps. The
931 // previous presentation timestamp is equal to current_timestamp. 920 // previous presentation timestamp is equal to current_timestamp.
932 // TODO(qinmin): determine whether 2 is a good coefficient for estimating 921 // TODO(qinmin): determine whether 2 is a good coefficient for estimating
933 // video frame timeout. 922 // video frame timeout.
934 timeout = 2 * (presentation_timestamp - current_timestamp); 923 timeout = 2 * (current_presentation_timestamp - current_timestamp);
935 } 924 }
936 925
937 timeout = std::max(timeout, kMinStarvationTimeout); 926 timeout = std::max(timeout, kMinStarvationTimeout);
938 927
939 decoder_starvation_callback_.Reset(base::Bind( 928 decoder_starvation_callback_.Reset(base::Bind(
940 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr())); 929 &MediaSourcePlayer::OnDecoderStarved, weak_factory_.GetWeakPtr()));
941 base::MessageLoop::current()->PostDelayedTask( 930 base::MessageLoop::current()->PostDelayedTask(
942 FROM_HERE, decoder_starvation_callback_.callback(), timeout); 931 FROM_HERE, decoder_starvation_callback_.callback(), timeout);
943 } 932 }
944 933
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 1008
1020 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 1009 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
1021 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 1010 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
1022 DCHECK_NE(event, NO_EVENT_PENDING); 1011 DCHECK_NE(event, NO_EVENT_PENDING);
1023 DCHECK(IsEventPending(event)) << GetEventName(event); 1012 DCHECK(IsEventPending(event)) << GetEventName(event);
1024 1013
1025 pending_event_ &= ~event; 1014 pending_event_ &= ~event;
1026 } 1015 }
1027 1016
1028 } // namespace media 1017 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.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