Chromium Code Reviews| 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 |