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

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: Fixed SeekTo() followed by Release() and added uunit tests for this case Created 5 years, 4 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 NOTREACHED(); 286 NOTREACHED();
240 break; 287 break;
241 } 288 }
242 } 289 }
243 290
244 void MediaCodecPlayer::Release() { 291 void MediaCodecPlayer::Release() {
245 RUN_ON_MEDIA_THREAD(Release); 292 RUN_ON_MEDIA_THREAD(Release);
246 293
247 DVLOG(1) << __FUNCTION__; 294 DVLOG(1) << __FUNCTION__;
248 295
249 SetState(STATE_PAUSED); 296 // Stop decoding threads and delete MediaCodecs, but keep IPC between browser
Tima Vaisburd 2015/07/28 22:56:44 Changed this Release().
297 // and renderer processes going. Seek should work across and after Release().
298
250 ReleaseDecoderResources(); 299 ReleaseDecoderResources();
300
301 SetPendingStart(false);
302
303 if (state_ != STATE_WAITING_FOR_SEEK)
304 SetState(STATE_PAUSED);
305
306 base::TimeDelta pending_seek_time = GetPendingSeek();
307 if (pending_seek_time != kNoTimestamp()) {
308 SetPendingSeek(kNoTimestamp());
309 SetState(STATE_WAITING_FOR_SEEK);
310 RequestDemuxerSeek(pending_seek_time);
311 }
251 } 312 }
252 313
253 void MediaCodecPlayer::SetVolume(double volume) { 314 void MediaCodecPlayer::SetVolume(double volume) {
254 RUN_ON_MEDIA_THREAD(SetVolume, volume); 315 RUN_ON_MEDIA_THREAD(SetVolume, volume);
255 316
256 DVLOG(1) << __FUNCTION__ << " " << volume; 317 DVLOG(1) << __FUNCTION__ << " " << volume;
257 audio_decoder_->SetVolume(volume); 318 audio_decoder_->SetVolume(volume);
258 } 319 }
259 320
260 int MediaCodecPlayer::GetVideoWidth() { 321 int MediaCodecPlayer::GetVideoWidth() {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 if (data.type == DemuxerStream::VIDEO) 408 if (data.type == DemuxerStream::VIDEO)
348 video_decoder_->OnDemuxerDataAvailable(data); 409 video_decoder_->OnDemuxerDataAvailable(data);
349 } 410 }
350 411
351 void MediaCodecPlayer::OnDemuxerSeekDone( 412 void MediaCodecPlayer::OnDemuxerSeekDone(
352 base::TimeDelta actual_browser_seek_time) { 413 base::TimeDelta actual_browser_seek_time) {
353 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 414 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
354 415
355 DVLOG(1) << __FUNCTION__ << " actual_time:" << actual_browser_seek_time; 416 DVLOG(1) << __FUNCTION__ << " actual_time:" << actual_browser_seek_time;
356 417
357 if (state_ != STATE_WAITING_FOR_SEEK) 418 DCHECK(state_ == STATE_WAITING_FOR_SEEK);
Tima Vaisburd 2015/07/28 22:56:44 Added this DCHECK instead of ignoring the signal i
358 return; // ignore
359
360 DCHECK(seek_info_.get()); 419 DCHECK(seek_info_.get());
361 DCHECK(seek_info_->seek_time != kNoTimestamp()); 420 DCHECK(seek_info_->seek_time != kNoTimestamp());
362 421
363 // A browser seek must not jump into the past. Ideally, it seeks to the 422 // A browser seek must not jump into the past. Ideally, it seeks to the
364 // requested time, but it might jump into the future. 423 // requested time, but it might jump into the future.
365 DCHECK(!seek_info_->is_browser_seek || 424 DCHECK(!seek_info_->is_browser_seek ||
366 seek_info_->seek_time <= actual_browser_seek_time); 425 seek_info_->seek_time <= actual_browser_seek_time);
367 426
368 // Restrict the current time to be equal to seek_time 427 // Restrict the current time to be equal to seek_time
369 // for the next StartPlaybackDecoders() call. 428 // for the next StartPlaybackDecoders() call.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 if (state_ != STATE_PREFETCHING) { 520 if (state_ != STATE_PREFETCHING) {
462 DVLOG(1) << __FUNCTION__ << " wrong state " << AsString(state_) 521 DVLOG(1) << __FUNCTION__ << " wrong state " << AsString(state_)
463 << " ignoring"; 522 << " ignoring";
464 return; // Ignore 523 return; // Ignore
465 } 524 }
466 525
467 DVLOG(1) << __FUNCTION__; 526 DVLOG(1) << __FUNCTION__;
468 527
469 if (!HasAudio() && !HasVideo()) { 528 if (!HasAudio() && !HasVideo()) {
470 // No configuration at all after prefetching. 529 // No configuration at all after prefetching.
471 // This is an error, initial configuration is expected 530 // This is an error, initial configuration is expected
wolenetz 2015/07/29 22:37:03 nit: we might want to DCHECK that internal_error_c
Tima Vaisburd 2015/07/30 20:28:35 Done.
472 // before the first data chunk. 531 // before the first data chunk.
473 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 532 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
474 return; 533 return;
475 } 534 }
476 535
477 if (HasVideo() && !HasPendingSurface()) { 536 if (HasVideo() && !video_decoder_->HasVideoSurface()) {
478 SetState(STATE_WAITING_FOR_SURFACE); 537 SetState(STATE_WAITING_FOR_SURFACE);
479 return; 538 return;
480 } 539 }
481 540
482 SetState(STATE_PLAYING); 541 SetState(STATE_PLAYING);
483 StartPlaybackDecoders(); 542 StartPlaybackOrBrowserSeek();
484 } 543 }
485 544
486 void MediaCodecPlayer::OnStopDone() { 545 void MediaCodecPlayer::OnStopDone() {
487 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 546 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
488 DVLOG(1) << __FUNCTION__; 547 DVLOG(1) << __FUNCTION__;
489 548
490 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) 549 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped()))
491 return; // Wait until other stream is stopped 550 return; // Wait until other stream is stopped
492 551
493 // At this point decoder threads should not be running 552 // At this point decoder threads should not be running
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 } 591 }
533 592
534 void MediaCodecPlayer::OnError() { 593 void MediaCodecPlayer::OnError() {
535 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 594 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
536 DVLOG(1) << __FUNCTION__; 595 DVLOG(1) << __FUNCTION__;
537 596
538 // STATE_ERROR blocks all events 597 // STATE_ERROR blocks all events
539 SetState(STATE_ERROR); 598 SetState(STATE_ERROR);
540 599
541 ReleaseDecoderResources(); 600 ReleaseDecoderResources();
601
602 ui_task_runner_->PostTask(FROM_HERE,
603 base::Bind(error_cb_, MEDIA_ERROR_DECODE));
542 } 604 }
543 605
544 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) { 606 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) {
545 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 607 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
546 DVLOG(1) << __FUNCTION__ << " stream type:" << type; 608 DVLOG(1) << __FUNCTION__ << " stream type:" << type;
547 609
548 if (state_ != STATE_PLAYING) 610 if (state_ != STATE_PLAYING)
549 return; // Ignore 611 return; // Ignore
550 612
551 SetState(STATE_STOPPING); 613 SetState(STATE_STOPPING);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 660
599 // State machine operations, called on Media thread 661 // State machine operations, called on Media thread
600 662
601 void MediaCodecPlayer::SetState(PlayerState new_state) { 663 void MediaCodecPlayer::SetState(PlayerState new_state) {
602 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 664 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
603 665
604 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state); 666 DVLOG(1) << "SetState:" << AsString(state_) << " -> " << AsString(new_state);
605 state_ = new_state; 667 state_ = new_state;
606 } 668 }
607 669
608 void MediaCodecPlayer::SetPendingSurface(gfx::ScopedJavaSurface surface) {
609 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
610 DVLOG(1) << __FUNCTION__;
611
612 video_decoder_->SetPendingSurface(surface.Pass());
613 }
614
615 bool MediaCodecPlayer::HasPendingSurface() const {
616 return video_decoder_->HasPendingSurface();
617 }
618
619 void MediaCodecPlayer::SetPendingStart(bool need_to_start) { 670 void MediaCodecPlayer::SetPendingStart(bool need_to_start) {
620 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 671 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
621 DVLOG(1) << __FUNCTION__ << ": " << need_to_start; 672 DVLOG(1) << __FUNCTION__ << ": " << need_to_start;
622 pending_start_ = need_to_start; 673 pending_start_ = need_to_start;
623 } 674 }
624 675
625 bool MediaCodecPlayer::HasPendingStart() const { 676 bool MediaCodecPlayer::HasPendingStart() const {
626 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 677 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
627 return pending_start_; 678 return pending_start_;
628 } 679 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 base::Closure prefetch_cb = base::BarrierClosure( 743 base::Closure prefetch_cb = base::BarrierClosure(
693 count, base::Bind(&MediaCodecPlayer::OnPrefetchDone, media_weak_this_)); 744 count, base::Bind(&MediaCodecPlayer::OnPrefetchDone, media_weak_this_));
694 745
695 if (do_audio) 746 if (do_audio)
696 audio_decoder_->Prefetch(prefetch_cb); 747 audio_decoder_->Prefetch(prefetch_cb);
697 748
698 if (do_video) 749 if (do_video)
699 video_decoder_->Prefetch(prefetch_cb); 750 video_decoder_->Prefetch(prefetch_cb);
700 } 751 }
701 752
702 void MediaCodecPlayer::StartPlaybackDecoders() { 753 void MediaCodecPlayer::StartPlaybackOrBrowserSeek() {
703 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 754 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
704 DVLOG(1) << __FUNCTION__; 755 DVLOG(1) << __FUNCTION__;
705 756
706 // Configure all streams before the start since 757 // TODO(timav): consider replacing this method with posting a
707 // we may discover that browser seek is required. 758 // browser seek task (i.e. generate an event) from StartPlaybackDecoders().
759
760 StartStatus status = StartPlaybackDecoders();
761
762 switch (status) {
763 case START_BROWSER_SEEK_REQUIRED:
764 // Browser seek
765 SetState(STATE_WAITING_FOR_SEEK);
766 SetPendingStart(true);
767 StopDecoders();
768 RequestDemuxerSeek(GetInterpolatedTime(), true);
769 break;
770 case START_FAILED:
771 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_);
772 break;
773 case START_OK:
774 break;
775 }
776 }
777
778 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartPlaybackDecoders() {
779 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
780 DVLOG(1) << __FUNCTION__;
708 781
709 bool do_audio = !AudioFinished(); 782 bool do_audio = !AudioFinished();
710 bool do_video = !VideoFinished(); 783 bool do_video = !VideoFinished();
711 784
712 // If there is nothing to play, the state machine should determine 785 // If there is nothing to play, the state machine should determine this at the
713 // this at the prefetch state and never call this method. 786 // prefetch state and never call this method.
714 DCHECK(do_audio || do_video); 787 DCHECK(do_audio || do_video);
715 788
789 // Configure all streams before the start since we may discover that browser
790 // seek is required. Start with video: if browser seek is required it would
791 // not make sense to configure audio.
792
793 if (do_video) {
794 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure();
795 switch (status) {
796 case MediaCodecDecoder::CONFIG_OK:
797 break;
798 case MediaCodecDecoder::CONFIG_KEY_FRAME_REQUIRED:
799 // TODO(timav): post a task or return the status?
800 return START_BROWSER_SEEK_REQUIRED;
801 case MediaCodecDecoder::CONFIG_FAILURE:
802 return START_FAILED;
803 }
804 }
805
716 if (do_audio) { 806 if (do_audio) {
717 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure(); 807 MediaCodecDecoder::ConfigStatus status = audio_decoder_->Configure();
718 if (status != MediaCodecDecoder::CONFIG_OK) { 808 if (status != MediaCodecDecoder::CONFIG_OK) {
719 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 809 return START_FAILED;
720 return;
721 } 810 }
722 } 811 }
723 812
724 if (do_video) {
725 MediaCodecDecoder::ConfigStatus status = video_decoder_->Configure();
726 if (status != MediaCodecDecoder::CONFIG_OK) {
727 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_);
728 return;
729 }
730 }
731
732 // At this point decoder threads should not be running. 813 // At this point decoder threads should not be running.
733 if (!interpolator_.interpolating()) 814 if (!interpolator_.interpolating())
734 interpolator_.StartInterpolating(); 815 interpolator_.StartInterpolating();
735 816
736 base::TimeDelta current_time = GetInterpolatedTime(); 817 base::TimeDelta current_time = GetInterpolatedTime();
737 818
738 if (do_audio) { 819 if (do_audio) {
739 if (!audio_decoder_->Start(current_time)) { 820 if (!audio_decoder_->Start(current_time)) {
740 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 821 return START_FAILED;
741 return;
742 } 822 }
743 823
744 // Attach listener on UI thread 824 // Attach listener on UI thread
745 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_); 825 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_);
746 } 826 }
747 827
748 if (do_video) { 828 if (do_video) {
749 if (!video_decoder_->Start(current_time)) { 829 if (!video_decoder_->Start(current_time)) {
750 GetMediaTaskRunner()->PostTask(FROM_HERE, error_cb_); 830 return START_FAILED;
751 return;
752 } 831 }
753 } 832 }
833
834 return START_OK;
754 } 835 }
755 836
756 void MediaCodecPlayer::StopDecoders() { 837 void MediaCodecPlayer::StopDecoders() {
757 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 838 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
758 DVLOG(1) << __FUNCTION__; 839 DVLOG(1) << __FUNCTION__;
759 840
841 video_decoder_->SyncStop();
760 audio_decoder_->SyncStop(); 842 audio_decoder_->SyncStop();
761 video_decoder_->SyncStop();
762 } 843 }
763 844
764 void MediaCodecPlayer::RequestToStopDecoders() { 845 void MediaCodecPlayer::RequestToStopDecoders() {
765 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 846 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
766 DVLOG(1) << __FUNCTION__; 847 DVLOG(1) << __FUNCTION__;
767 848
768 bool do_audio = false; 849 bool do_audio = false;
769 bool do_video = false; 850 bool do_video = false;
770 851
771 if (audio_decoder_->IsPrefetchingOrPlaying()) 852 if (audio_decoder_->IsPrefetchingOrPlaying())
(...skipping 10 matching lines...) Expand all
782 if (do_audio) 863 if (do_audio)
783 audio_decoder_->RequestToStop(); 864 audio_decoder_->RequestToStop();
784 if (do_video) 865 if (do_video)
785 video_decoder_->RequestToStop(); 866 video_decoder_->RequestToStop();
786 } 867 }
787 868
788 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, 869 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time,
789 bool is_browser_seek) { 870 bool is_browser_seek) {
790 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 871 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
791 DVLOG(1) << __FUNCTION__ << " " << seek_time 872 DVLOG(1) << __FUNCTION__ << " " << seek_time
792 << (is_browser_seek ? " browser_seek" : ""); 873 << (is_browser_seek ? " BROWSER_SEEK" : "");
793 874
794 // Flush decoders before requesting demuxer. 875 // Flush decoders before requesting demuxer.
795 audio_decoder_->Flush(); 876 audio_decoder_->Flush();
796 video_decoder_->Flush(); 877 video_decoder_->Flush();
797 878
798 // Save active seek data. Logically it is attached to STATE_WAITING_FOR_SEEK. 879 // Save active seek data. Logically it is attached to STATE_WAITING_FOR_SEEK.
799 DCHECK(state_ == STATE_WAITING_FOR_SEEK); 880 DCHECK(state_ == STATE_WAITING_FOR_SEEK);
800 seek_info_.reset(new SeekInfo(seek_time, is_browser_seek)); 881 seek_info_.reset(new SeekInfo(seek_time, is_browser_seek));
801 882
802 demuxer_->RequestDemuxerSeek(seek_time, is_browser_seek); 883 demuxer_->RequestDemuxerSeek(seek_time, is_browser_seek);
(...skipping 11 matching lines...) Expand all
814 895
815 // At this point decoder threads should not be running 896 // At this point decoder threads should not be running
816 if (interpolator_.interpolating()) 897 if (interpolator_.interpolating())
817 interpolator_.StopInterpolating(); 898 interpolator_.StopInterpolating();
818 } 899 }
819 900
820 void MediaCodecPlayer::CreateDecoders() { 901 void MediaCodecPlayer::CreateDecoders() {
821 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 902 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
822 DVLOG(1) << __FUNCTION__; 903 DVLOG(1) << __FUNCTION__;
823 904
824 error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); 905 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_);
825 906
826 audio_decoder_.reset(new MediaCodecAudioDecoder( 907 audio_decoder_.reset(new MediaCodecAudioDecoder(
827 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 908 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
828 media_weak_this_, DemuxerStream::AUDIO), 909 media_weak_this_, DemuxerStream::AUDIO),
829 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 910 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
830 DemuxerStream::AUDIO), 911 DemuxerStream::AUDIO),
831 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), error_cb_, 912 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_),
913 internal_error_cb_,
832 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 914 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
833 DemuxerStream::AUDIO))); 915 DemuxerStream::AUDIO)));
834 916
835 video_decoder_.reset(new MediaCodecVideoDecoder( 917 video_decoder_.reset(new MediaCodecVideoDecoder(
836 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 918 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
837 media_weak_this_, DemuxerStream::VIDEO), 919 media_weak_this_, DemuxerStream::VIDEO),
838 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 920 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
839 DemuxerStream::VIDEO), 921 DemuxerStream::VIDEO),
840 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), error_cb_, 922 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_),
923 internal_error_cb_,
841 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 924 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
842 DemuxerStream::VIDEO), 925 DemuxerStream::VIDEO),
843 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), 926 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_),
844 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); 927 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_)));
845 } 928 }
846 929
847 bool MediaCodecPlayer::AudioFinished() const { 930 bool MediaCodecPlayer::AudioFinished() const {
848 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); 931 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream();
849 } 932 }
850 933
(...skipping 23 matching lines...) Expand all
874 RETURN_STRING(STATE_WAITING_FOR_SURFACE); 957 RETURN_STRING(STATE_WAITING_FOR_SURFACE);
875 RETURN_STRING(STATE_WAITING_FOR_SEEK); 958 RETURN_STRING(STATE_WAITING_FOR_SEEK);
876 RETURN_STRING(STATE_ERROR); 959 RETURN_STRING(STATE_ERROR);
877 } 960 }
878 return nullptr; // crash early 961 return nullptr; // crash early
879 } 962 }
880 963
881 #undef RETURN_STRING 964 #undef RETURN_STRING
882 965
883 } // namespace media 966 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698