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

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

Issue 1242913004: MediaCodecPlayer implementation (stage 3 - browser seek and surface change) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-seek
Patch Set: Addressed Min comments, added unit tests. Created 5 years, 5 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_codec_player.h" 5 #include "media/base/android/media_codec_player.h"
6 6
7 #include "base/barrier_closure.h" 7 #include "base/barrier_closure.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 DCHECK(ui_task_runner_->BelongsToCurrentThread()); 66 DCHECK(ui_task_runner_->BelongsToCurrentThread());
67 67
68 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id; 68 DVLOG(1) << "MediaCodecPlayer::MediaCodecPlayer: player_id:" << player_id;
69 69
70 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id); 70 request_resources_cb_ = base::Bind(request_media_resources_cb_, player_id);
71 71
72 completion_cb_ = 72 completion_cb_ =
73 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id); 73 base::Bind(&MediaPlayerManager::OnPlaybackComplete, manager, player_id);
74 seek_done_cb_ = 74 seek_done_cb_ =
75 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id); 75 base::Bind(&MediaPlayerManager::OnSeekComplete, manager, player_id);
76 error_cb_ = base::Bind(&MediaPlayerManager::OnError, manager, player_id);
76 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener, 77 attach_listener_cb_ = base::Bind(&MediaPlayerAndroid::AttachListener,
77 WeakPtrForUIThread(), nullptr); 78 WeakPtrForUIThread(), nullptr);
78 detach_listener_cb_ = 79 detach_listener_cb_ =
79 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread()); 80 base::Bind(&MediaPlayerAndroid::DetachListener, WeakPtrForUIThread());
80 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged, 81 metadata_changed_cb_ = base::Bind(&MediaPlayerAndroid::OnMediaMetadataChanged,
81 WeakPtrForUIThread()); 82 WeakPtrForUIThread());
82 time_update_cb_ = 83 time_update_cb_ =
83 base::Bind(&MediaPlayerAndroid::OnTimeUpdate, WeakPtrForUIThread()); 84 base::Bind(&MediaPlayerAndroid::OnTimeUpdate, WeakPtrForUIThread());
84 85
85 media_weak_this_ = media_weak_factory_.GetWeakPtr(); 86 media_weak_this_ = media_weak_factory_.GetWeakPtr();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 124
124 // Post deletion onto Media thread 125 // Post deletion onto Media thread
125 GetMediaTaskRunner()->DeleteSoon(FROM_HERE, this); 126 GetMediaTaskRunner()->DeleteSoon(FROM_HERE, this);
126 } 127 }
127 128
128 void MediaCodecPlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { 129 void MediaCodecPlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
129 RUN_ON_MEDIA_THREAD(SetVideoSurface, base::Passed(&surface)); 130 RUN_ON_MEDIA_THREAD(SetVideoSurface, base::Passed(&surface));
130 131
131 DVLOG(1) << __FUNCTION__ << (surface.IsEmpty() ? " empty" : " non-empty"); 132 DVLOG(1) << __FUNCTION__ << (surface.IsEmpty() ? " empty" : " non-empty");
132 133
133 // I assume that if video decoder already has the surface, 134 // Save the empty-ness before we pass the surface to the decoder.
134 // there will be two calls: 135 bool surface_is_empty = surface.IsEmpty();
135 // (1) SetVideoSurface(0)
136 // (2) SetVideoSurface(new_surface)
137 video_decoder_->SetPendingSurface(surface.Pass());
138 136
139 if (video_decoder_->HasPendingSurface() && 137 // Apparently RemoveVideoSurface() can be called several times in a row,
140 state_ == STATE_WAITING_FOR_SURFACE) { 138 // ignore the second and subsequent calls.
141 SetState(STATE_PLAYING); 139 if (surface_is_empty && !video_decoder_->HasVideoSurface()) {
142 StartPlaybackDecoders(); 140 DVLOG(1) << __FUNCTION__ << ": surface already removed, ignoring";
141 return;
142 }
143
144 video_decoder_->SetVideoSurface(surface.Pass());
145
146 if (surface_is_empty) {
147 // Remove video surface.
148 switch (state_) {
149 case STATE_PLAYING:
150 if (VideoFinished())
151 break;
152
153 DVLOG(1) << __FUNCTION__ << ": stopping and restarting";
154 // Stop decoders as quickly as possible.
155 StopDecoders(); // synchronous stop
156
157 // Prefetch or wait for initial configuration.
158 if (HasAudio() || HasVideo()) {
159 SetState(STATE_PREFETCHING);
160 StartPrefetchDecoders();
161 } else {
162 SetState(STATE_WAITING_FOR_CONFIG);
163 }
164 break;
165
166 default:
167 break; // ignore
168 }
169 } else {
170 // Replace video surface.
171 switch (state_) {
172 case STATE_WAITING_FOR_SURFACE:
173 SetState(STATE_PLAYING);
174 StartPlaybackOrBrowserSeek();
175 break;
176
177 case STATE_PLAYING:
178 if (VideoFinished())
179 break;
180
181 DVLOG(1) << __FUNCTION__ << ": requesting to stop and restart";
182 SetState(STATE_STOPPING);
183 RequestToStopDecoders();
184 SetPendingStart(true);
185 break;
186
187 default:
188 break; // ignore
189 }
143 } 190 }
144 } 191 }
145 192
146 void MediaCodecPlayer::Start() { 193 void MediaCodecPlayer::Start() {
147 RUN_ON_MEDIA_THREAD(Start); 194 RUN_ON_MEDIA_THREAD(Start);
148 195
149 DVLOG(1) << __FUNCTION__; 196 DVLOG(1) << __FUNCTION__;
150 197
151 switch (state_) { 198 switch (state_) {
152 case STATE_PAUSED: 199 case STATE_PAUSED:
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 << " ignoring"; 511 << " ignoring";
465 return; // Ignore 512 return; // Ignore
466 } 513 }
467 514
468 DVLOG(1) << __FUNCTION__; 515 DVLOG(1) << __FUNCTION__;
469 516
470 if (!HasAudio() && !HasVideo()) { 517 if (!HasAudio() && !HasVideo()) {
471 // No configuration at all after prefetching. 518 // No configuration at all after prefetching.
472 // This is an error, initial configuration is expected 519 // This is an error, initial configuration is expected
473 // before the first data chunk. 520 // before the first data chunk.
474 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 521 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
475 return; 522 return;
476 } 523 }
477 524
478 if (HasVideo() && !HasPendingSurface()) { 525 if (HasVideo() && !video_decoder_->HasVideoSurface()) {
479 SetState(STATE_WAITING_FOR_SURFACE); 526 SetState(STATE_WAITING_FOR_SURFACE);
480 return; 527 return;
481 } 528 }
482 529
483 SetState(STATE_PLAYING); 530 SetState(STATE_PLAYING);
484 StartPlaybackDecoders(); 531 StartPlaybackOrBrowserSeek();
485 } 532 }
486 533
487 void MediaCodecPlayer::OnStopDone() { 534 void MediaCodecPlayer::OnStopDone() {
488 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 535 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
489 DVLOG(1) << __FUNCTION__; 536 DVLOG(1) << __FUNCTION__;
490 537
491 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) 538 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped()))
492 return; // Wait until other stream is stopped 539 return; // Wait until other stream is stopped
493 540
494 // At this point decoder threads should not be running 541 // At this point decoder threads should not be running
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 } 580 }
534 581
535 void MediaCodecPlayer::OnError() { 582 void MediaCodecPlayer::OnError() {
536 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 583 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
537 DVLOG(1) << __FUNCTION__; 584 DVLOG(1) << __FUNCTION__;
538 585
539 // STATE_ERROR blocks all events 586 // STATE_ERROR blocks all events
540 SetState(STATE_ERROR); 587 SetState(STATE_ERROR);
541 588
542 ReleaseDecoderResources(); 589 ReleaseDecoderResources();
590
591 ui_task_runner_->PostTask(FROM_HERE,
592 base::Bind(error_cb_, MEDIA_ERROR_DECODE));
543 } 593 }
544 594
545 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) { 595 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) {
546 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 596 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
547 DVLOG(1) << __FUNCTION__ << " stream type:" << type; 597 DVLOG(1) << __FUNCTION__ << " stream type:" << type;
548 598
549 if (state_ != STATE_PLAYING) 599 if (state_ != STATE_PLAYING)
550 return; // Ignore 600 return; // Ignore
551 601
552 SetState(STATE_STOPPING); 602 SetState(STATE_STOPPING);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 649
600 // State machine operations, called on Media thread 650 // State machine operations, called on Media thread
601 651
602 void MediaCodecPlayer::SetState(PlayerState new_state) { 652 void MediaCodecPlayer::SetState(PlayerState new_state) {
603 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 653 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
604 654
605 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); 655 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state);
606 state_ = new_state; 656 state_ = new_state;
607 } 657 }
608 658
609 void MediaCodecPlayer::SetPendingSurface(gfx::ScopedJavaSurface surface) {
610 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
611 DVLOG(1) << __FUNCTION__;
612
613 video_decoder_->SetPendingSurface(surface.Pass());
614 }
615
616 bool MediaCodecPlayer::HasPendingSurface() {
617 return video_decoder_->HasPendingSurface();
618 }
619
620 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { 659 void MediaCodecPlayer::SetPendingStart(bool need_to_start) {
621 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 660 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
622 DVLOG(1) << __FUNCTION__ << ": " << need_to_start; 661 DVLOG(1) << __FUNCTION__ << ": " << need_to_start;
623 pending_start_ = need_to_start; 662 pending_start_ = need_to_start;
624 } 663 }
625 664
626 bool MediaCodecPlayer::HasPendingStart() { 665 bool MediaCodecPlayer::HasPendingStart() {
627 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 666 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
628 return pending_start_; 667 return pending_start_;
629 } 668 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 base::Closure prefetch_cb = base::BarrierClosure( 732 base::Closure prefetch_cb = base::BarrierClosure(
694 count, base::Bind(&MediaCodecPlayer::OnPrefetchDone, media_weak_this_)); 733 count, base::Bind(&MediaCodecPlayer::OnPrefetchDone, media_weak_this_));
695 734
696 if (do_audio) 735 if (do_audio)
697 audio_decoder_->Prefetch(prefetch_cb); 736 audio_decoder_->Prefetch(prefetch_cb);
698 737
699 if (do_video) 738 if (do_video)
700 video_decoder_->Prefetch(prefetch_cb); 739 video_decoder_->Prefetch(prefetch_cb);
701 } 740 }
702 741
703 void MediaCodecPlayer::StartPlaybackDecoders() { 742 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() {
704 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 743 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
705 DVLOG(1) << __FUNCTION__; 744 DVLOG(1) << __FUNCTION__;
706 745
707 // Configure all streams before the start since 746 // TODO(timav): consider replacing this method with posting a
708 // we may discover that browser seek is required. 747 // browser seek task (i.e. generate an event) from StartPlaybackDecoders().
748
749 StartStatus status = StartPlaybackDecoders();
750
751 switch (status) {
752 case START_BROWSER_SEEK_REQUIRED:
753 // Browser seek
754 SetState(STATE_WAITING_FOR_SEEK);
755 SetPendingStart(true);
756 StopDecoders();
757 RequestDemuxerSeek(GetInterpolatedTime(), true);
758 break;
759 case START_FAILED:
760 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
761 break;
762 case START_OK:
763 break;
764 }
765 }
766
767 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() {
768 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
769 DVLOG(1) << __FUNCTION__;
709 770
710 bool do_audio = !AudioFinished(); 771 bool do_audio = !AudioFinished();
711 bool do_video = !VideoFinished(); 772 bool do_video = !VideoFinished();
712 773
713 // If there is nothing to play, the state machine should determine 774 // If there is nothing to play, the state machine should determine this at the
714 // this at the prefetch state and never call this method. 775 // prefetch state and never call this method.
715 DCHECK(do_audio || do_video); 776 DCHECK(do_audio || do_video);
716 777
778 // Configure all streams before the start since we may discover that browser
779 // seek is required. Start with video: if browser seek is required it would
780 // not make sense to configure audio.
781
782 if (do_video) {
783 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure();
784 switch (status) {
785 case MediaCodecDecoder::CONFIG_OK:
786 break;
787 case MediaCodecDecoder::CONFIG_KEY_FRAME_REQUIRED:
788 // TODO(timav): post a task or return the status?
789 return START_BROWSER_SEEK_REQUIRED;
790 case MediaCodecDecoder::CONFIG_FAILURE:
791 return START_FAILED;
792 }
793 }
794
717 if (do_audio) { 795 if (do_audio) {
718 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); 796 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure();
719 if (status != MediaCodecDecoder::CONFIG_OK) { 797 if (status != MediaCodecDecoder::CONFIG_OK) {
720 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 798 return START_FAILED;
721 return;
722 } 799 }
723 } 800 }
724 801
725 if (do_video) {
726 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure();
727 if (status != MediaCodecDecoder::CONFIG_OK) {
728 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_);
729 return;
730 }
731 }
732
733 // At this point decoder threads should not be running. 802 // At this point decoder threads should not be running.
734 if (!interpolator_.interpolating()) 803 if (!interpolator_.interpolating())
735 interpolator_.StartInterpolating(); 804 interpolator_.StartInterpolating();
736 805
737 base::TimeDelta current_time = GetInterpolatedTime(); 806 base::TimeDelta current_time = GetInterpolatedTime();
738 807
739 if (do_audio) { 808 if (do_audio) {
740 if (!audio_decoder_->Start(current_time)) { 809 if (!audio_decoder_->Start(current_time)) {
741 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 810 return START_FAILED;
742 return;
743 } 811 }
744 812
745 // Attach listener on UI thread 813 // Attach listener on UI thread
746 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_); 814 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_);
747 } 815 }
748 816
749 if (do_video) { 817 if (do_video) {
750 if (!video_decoder_->Start(current_time)) { 818 if (!video_decoder_->Start(current_time)) {
751 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 819 return START_FAILED;
752 return;
753 } 820 }
754 } 821 }
822
823 return START_OK;
755 } 824 }
756 825
757 void MediaCodecPlayer::StopDecoders() { 826 void MediaCodecPlayer::StopDecoders() {
758 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 827 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
759 DVLOG(1) << __FUNCTION__; 828 DVLOG(1) << __FUNCTION__;
760 829
830 video_decoder_->SyncStop();
761 audio_decoder_->SyncStop(); 831 audio_decoder_->SyncStop();
762 video_decoder_->SyncStop();
763 } 832 }
764 833
765 void MediaCodecPlayer::RequestToStopDecoders() { 834 void MediaCodecPlayer::RequestToStopDecoders() {
766 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 835 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
767 DVLOG(1) << __FUNCTION__; 836 DVLOG(1) << __FUNCTION__;
768 837
769 bool do_audio = false; 838 bool do_audio = false;
770 bool do_video = false; 839 bool do_video = false;
771 840
772 if (audio_decoder_->IsPrefetchingOrPlaying()) 841 if (audio_decoder_->IsPrefetchingOrPlaying())
(...skipping 10 matching lines...) Expand all
783 if (do_audio) 852 if (do_audio)
784 audio_decoder_->RequestToStop(); 853 audio_decoder_->RequestToStop();
785 if (do_video) 854 if (do_video)
786 video_decoder_->RequestToStop(); 855 video_decoder_->RequestToStop();
787 } 856 }
788 857
789 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, 858 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time,
790 bool is_browser_seek) { 859 bool is_browser_seek) {
791 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 860 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
792 DVLOG(1) << __FUNCTION__ << " " << seek_time 861 DVLOG(1) << __FUNCTION__ << " " << seek_time
793 << (is_browser_seek ? " browser_seek" : ""); 862 << (is_browser_seek ? " BROWSER_SEEK" : "");
794 863
795 // Flush decoders before requesting demuxer. 864 // Flush decoders before requesting demuxer.
796 audio_decoder_->Flush(); 865 audio_decoder_->Flush();
797 video_decoder_->Flush(); 866 video_decoder_->Flush();
798 867
799 // Save active seek data. Logically it is attached to STATE_WAITING_FOR_SEEK. 868 // Save active seek data. Logically it is attached to STATE_WAITING_FOR_SEEK.
800 seek_info_.reset(new SeekInfo(seek_time, is_browser_seek)); 869 seek_info_.reset(new SeekInfo(seek_time, is_browser_seek));
801 870
802 demuxer_->RequestDemuxerSeek(seek_time, is_browser_seek); 871 demuxer_->RequestDemuxerSeek(seek_time, is_browser_seek);
803 } 872 }
(...skipping 10 matching lines...) Expand all
814 883
815 // At this point decoder threads should not be running 884 // At this point decoder threads should not be running
816 if (interpolator_.interpolating()) 885 if (interpolator_.interpolating())
817 interpolator_.StopInterpolating(); 886 interpolator_.StopInterpolating();
818 } 887 }
819 888
820 void MediaCodecPlayer::CreateDecoders() { 889 void MediaCodecPlayer::CreateDecoders() {
821 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 890 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
822 DVLOG(1) << __FUNCTION__; 891 DVLOG(1) << __FUNCTION__;
823 892
824 error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); 893 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_);
825 894
826 audio_decoder_.reset(new MediaCodecAudioDecoder( 895 audio_decoder_.reset(new MediaCodecAudioDecoder(
827 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 896 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
828 media_weak_this_, DemuxerStream::AUDIO), 897 media_weak_this_, DemuxerStream::AUDIO),
829 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 898 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
830 DemuxerStream::AUDIO), 899 DemuxerStream::AUDIO),
831 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), error_cb_, 900 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_),
901 internal_error_cb_,
832 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 902 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
833 DemuxerStream::AUDIO))); 903 DemuxerStream::AUDIO)));
834 904
835 video_decoder_.reset(new MediaCodecVideoDecoder( 905 video_decoder_.reset(new MediaCodecVideoDecoder(
836 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 906 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
837 media_weak_this_, DemuxerStream::VIDEO), 907 media_weak_this_, DemuxerStream::VIDEO),
838 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 908 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
839 DemuxerStream::VIDEO), 909 DemuxerStream::VIDEO),
840 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), error_cb_, 910 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_),
911 internal_error_cb_,
841 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 912 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
842 DemuxerStream::VIDEO), 913 DemuxerStream::VIDEO),
843 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), 914 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_),
844 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); 915 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_)));
845 } 916 }
846 917
847 bool MediaCodecPlayer::AudioFinished() { 918 bool MediaCodecPlayer::AudioFinished() {
848 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); 919 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream();
849 } 920 }
850 921
(...skipping 23 matching lines...) Expand all
874 RETURN_STRING(STATE_WAITING_FOR_SURFACE); 945 RETURN_STRING(STATE_WAITING_FOR_SURFACE);
875 RETURN_STRING(STATE_WAITING_FOR_SEEK); 946 RETURN_STRING(STATE_WAITING_FOR_SEEK);
876 RETURN_STRING(STATE_ERROR); 947 RETURN_STRING(STATE_ERROR);
877 } 948 }
878 return nullptr; // crash early 949 return nullptr; // crash early
879 } 950 }
880 951
881 #undef RETURN_STRING 952 #undef RETURN_STRING
882 953
883 } // namespace media 954 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698