| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <stdint.h> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 renderer_impl_( | 75 renderer_impl_( |
| 76 new RendererImpl(message_loop_.task_runner(), | 76 new RendererImpl(message_loop_.task_runner(), |
| 77 std::unique_ptr<AudioRenderer>(audio_renderer_), | 77 std::unique_ptr<AudioRenderer>(audio_renderer_), |
| 78 std::unique_ptr<VideoRenderer>(video_renderer_))), | 78 std::unique_ptr<VideoRenderer>(video_renderer_))), |
| 79 cdm_context_(new StrictMock<MockCdmContext>()), | 79 cdm_context_(new StrictMock<MockCdmContext>()), |
| 80 video_renderer_client_(nullptr), | 80 video_renderer_client_(nullptr), |
| 81 audio_renderer_client_(nullptr), | 81 audio_renderer_client_(nullptr), |
| 82 initialization_status_(PIPELINE_OK) { | 82 initialization_status_(PIPELINE_OK) { |
| 83 // CreateAudioStream() and CreateVideoStream() overrides expectations for | 83 // CreateAudioStream() and CreateVideoStream() overrides expectations for |
| 84 // expected non-NULL streams. | 84 // expected non-NULL streams. |
| 85 DemuxerStream* null_pointer = NULL; | 85 EXPECT_CALL(*demuxer_, GetAllStreams()).WillRepeatedly(Return(streams_)); |
| 86 EXPECT_CALL(*demuxer_, GetStream(_)) | |
| 87 .WillRepeatedly(Return(null_pointer)); | |
| 88 } | 86 } |
| 89 | 87 |
| 90 virtual ~RendererImplTest() { Destroy(); } | 88 virtual ~RendererImplTest() { Destroy(); } |
| 91 | 89 |
| 92 protected: | 90 protected: |
| 93 void Destroy() { | 91 void Destroy() { |
| 94 renderer_impl_.reset(); | 92 renderer_impl_.reset(); |
| 95 base::RunLoop().RunUntilIdle(); | 93 base::RunLoop().RunUntilIdle(); |
| 96 } | 94 } |
| 97 | 95 |
| 98 std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream( | 96 std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream( |
| 99 DemuxerStream::Type type) { | 97 DemuxerStream::Type type) { |
| 100 std::unique_ptr<StrictMock<MockDemuxerStream>> stream( | 98 std::unique_ptr<StrictMock<MockDemuxerStream>> stream( |
| 101 new StrictMock<MockDemuxerStream>(type)); | 99 new StrictMock<MockDemuxerStream>(type)); |
| 102 EXPECT_CALL(*stream, SetStreamStatusChangeCB(_)) | 100 EXPECT_CALL(*stream, enabled()).WillRepeatedly(Return(true)); |
| 101 EXPECT_CALL(*demuxer_, SetStreamStatusChangeCB(_)) |
| 103 .Times(testing::AnyNumber()); | 102 .Times(testing::AnyNumber()); |
| 104 return stream; | 103 return stream; |
| 105 } | 104 } |
| 106 | 105 |
| 107 // Sets up expectations to allow the audio renderer to initialize. | 106 // Sets up expectations to allow the audio renderer to initialize. |
| 108 void SetAudioRendererInitializeExpectations(PipelineStatus status) { | 107 void SetAudioRendererInitializeExpectations(PipelineStatus status) { |
| 109 EXPECT_CALL(*audio_renderer_, Initialize(audio_stream_.get(), _, _, _)) | 108 EXPECT_CALL(*audio_renderer_, Initialize(audio_stream_.get(), _, _, _)) |
| 110 .WillOnce( | 109 .WillOnce( |
| 111 DoAll(SaveArg<2>(&audio_renderer_client_), RunCallback<3>(status))); | 110 DoAll(SaveArg<2>(&audio_renderer_client_), RunCallback<3>(status))); |
| 112 } | 111 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 131 } | 130 } |
| 132 | 131 |
| 133 renderer_impl_->Initialize(demuxer_.get(), &callbacks_, | 132 renderer_impl_->Initialize(demuxer_.get(), &callbacks_, |
| 134 base::Bind(&CallbackHelper::OnInitialize, | 133 base::Bind(&CallbackHelper::OnInitialize, |
| 135 base::Unretained(&callbacks_))); | 134 base::Unretained(&callbacks_))); |
| 136 base::RunLoop().RunUntilIdle(); | 135 base::RunLoop().RunUntilIdle(); |
| 137 } | 136 } |
| 138 | 137 |
| 139 void CreateAudioStream() { | 138 void CreateAudioStream() { |
| 140 audio_stream_ = CreateStream(DemuxerStream::AUDIO); | 139 audio_stream_ = CreateStream(DemuxerStream::AUDIO); |
| 141 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO)) | 140 streams_.push_back(audio_stream_.get()); |
| 142 .WillRepeatedly(Return(audio_stream_.get())); | 141 EXPECT_CALL(*demuxer_, GetAllStreams()).WillRepeatedly(Return(streams_)); |
| 143 } | 142 } |
| 144 | 143 |
| 145 void CreateVideoStream(bool is_encrypted = false) { | 144 void CreateVideoStream(bool is_encrypted = false) { |
| 146 video_stream_ = CreateStream(DemuxerStream::VIDEO); | 145 video_stream_ = CreateStream(DemuxerStream::VIDEO); |
| 147 video_stream_->set_video_decoder_config( | 146 video_stream_->set_video_decoder_config( |
| 148 is_encrypted ? TestVideoConfig::NormalEncrypted() | 147 is_encrypted ? TestVideoConfig::NormalEncrypted() |
| 149 : TestVideoConfig::Normal()); | 148 : TestVideoConfig::Normal()); |
| 150 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::VIDEO)) | 149 streams_.push_back(video_stream_.get()); |
| 151 .WillRepeatedly(Return(video_stream_.get())); | 150 EXPECT_CALL(*demuxer_, GetAllStreams()).WillRepeatedly(Return(streams_)); |
| 152 } | 151 } |
| 153 | 152 |
| 154 void CreateEncryptedVideoStream() { CreateVideoStream(true); } | 153 void CreateEncryptedVideoStream() { CreateVideoStream(true); } |
| 155 | 154 |
| 156 void CreateAudioAndVideoStream() { | 155 void CreateAudioAndVideoStream() { |
| 157 CreateAudioStream(); | 156 CreateAudioStream(); |
| 158 CreateVideoStream(); | 157 CreateVideoStream(); |
| 159 } | 158 } |
| 160 | 159 |
| 161 void InitializeWithAudio() { | 160 void InitializeWithAudio() { |
| 162 CreateAudioStream(); | 161 CreateAudioStream(); |
| 163 SetAudioRendererInitializeExpectations(PIPELINE_OK); | 162 SetAudioRendererInitializeExpectations(PIPELINE_OK); |
| 164 // There is a potential race between HTMLMediaElement/WMPI shutdown and | 163 // There is a potential race between HTMLMediaElement/WMPI shutdown and |
| 165 // renderers being initialized which might result in MediaResource GetStream | 164 // renderers being initialized which might result in MediaResource |
| 166 // suddenly returning NULL (see crbug.com/668604). So we are going to check | 165 // GetAllStreams suddenly returning fewer streams than before or even |
| 167 // here that GetStream will be invoked exactly 3 times during RendererImpl | 166 // returning |
| 168 // initialization to help catch potential issues. Currently the GetStream is | 167 // and empty stream collection (see crbug.com/668604). So we are going to |
| 169 // invoked once directly from RendererImpl::Initialize, once indirectly from | 168 // check here that GetAllStreams will be invoked exactly 3 times during |
| 170 // RendererImpl::Initialize via HasEncryptedStream and once from | 169 // RendererImpl initialization to help catch potential issues. Currently the |
| 171 // RendererImpl::InitializeAudioRenderer. | 170 // GetAllStreams is invoked once from the RendererImpl::Initialize via |
| 172 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO)) | 171 // HasEncryptedStream, once from the RendererImpl::InitializeAudioRenderer |
| 173 .Times(2) | 172 // and once from the RendererImpl::InitializeVideoRenderer. |
| 174 .WillRepeatedly(Return(audio_stream_.get())); | 173 EXPECT_CALL(*demuxer_, GetAllStreams()) |
| 174 .Times(3) |
| 175 .WillRepeatedly(Return(streams_)); |
| 175 InitializeAndExpect(PIPELINE_OK); | 176 InitializeAndExpect(PIPELINE_OK); |
| 176 } | 177 } |
| 177 | 178 |
| 178 void InitializeWithVideo() { | 179 void InitializeWithVideo() { |
| 179 CreateVideoStream(); | 180 CreateVideoStream(); |
| 180 SetVideoRendererInitializeExpectations(PIPELINE_OK); | 181 SetVideoRendererInitializeExpectations(PIPELINE_OK); |
| 181 // There is a potential race between HTMLMediaElement/WMPI shutdown and | 182 // There is a potential race between HTMLMediaElement/WMPI shutdown and |
| 182 // renderers being initialized which might result in MediaResource GetStream | 183 // renderers being initialized which might result in MediaResource |
| 183 // suddenly returning NULL (see crbug.com/668604). So we are going to check | 184 // GetAllStreams suddenly returning fewer streams than before or even |
| 184 // here that GetStream will be invoked exactly 3 times during RendererImpl | 185 // returning |
| 185 // initialization to help catch potential issues. Currently the GetStream is | 186 // and empty stream collection (see crbug.com/668604). So we are going to |
| 186 // invoked once directly from RendererImpl::Initialize, once indirectly from | 187 // check here that GetAllStreams will be invoked exactly 3 times during |
| 187 // RendererImpl::Initialize via HasEncryptedStream and once from | 188 // RendererImpl initialization to help catch potential issues. Currently the |
| 188 // RendererImpl::InitializeVideoRenderer. | 189 // GetAllStreams is invoked once from the RendererImpl::Initialize via |
| 189 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::VIDEO)) | 190 // HasEncryptedStream, once from the RendererImpl::InitializeAudioRenderer |
| 190 .Times(2) | 191 // and once from the RendererImpl::InitializeVideoRenderer. |
| 191 .WillRepeatedly(Return(video_stream_.get())); | 192 EXPECT_CALL(*demuxer_, GetAllStreams()) |
| 193 .Times(3) |
| 194 .WillRepeatedly(Return(streams_)); |
| 192 InitializeAndExpect(PIPELINE_OK); | 195 InitializeAndExpect(PIPELINE_OK); |
| 193 } | 196 } |
| 194 | 197 |
| 195 void InitializeWithAudioAndVideo() { | 198 void InitializeWithAudioAndVideo() { |
| 196 CreateAudioAndVideoStream(); | 199 CreateAudioAndVideoStream(); |
| 197 SetAudioRendererInitializeExpectations(PIPELINE_OK); | 200 SetAudioRendererInitializeExpectations(PIPELINE_OK); |
| 198 SetVideoRendererInitializeExpectations(PIPELINE_OK); | 201 SetVideoRendererInitializeExpectations(PIPELINE_OK); |
| 199 InitializeAndExpect(PIPELINE_OK); | 202 InitializeAndExpect(PIPELINE_OK); |
| 200 } | 203 } |
| 201 | 204 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 | 295 |
| 293 std::unique_ptr<StrictMock<MockDemuxer>> demuxer_; | 296 std::unique_ptr<StrictMock<MockDemuxer>> demuxer_; |
| 294 StrictMock<MockVideoRenderer>* video_renderer_; | 297 StrictMock<MockVideoRenderer>* video_renderer_; |
| 295 StrictMock<MockAudioRenderer>* audio_renderer_; | 298 StrictMock<MockAudioRenderer>* audio_renderer_; |
| 296 std::unique_ptr<RendererImpl> renderer_impl_; | 299 std::unique_ptr<RendererImpl> renderer_impl_; |
| 297 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_; | 300 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_; |
| 298 | 301 |
| 299 StrictMock<MockTimeSource> time_source_; | 302 StrictMock<MockTimeSource> time_source_; |
| 300 std::unique_ptr<StrictMock<MockDemuxerStream>> audio_stream_; | 303 std::unique_ptr<StrictMock<MockDemuxerStream>> audio_stream_; |
| 301 std::unique_ptr<StrictMock<MockDemuxerStream>> video_stream_; | 304 std::unique_ptr<StrictMock<MockDemuxerStream>> video_stream_; |
| 305 std::vector<DemuxerStream*> streams_; |
| 302 RendererClient* video_renderer_client_; | 306 RendererClient* video_renderer_client_; |
| 303 RendererClient* audio_renderer_client_; | 307 RendererClient* audio_renderer_client_; |
| 304 VideoDecoderConfig video_decoder_config_; | 308 VideoDecoderConfig video_decoder_config_; |
| 305 PipelineStatus initialization_status_; | 309 PipelineStatus initialization_status_; |
| 306 | 310 |
| 307 private: | 311 private: |
| 308 DISALLOW_COPY_AND_ASSIGN(RendererImplTest); | 312 DISALLOW_COPY_AND_ASSIGN(RendererImplTest); |
| 309 }; | 313 }; |
| 310 | 314 |
| 311 TEST_F(RendererImplTest, Destroy_BeforeInitialize) { | 315 TEST_F(RendererImplTest, Destroy_BeforeInitialize) { |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 EXPECT_CALL(*video_renderer_, StartPlayingFrom(kStartTime)); | 748 EXPECT_CALL(*video_renderer_, StartPlayingFrom(kStartTime)); |
| 745 renderer_impl_->StartPlayingFrom(kStartTime); | 749 renderer_impl_->StartPlayingFrom(kStartTime); |
| 746 | 750 |
| 747 // Nothing else should primed on the message loop. | 751 // Nothing else should primed on the message loop. |
| 748 base::RunLoop().RunUntilIdle(); | 752 base::RunLoop().RunUntilIdle(); |
| 749 } | 753 } |
| 750 | 754 |
| 751 TEST_F(RendererImplTest, StreamStatusNotificationHandling) { | 755 TEST_F(RendererImplTest, StreamStatusNotificationHandling) { |
| 752 CreateAudioAndVideoStream(); | 756 CreateAudioAndVideoStream(); |
| 753 | 757 |
| 754 DemuxerStream::StreamStatusChangeCB audio_stream_status_change_cb; | 758 StreamStatusChangeCB stream_status_change_cb; |
| 755 DemuxerStream::StreamStatusChangeCB video_stream_status_change_cb; | 759 EXPECT_CALL(*demuxer_, SetStreamStatusChangeCB(_)) |
| 756 EXPECT_CALL(*audio_stream_, SetStreamStatusChangeCB(_)) | 760 .WillOnce(SaveArg<0>(&stream_status_change_cb)); |
| 757 .WillOnce(SaveArg<0>(&audio_stream_status_change_cb)); | |
| 758 EXPECT_CALL(*video_stream_, SetStreamStatusChangeCB(_)) | |
| 759 .WillOnce(SaveArg<0>(&video_stream_status_change_cb)); | |
| 760 SetAudioRendererInitializeExpectations(PIPELINE_OK); | 761 SetAudioRendererInitializeExpectations(PIPELINE_OK); |
| 761 SetVideoRendererInitializeExpectations(PIPELINE_OK); | 762 SetVideoRendererInitializeExpectations(PIPELINE_OK); |
| 762 InitializeAndExpect(PIPELINE_OK); | 763 InitializeAndExpect(PIPELINE_OK); |
| 763 Play(); | 764 Play(); |
| 764 | 765 |
| 765 // Verify that DemuxerStream status changes cause the corresponding | 766 // Verify that DemuxerStream status changes cause the corresponding |
| 766 // audio/video renderer to be flushed and restarted. | 767 // audio/video renderer to be flushed and restarted. |
| 767 EXPECT_CALL(time_source_, StopTicking()); | 768 EXPECT_CALL(time_source_, StopTicking()); |
| 768 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>()); | 769 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>()); |
| 769 EXPECT_CALL(*audio_renderer_, StartPlaying()) | 770 EXPECT_CALL(*audio_renderer_, StartPlaying()) |
| 770 .Times(1) | 771 .Times(1) |
| 771 .WillOnce( | 772 .WillOnce( |
| 772 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)); | 773 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)); |
| 773 audio_stream_status_change_cb.Run(false, base::TimeDelta()); | 774 stream_status_change_cb.Run(audio_stream_.get(), false, base::TimeDelta()); |
| 774 | 775 |
| 775 EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>()); | 776 EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>()); |
| 776 EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)) | 777 EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)) |
| 777 .Times(1) | 778 .Times(1) |
| 778 .WillOnce(DoAll( | 779 .WillOnce(DoAll( |
| 779 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), | 780 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), |
| 780 PostQuitWhenIdle())); | 781 PostQuitWhenIdle())); |
| 781 | 782 |
| 782 video_stream_status_change_cb.Run(false, base::TimeDelta()); | 783 stream_status_change_cb.Run(video_stream_.get(), false, base::TimeDelta()); |
| 783 base::RunLoop().Run(); | 784 base::RunLoop().Run(); |
| 784 } | 785 } |
| 785 | 786 |
| 786 // Stream status changes are handled asynchronously by the renderer and may take | 787 // Stream status changes are handled asynchronously by the renderer and may take |
| 787 // some time to process. This test verifies that all status changes are | 788 // some time to process. This test verifies that all status changes are |
| 788 // processed correctly by the renderer even if status changes of the stream | 789 // processed correctly by the renderer even if status changes of the stream |
| 789 // happen much faster than the renderer can process them. In that case the | 790 // happen much faster than the renderer can process them. In that case the |
| 790 // renderer may postpone processing status changes, but still must process all | 791 // renderer may postpone processing status changes, but still must process all |
| 791 // of them eventually. | 792 // of them eventually. |
| 792 TEST_F(RendererImplTest, PostponedStreamStatusNotificationHandling) { | 793 TEST_F(RendererImplTest, PostponedStreamStatusNotificationHandling) { |
| 793 CreateAudioAndVideoStream(); | 794 CreateAudioAndVideoStream(); |
| 794 | 795 |
| 795 DemuxerStream::StreamStatusChangeCB audio_stream_status_change_cb; | 796 StreamStatusChangeCB stream_status_change_cb; |
| 796 DemuxerStream::StreamStatusChangeCB video_stream_status_change_cb; | 797 EXPECT_CALL(*demuxer_, SetStreamStatusChangeCB(_)) |
| 797 EXPECT_CALL(*audio_stream_, SetStreamStatusChangeCB(_)) | 798 .WillOnce(SaveArg<0>(&stream_status_change_cb)); |
| 798 .WillOnce(SaveArg<0>(&audio_stream_status_change_cb)); | |
| 799 EXPECT_CALL(*video_stream_, SetStreamStatusChangeCB(_)) | |
| 800 .WillOnce(SaveArg<0>(&video_stream_status_change_cb)); | |
| 801 SetAudioRendererInitializeExpectations(PIPELINE_OK); | 799 SetAudioRendererInitializeExpectations(PIPELINE_OK); |
| 802 SetVideoRendererInitializeExpectations(PIPELINE_OK); | 800 SetVideoRendererInitializeExpectations(PIPELINE_OK); |
| 803 InitializeAndExpect(PIPELINE_OK); | 801 InitializeAndExpect(PIPELINE_OK); |
| 804 Play(); | 802 Play(); |
| 805 | 803 |
| 806 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)) | 804 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)) |
| 807 .Times(2); | 805 .Times(2); |
| 808 | 806 |
| 809 EXPECT_CALL(time_source_, StopTicking()).Times(2); | 807 EXPECT_CALL(time_source_, StopTicking()).Times(2); |
| 810 EXPECT_CALL(time_source_, StartTicking()).Times(2); | 808 EXPECT_CALL(time_source_, StartTicking()).Times(2); |
| 811 EXPECT_CALL(*audio_renderer_, Flush(_)) | 809 EXPECT_CALL(*audio_renderer_, Flush(_)) |
| 812 .Times(2) | 810 .Times(2) |
| 813 .WillRepeatedly(DoAll( | 811 .WillRepeatedly(DoAll( |
| 814 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_NOTHING), | 812 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_NOTHING), |
| 815 WithArg<0>(PostCallback()))); | 813 WithArg<0>(PostCallback()))); |
| 816 EXPECT_CALL(*audio_renderer_, StartPlaying()) | 814 EXPECT_CALL(*audio_renderer_, StartPlaying()) |
| 817 .Times(2) | 815 .Times(2) |
| 818 .WillOnce( | 816 .WillOnce( |
| 819 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)) | 817 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)) |
| 820 .WillOnce(DoAll( | 818 .WillOnce(DoAll( |
| 821 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH), | 819 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH), |
| 822 PostQuitWhenIdle())); | 820 PostQuitWhenIdle())); |
| 823 // The first stream status change will be processed immediately. Each status | 821 // The first stream status change will be processed immediately. Each status |
| 824 // change processing involves Flush + StartPlaying when the Flush is done. The | 822 // change processing involves Flush + StartPlaying when the Flush is done. The |
| 825 // Flush operation is async in this case, so the second status change will be | 823 // Flush operation is async in this case, so the second status change will be |
| 826 // postponed by renderer until after processing the first one is finished. But | 824 // postponed by renderer until after processing the first one is finished. But |
| 827 // we must still get two pairs of Flush/StartPlaying calls eventually. | 825 // we must still get two pairs of Flush/StartPlaying calls eventually. |
| 828 audio_stream_status_change_cb.Run(false, base::TimeDelta()); | 826 stream_status_change_cb.Run(audio_stream_.get(), false, base::TimeDelta()); |
| 829 audio_stream_status_change_cb.Run(true, base::TimeDelta()); | 827 stream_status_change_cb.Run(audio_stream_.get(), true, base::TimeDelta()); |
| 830 base::RunLoop().Run(); | 828 base::RunLoop().Run(); |
| 831 | 829 |
| 832 EXPECT_CALL(*video_renderer_, Flush(_)) | 830 EXPECT_CALL(*video_renderer_, Flush(_)) |
| 833 .Times(2) | 831 .Times(2) |
| 834 .WillRepeatedly(DoAll( | 832 .WillRepeatedly(DoAll( |
| 835 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_NOTHING), | 833 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_NOTHING), |
| 836 WithArg<0>(PostCallback()))); | 834 WithArg<0>(PostCallback()))); |
| 837 EXPECT_CALL(*video_renderer_, StartPlayingFrom(base::TimeDelta())) | 835 EXPECT_CALL(*video_renderer_, StartPlayingFrom(base::TimeDelta())) |
| 838 .Times(2) | 836 .Times(2) |
| 839 .WillOnce( | 837 .WillOnce( |
| 840 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH)) | 838 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH)) |
| 841 .WillOnce(DoAll( | 839 .WillOnce(DoAll( |
| 842 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), | 840 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), |
| 843 PostQuitWhenIdle())); | 841 PostQuitWhenIdle())); |
| 844 // The first stream status change will be processed immediately. Each status | 842 // The first stream status change will be processed immediately. Each status |
| 845 // change processing involves Flush + StartPlaying when the Flush is done. The | 843 // change processing involves Flush + StartPlaying when the Flush is done. The |
| 846 // Flush operation is async in this case, so the second status change will be | 844 // Flush operation is async in this case, so the second status change will be |
| 847 // postponed by renderer until after processing the first one is finished. But | 845 // postponed by renderer until after processing the first one is finished. But |
| 848 // we must still get two pairs of Flush/StartPlaying calls eventually. | 846 // we must still get two pairs of Flush/StartPlaying calls eventually. |
| 849 video_stream_status_change_cb.Run(false, base::TimeDelta()); | 847 stream_status_change_cb.Run(video_stream_.get(), false, base::TimeDelta()); |
| 850 video_stream_status_change_cb.Run(true, base::TimeDelta()); | 848 stream_status_change_cb.Run(video_stream_.get(), true, base::TimeDelta()); |
| 851 base::RunLoop().Run(); | 849 base::RunLoop().Run(); |
| 852 } | 850 } |
| 853 | 851 |
| 854 } // namespace media | 852 } // namespace media |
| OLD | NEW |