OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 DVLOG(1) << __FUNCTION__ << ": stopping and restarting"; | |
151 // Stop decoders as quickly as possible. | |
152 StopDecoders(); // synchronous stop | |
qinmin
2015/07/22 17:30:33
we only need to do this if video is available.
Tima Vaisburd
2015/07/23 00:37:49
I added checks in both remove and replace sections
| |
153 | |
154 // Prefetch or wait for initial configuration. | |
155 if (HasAudio() || HasVideo()) { | |
156 SetState(STATE_PREFETCHING); | |
157 StartPrefetchDecoders(); | |
158 } else { | |
159 SetState(STATE_WAITING_FOR_CONFIG); | |
160 } | |
161 break; | |
162 | |
163 default: | |
164 break; // ignore | |
165 } | |
166 } else { | |
167 // Replace video surface. | |
168 switch (state_) { | |
169 case STATE_WAITING_FOR_SURFACE: | |
170 SetState(STATE_PLAYING); | |
171 StartPlaybackOrBrowserSeek(); | |
172 break; | |
173 | |
174 case STATE_PLAYING: | |
175 DVLOG(1) << __FUNCTION__ << ": requesting to stop and restart"; | |
176 SetState(STATE_STOPPING); | |
177 RequestToStopDecoders(); | |
178 SetPendingStart(true); | |
179 break; | |
180 | |
181 default: | |
182 break; // ignore | |
183 } | |
143 } | 184 } |
144 } | 185 } |
145 | 186 |
146 void MediaCodecPlayer::Start() { | 187 void MediaCodecPlayer::Start() { |
147 RUN_ON_MEDIA_THREAD(Start); | 188 RUN_ON_MEDIA_THREAD(Start); |
148 | 189 |
149 DVLOG(1) << __FUNCTION__; | 190 DVLOG(1) << __FUNCTION__; |
150 | 191 |
151 switch (state_) { | 192 switch (state_) { |
152 case STATE_PAUSED: | 193 case STATE_PAUSED: |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 << " ignoring"; | 505 << " ignoring"; |
465 return; // Ignore | 506 return; // Ignore |
466 } | 507 } |
467 | 508 |
468 DVLOG(1) << __FUNCTION__; | 509 DVLOG(1) << __FUNCTION__; |
469 | 510 |
470 if (!HasAudio() && !HasVideo()) { | 511 if (!HasAudio() && !HasVideo()) { |
471 // No configuration at all after prefetching. | 512 // No configuration at all after prefetching. |
472 // This is an error, initial configuration is expected | 513 // This is an error, initial configuration is expected |
473 // before the first data chunk. | 514 // before the first data chunk. |
474 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); | 515 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); |
475 return; | 516 return; |
476 } | 517 } |
477 | 518 |
478 if (HasVideo() && !HasPendingSurface()) { | 519 if (HasVideo() && !video_decoder_->HasVideoSurface()) { |
479 SetState(STATE_WAITING_FOR_SURFACE); | 520 SetState(STATE_WAITING_FOR_SURFACE); |
480 return; | 521 return; |
481 } | 522 } |
482 | 523 |
483 SetState(STATE_PLAYING); | 524 SetState(STATE_PLAYING); |
484 StartPlaybackDecoders(); | 525 StartPlaybackOrBrowserSeek(); |
485 } | 526 } |
486 | 527 |
487 void MediaCodecPlayer::OnStopDone() { | 528 void MediaCodecPlayer::OnStopDone() { |
488 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 529 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
489 DVLOG(1) << __FUNCTION__; | 530 DVLOG(1) << __FUNCTION__; |
490 | 531 |
491 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) | 532 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) |
492 return; // Wait until other stream is stopped | 533 return; // Wait until other stream is stopped |
493 | 534 |
494 // At this point decoder threads should not be running | 535 // At this point decoder threads should not be running |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
533 } | 574 } |
534 | 575 |
535 void MediaCodecPlayer::OnError() { | 576 void MediaCodecPlayer::OnError() { |
536 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 577 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
537 DVLOG(1) << __FUNCTION__; | 578 DVLOG(1) << __FUNCTION__; |
538 | 579 |
539 // STATE_ERROR blocks all events | 580 // STATE_ERROR blocks all events |
540 SetState(STATE_ERROR); | 581 SetState(STATE_ERROR); |
541 | 582 |
542 ReleaseDecoderResources(); | 583 ReleaseDecoderResources(); |
584 | |
585 ui_task_runner_->PostTask(FROM_HERE, | |
586 base::Bind(error_cb_, MEDIA_ERROR_DECODE)); | |
543 } | 587 } |
544 | 588 |
545 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) { | 589 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) { |
546 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 590 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
547 DVLOG(1) << __FUNCTION__ << " stream type:" << type; | 591 DVLOG(1) << __FUNCTION__ << " stream type:" << type; |
548 | 592 |
549 if (state_ != STATE_PLAYING) | 593 if (state_ != STATE_PLAYING) |
550 return; // Ignore | 594 return; // Ignore |
551 | 595 |
552 SetState(STATE_STOPPING); | 596 SetState(STATE_STOPPING); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 | 643 |
600 // State machine operations, called on Media thread | 644 // State machine operations, called on Media thread |
601 | 645 |
602 void MediaCodecPlayer::SetState(PlayerState new_state) { | 646 void MediaCodecPlayer::SetState(PlayerState new_state) { |
603 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 647 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
604 | 648 |
605 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); | 649 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); |
606 state_ = new_state; | 650 state_ = new_state; |
607 } | 651 } |
608 | 652 |
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) { | 653 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { |
621 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 654 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
622 DVLOG(1) << __FUNCTION__ << ": " << need_to_start; | 655 DVLOG(1) << __FUNCTION__ << ": " << need_to_start; |
623 pending_start_ = need_to_start; | 656 pending_start_ = need_to_start; |
624 } | 657 } |
625 | 658 |
626 bool MediaCodecPlayer::HasPendingStart() { | 659 bool MediaCodecPlayer::HasPendingStart() { |
627 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 660 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
628 return pending_start_; | 661 return pending_start_; |
629 } | 662 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
693 base::Closure prefetch_cb = base::BarrierClosure( | 726 base::Closure prefetch_cb = base::BarrierClosure( |
694 count, base::Bind(&MediaCodecPlayer::OnPrefetchDone, media_weak_this_)); | 727 count, base::Bind(&MediaCodecPlayer::OnPrefetchDone, media_weak_this_)); |
695 | 728 |
696 if (do_audio) | 729 if (do_audio) |
697 audio_decoder_->Prefetch(prefetch_cb); | 730 audio_decoder_->Prefetch(prefetch_cb); |
698 | 731 |
699 if (do_video) | 732 if (do_video) |
700 video_decoder_->Prefetch(prefetch_cb); | 733 video_decoder_->Prefetch(prefetch_cb); |
701 } | 734 } |
702 | 735 |
703 void MediaCodecPlayer::StartPlaybackDecoders() { | 736 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() { |
704 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 737 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
705 DVLOG(1) << __FUNCTION__; | 738 DVLOG(1) << __FUNCTION__; |
706 | 739 |
707 // Configure all streams before the start since | 740 // TODO(timav): consider replacing this method with posting a |
708 // we may discover that browser seek is required. | 741 // browser seek task (i.e. generate an event) from StartPlaybackDecoders(). |
742 | |
743 StartStatus status = StartPlaybackDecoders(); | |
744 | |
745 switch (status) { | |
746 case START_BROWSER_SEEK_REQUIRED: | |
747 // Browser seek | |
748 SetState(STATE_WAITING_FOR_SEEK); | |
749 SetPendingStart(true); | |
750 StopDecoders(); | |
751 RequestDemuxerSeek(GetInterpolatedTime(), true); | |
752 break; | |
753 case START_FAILED: | |
754 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); | |
755 break; | |
756 case START_OK: | |
757 break; | |
758 } | |
759 } | |
760 | |
761 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() { | |
762 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | |
763 DVLOG(1) << __FUNCTION__; | |
709 | 764 |
710 bool do_audio = !AudioFinished(); | 765 bool do_audio = !AudioFinished(); |
711 bool do_video = !VideoFinished(); | 766 bool do_video = !VideoFinished(); |
712 | 767 |
713 // If there is nothing to play, the state machine should determine | 768 // 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. | 769 // prefetch state and never call this method. |
715 DCHECK(do_audio || do_video); | 770 DCHECK(do_audio || do_video); |
716 | 771 |
772 // Configure all streams before the start since we may discover that browser | |
773 // seek is required. Start with video: if browser seek is required it would | |
774 // not make sense to configure audio. | |
775 | |
776 if (do_video) { | |
777 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure(); | |
778 switch (status) { | |
779 case MediaCodecDecoder::CONFIG_OK: | |
780 break; | |
781 case MediaCodecDecoder::CONFIG_KEY_FRAME_REQUIRED: | |
782 // TODO(timav): post a task or return the status? | |
783 return START_BROWSER_SEEK_REQUIRED; | |
784 case MediaCodecDecoder::CONFIG_FAILURE: | |
785 return START_FAILED; | |
786 } | |
787 } | |
788 | |
717 if (do_audio) { | 789 if (do_audio) { |
718 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); | 790 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); |
719 if (status != MediaCodecDecoder::CONFIG_OK) { | 791 if (status != MediaCodecDecoder::CONFIG_OK) { |
720 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); | 792 return START_FAILED; |
721 return; | |
722 } | 793 } |
723 } | 794 } |
724 | 795 |
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. | 796 // At this point decoder threads should not be running. |
734 if (!interpolator_.interpolating()) | 797 if (!interpolator_.interpolating()) |
735 interpolator_.StartInterpolating(); | 798 interpolator_.StartInterpolating(); |
736 | 799 |
737 base::TimeDelta current_time = GetInterpolatedTime(); | 800 base::TimeDelta current_time = GetInterpolatedTime(); |
738 | 801 |
739 if (do_audio) { | 802 if (do_audio) { |
740 if (!audio_decoder_->Start(current_time)) { | 803 if (!audio_decoder_->Start(current_time)) { |
741 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); | 804 return START_FAILED; |
742 return; | |
743 } | 805 } |
744 | 806 |
745 // Attach listener on UI thread | 807 // Attach listener on UI thread |
746 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_); | 808 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_); |
747 } | 809 } |
748 | 810 |
749 if (do_video) { | 811 if (do_video) { |
750 if (!video_decoder_->Start(current_time)) { | 812 if (!video_decoder_->Start(current_time)) { |
751 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); | 813 return START_FAILED; |
752 return; | |
753 } | 814 } |
754 } | 815 } |
816 | |
817 return START_OK; | |
755 } | 818 } |
756 | 819 |
757 void MediaCodecPlayer::StopDecoders() { | 820 void MediaCodecPlayer::StopDecoders() { |
758 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 821 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
759 DVLOG(1) << __FUNCTION__; | 822 DVLOG(1) << __FUNCTION__; |
760 | 823 |
824 video_decoder_->SyncStop(); | |
761 audio_decoder_->SyncStop(); | 825 audio_decoder_->SyncStop(); |
762 video_decoder_->SyncStop(); | |
763 } | 826 } |
764 | 827 |
765 void MediaCodecPlayer::RequestToStopDecoders() { | 828 void MediaCodecPlayer::RequestToStopDecoders() { |
766 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 829 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
767 DVLOG(1) << __FUNCTION__; | 830 DVLOG(1) << __FUNCTION__; |
768 | 831 |
769 bool do_audio = false; | 832 bool do_audio = false; |
770 bool do_video = false; | 833 bool do_video = false; |
771 | 834 |
772 if (audio_decoder_->IsPrefetchingOrPlaying()) | 835 if (audio_decoder_->IsPrefetchingOrPlaying()) |
(...skipping 10 matching lines...) Expand all Loading... | |
783 if (do_audio) | 846 if (do_audio) |
784 audio_decoder_->RequestToStop(); | 847 audio_decoder_->RequestToStop(); |
785 if (do_video) | 848 if (do_video) |
786 video_decoder_->RequestToStop(); | 849 video_decoder_->RequestToStop(); |
787 } | 850 } |
788 | 851 |
789 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, | 852 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, |
790 bool is_browser_seek) { | 853 bool is_browser_seek) { |
791 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 854 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
792 DVLOG(1) << __FUNCTION__ << " " << seek_time | 855 DVLOG(1) << __FUNCTION__ << " " << seek_time |
793 << (is_browser_seek ? " browser_seek" : ""); | 856 << (is_browser_seek ? " BROWSER_SEEK" : ""); |
794 | 857 |
795 // Flush decoders before requesting demuxer. | 858 // Flush decoders before requesting demuxer. |
796 audio_decoder_->Flush(); | 859 audio_decoder_->Flush(); |
797 video_decoder_->Flush(); | 860 video_decoder_->Flush(); |
798 | 861 |
799 // Save active seek data. Logically it is attached to STATE_WAITING_FOR_SEEK. | 862 // Save active seek data. Logically it is attached to STATE_WAITING_FOR_SEEK. |
800 seek_info_.reset(new SeekInfo(seek_time, is_browser_seek)); | 863 seek_info_.reset(new SeekInfo(seek_time, is_browser_seek)); |
801 | 864 |
802 demuxer_->RequestDemuxerSeek(seek_time, is_browser_seek); | 865 demuxer_->RequestDemuxerSeek(seek_time, is_browser_seek); |
803 } | 866 } |
(...skipping 10 matching lines...) Expand all Loading... | |
814 | 877 |
815 // At this point decoder threads should not be running | 878 // At this point decoder threads should not be running |
816 if (interpolator_.interpolating()) | 879 if (interpolator_.interpolating()) |
817 interpolator_.StopInterpolating(); | 880 interpolator_.StopInterpolating(); |
818 } | 881 } |
819 | 882 |
820 void MediaCodecPlayer::CreateDecoders() { | 883 void MediaCodecPlayer::CreateDecoders() { |
821 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 884 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
822 DVLOG(1) << __FUNCTION__; | 885 DVLOG(1) << __FUNCTION__; |
823 | 886 |
824 error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); | 887 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); |
825 | 888 |
826 audio_decoder_.reset(new MediaCodecAudioDecoder( | 889 audio_decoder_.reset(new MediaCodecAudioDecoder( |
827 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 890 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
828 media_weak_this_, DemuxerStream::AUDIO), | 891 media_weak_this_, DemuxerStream::AUDIO), |
829 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 892 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
830 DemuxerStream::AUDIO), | 893 DemuxerStream::AUDIO), |
831 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), error_cb_, | 894 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), |
895 internal_error_cb_, | |
832 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 896 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
833 DemuxerStream::AUDIO))); | 897 DemuxerStream::AUDIO))); |
834 | 898 |
835 video_decoder_.reset(new MediaCodecVideoDecoder( | 899 video_decoder_.reset(new MediaCodecVideoDecoder( |
836 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 900 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
837 media_weak_this_, DemuxerStream::VIDEO), | 901 media_weak_this_, DemuxerStream::VIDEO), |
838 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 902 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
839 DemuxerStream::VIDEO), | 903 DemuxerStream::VIDEO), |
840 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), error_cb_, | 904 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), |
905 internal_error_cb_, | |
841 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 906 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
842 DemuxerStream::VIDEO), | 907 DemuxerStream::VIDEO), |
843 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), | 908 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), |
844 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); | 909 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); |
845 } | 910 } |
846 | 911 |
847 bool MediaCodecPlayer::AudioFinished() { | 912 bool MediaCodecPlayer::AudioFinished() { |
848 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); | 913 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); |
849 } | 914 } |
850 | 915 |
(...skipping 23 matching lines...) Expand all Loading... | |
874 RETURN_STRING(STATE_WAITING_FOR_SURFACE); | 939 RETURN_STRING(STATE_WAITING_FOR_SURFACE); |
875 RETURN_STRING(STATE_WAITING_FOR_SEEK); | 940 RETURN_STRING(STATE_WAITING_FOR_SEEK); |
876 RETURN_STRING(STATE_ERROR); | 941 RETURN_STRING(STATE_ERROR); |
877 } | 942 } |
878 return nullptr; // crash early | 943 return nullptr; // crash early |
879 } | 944 } |
880 | 945 |
881 #undef RETURN_STRING | 946 #undef RETURN_STRING |
882 | 947 |
883 } // namespace media | 948 } // namespace media |
OLD | NEW |