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

Side by Side Diff: media/renderers/renderer_impl_unittest.cc

Issue 2491043003: MediaResource refactoring to support multiple streams (Closed)
Patch Set: rebase Created 3 years, 10 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 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
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 std::vector<DemuxerStream*> empty;
86 EXPECT_CALL(*demuxer_, GetStream(_)) 86 EXPECT_CALL(*demuxer_, GetStreams()).WillRepeatedly(Return(empty));
87 .WillRepeatedly(Return(null_pointer));
88 } 87 }
89 88
90 virtual ~RendererImplTest() { Destroy(); } 89 virtual ~RendererImplTest() { Destroy(); }
91 90
92 protected: 91 protected:
93 void Destroy() { 92 void Destroy() {
94 renderer_impl_.reset(); 93 renderer_impl_.reset();
95 base::RunLoop().RunUntilIdle(); 94 base::RunLoop().RunUntilIdle();
96 } 95 }
97 96
98 std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream( 97 std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream(
99 DemuxerStream::Type type) { 98 DemuxerStream::Type type) {
100 std::unique_ptr<StrictMock<MockDemuxerStream>> stream( 99 std::unique_ptr<StrictMock<MockDemuxerStream>> stream(
101 new StrictMock<MockDemuxerStream>(type)); 100 new StrictMock<MockDemuxerStream>(type));
102 EXPECT_CALL(*stream, SetStreamStatusChangeCB(_)) 101 EXPECT_CALL(*stream, enabled()).WillRepeatedly(Return(true));
102 EXPECT_CALL(*demuxer_, SetStreamStatusChangeCB(_))
103 .Times(testing::AnyNumber()); 103 .Times(testing::AnyNumber());
104 return stream; 104 return stream;
105 } 105 }
106 106
107 // Sets up expectations to allow the audio renderer to initialize. 107 // Sets up expectations to allow the audio renderer to initialize.
108 void SetAudioRendererInitializeExpectations(PipelineStatus status) { 108 void SetAudioRendererInitializeExpectations(PipelineStatus status) {
109 EXPECT_CALL(*audio_renderer_, Initialize(audio_stream_.get(), _, _, _)) 109 EXPECT_CALL(*audio_renderer_, Initialize(audio_stream_.get(), _, _, _))
110 .WillOnce( 110 .WillOnce(
111 DoAll(SaveArg<2>(&audio_renderer_client_), RunCallback<3>(status))); 111 DoAll(SaveArg<2>(&audio_renderer_client_), RunCallback<3>(status)));
112 } 112 }
(...skipping 18 matching lines...) Expand all
131 } 131 }
132 132
133 renderer_impl_->Initialize(demuxer_.get(), &callbacks_, 133 renderer_impl_->Initialize(demuxer_.get(), &callbacks_,
134 base::Bind(&CallbackHelper::OnInitialize, 134 base::Bind(&CallbackHelper::OnInitialize,
135 base::Unretained(&callbacks_))); 135 base::Unretained(&callbacks_)));
136 base::RunLoop().RunUntilIdle(); 136 base::RunLoop().RunUntilIdle();
137 } 137 }
138 138
139 void CreateAudioStream() { 139 void CreateAudioStream() {
140 audio_stream_ = CreateStream(DemuxerStream::AUDIO); 140 audio_stream_ = CreateStream(DemuxerStream::AUDIO);
141 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO)) 141 std::vector<DemuxerStream*> streams;
142 .WillRepeatedly(Return(audio_stream_.get())); 142 streams.push_back(audio_stream_.get());
143 if (video_stream_)
144 streams.push_back(video_stream_.get());
xhwang 2017/02/01 18:26:04 ditto about refactor this test, e.g. maybe just s/
servolk 2017/02/01 22:29:21 Done.
145 EXPECT_CALL(*demuxer_, GetStreams()).WillRepeatedly(Return(streams));
143 } 146 }
144 147
145 void CreateVideoStream(bool is_encrypted = false) { 148 void CreateVideoStream(bool is_encrypted = false) {
146 video_stream_ = CreateStream(DemuxerStream::VIDEO); 149 video_stream_ = CreateStream(DemuxerStream::VIDEO);
147 video_stream_->set_video_decoder_config( 150 video_stream_->set_video_decoder_config(
148 is_encrypted ? TestVideoConfig::NormalEncrypted() 151 is_encrypted ? TestVideoConfig::NormalEncrypted()
149 : TestVideoConfig::Normal()); 152 : TestVideoConfig::Normal());
150 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::VIDEO)) 153 std::vector<DemuxerStream*> streams;
151 .WillRepeatedly(Return(video_stream_.get())); 154 if (audio_stream_)
155 streams.push_back(audio_stream_.get());
156 streams.push_back(video_stream_.get());
157 EXPECT_CALL(*demuxer_, GetStreams()).WillRepeatedly(Return(streams));
152 } 158 }
153 159
154 void CreateEncryptedVideoStream() { CreateVideoStream(true); } 160 void CreateEncryptedVideoStream() { CreateVideoStream(true); }
155 161
156 void CreateAudioAndVideoStream() { 162 void CreateAudioAndVideoStream() {
157 CreateAudioStream(); 163 CreateAudioStream();
158 CreateVideoStream(); 164 CreateVideoStream();
159 } 165 }
160 166
161 void InitializeWithAudio() { 167 void InitializeWithAudio() {
162 CreateAudioStream(); 168 CreateAudioStream();
163 SetAudioRendererInitializeExpectations(PIPELINE_OK); 169 SetAudioRendererInitializeExpectations(PIPELINE_OK);
164 // There is a potential race between HTMLMediaElement/WMPI shutdown and 170 // There is a potential race between HTMLMediaElement/WMPI shutdown and
165 // renderers being initialized which might result in DemuxerStreamProvider 171 // renderers being initialized which might result in MediaResource
166 // GetStream suddenly returning NULL (see crbug.com/668604). So we are going 172 // GetStreams suddenly returning fewer streams than before or even returning
167 // to check here that GetStream will be invoked exactly 3 times during 173 // and empty stream collection (see crbug.com/668604). So we are going to
174 // check here that GetStreams will be invoked exactly 3 times during
168 // RendererImpl initialization to help catch potential issues. Currently the 175 // RendererImpl initialization to help catch potential issues. Currently the
169 // GetStream is invoked once directly from RendererImpl::Initialize, once 176 // GetStreams is invoked once from the RendererImpl::Initialize via
170 // indirectly from RendererImpl::Initialize via HasEncryptedStream and once 177 // HasEncryptedStream, once from the RendererImpl::InitializeAudioRenderer
171 // from RendererImpl::InitializeAudioRenderer. 178 // and once from the RendererImpl::InitializeVideoRenderer.
172 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO)) 179 std::vector<DemuxerStream*> streams;
173 .Times(2) 180 streams.push_back(audio_stream_.get());
174 .WillRepeatedly(Return(audio_stream_.get())); 181 EXPECT_CALL(*demuxer_, GetStreams())
182 .Times(3)
183 .WillRepeatedly(Return(streams));
175 InitializeAndExpect(PIPELINE_OK); 184 InitializeAndExpect(PIPELINE_OK);
176 } 185 }
177 186
178 void InitializeWithVideo() { 187 void InitializeWithVideo() {
179 CreateVideoStream(); 188 CreateVideoStream();
180 SetVideoRendererInitializeExpectations(PIPELINE_OK); 189 SetVideoRendererInitializeExpectations(PIPELINE_OK);
181 // There is a potential race between HTMLMediaElement/WMPI shutdown and 190 // There is a potential race between HTMLMediaElement/WMPI shutdown and
182 // renderers being initialized which might result in DemuxerStreamProvider 191 // renderers being initialized which might result in MediaResource
183 // GetStream suddenly returning NULL (see crbug.com/668604). So we are going 192 // GetStreams suddenly returning fewer streams than before or even returning
184 // to check here that GetStream will be invoked exactly 3 times during 193 // and empty stream collection (see crbug.com/668604). So we are going to
194 // check here that GetStreams will be invoked exactly 3 times during
185 // RendererImpl initialization to help catch potential issues. Currently the 195 // RendererImpl initialization to help catch potential issues. Currently the
186 // GetStream is invoked once directly from RendererImpl::Initialize, once 196 // GetStreams is invoked once from the RendererImpl::Initialize via
187 // indirectly from RendererImpl::Initialize via HasEncryptedStream and once 197 // HasEncryptedStream, once from the RendererImpl::InitializeAudioRenderer
188 // from RendererImpl::InitializeVideoRenderer. 198 // and once from the RendererImpl::InitializeVideoRenderer.
189 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::VIDEO)) 199 std::vector<DemuxerStream*> streams;
190 .Times(2) 200 streams.push_back(video_stream_.get());
191 .WillRepeatedly(Return(video_stream_.get())); 201 EXPECT_CALL(*demuxer_, GetStreams())
202 .Times(3)
203 .WillRepeatedly(Return(streams));
192 InitializeAndExpect(PIPELINE_OK); 204 InitializeAndExpect(PIPELINE_OK);
193 } 205 }
194 206
195 void InitializeWithAudioAndVideo() { 207 void InitializeWithAudioAndVideo() {
196 CreateAudioAndVideoStream(); 208 CreateAudioAndVideoStream();
197 SetAudioRendererInitializeExpectations(PIPELINE_OK); 209 SetAudioRendererInitializeExpectations(PIPELINE_OK);
198 SetVideoRendererInitializeExpectations(PIPELINE_OK); 210 SetVideoRendererInitializeExpectations(PIPELINE_OK);
199 InitializeAndExpect(PIPELINE_OK); 211 InitializeAndExpect(PIPELINE_OK);
200 } 212 }
201 213
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 EXPECT_CALL(*video_renderer_, StartPlayingFrom(kStartTime)); 756 EXPECT_CALL(*video_renderer_, StartPlayingFrom(kStartTime));
745 renderer_impl_->StartPlayingFrom(kStartTime); 757 renderer_impl_->StartPlayingFrom(kStartTime);
746 758
747 // Nothing else should primed on the message loop. 759 // Nothing else should primed on the message loop.
748 base::RunLoop().RunUntilIdle(); 760 base::RunLoop().RunUntilIdle();
749 } 761 }
750 762
751 TEST_F(RendererImplTest, StreamStatusNotificationHandling) { 763 TEST_F(RendererImplTest, StreamStatusNotificationHandling) {
752 CreateAudioAndVideoStream(); 764 CreateAudioAndVideoStream();
753 765
754 DemuxerStream::StreamStatusChangeCB audio_stream_status_change_cb; 766 StreamStatusChangeCB stream_status_change_cb;
755 DemuxerStream::StreamStatusChangeCB video_stream_status_change_cb; 767 EXPECT_CALL(*demuxer_, SetStreamStatusChangeCB(_))
756 EXPECT_CALL(*audio_stream_, SetStreamStatusChangeCB(_)) 768 .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); 769 SetAudioRendererInitializeExpectations(PIPELINE_OK);
761 SetVideoRendererInitializeExpectations(PIPELINE_OK); 770 SetVideoRendererInitializeExpectations(PIPELINE_OK);
762 InitializeAndExpect(PIPELINE_OK); 771 InitializeAndExpect(PIPELINE_OK);
763 Play(); 772 Play();
764 773
765 // Verify that DemuxerStream status changes cause the corresponding 774 // Verify that DemuxerStream status changes cause the corresponding
766 // audio/video renderer to be flushed and restarted. 775 // audio/video renderer to be flushed and restarted.
767 EXPECT_CALL(time_source_, StopTicking()); 776 EXPECT_CALL(time_source_, StopTicking());
768 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>()); 777 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>());
769 EXPECT_CALL(*audio_renderer_, StartPlaying()) 778 EXPECT_CALL(*audio_renderer_, StartPlaying())
770 .Times(1) 779 .Times(1)
771 .WillOnce( 780 .WillOnce(
772 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)); 781 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH));
773 audio_stream_status_change_cb.Run(false, base::TimeDelta()); 782 stream_status_change_cb.Run(audio_stream_.get(), false, base::TimeDelta());
774 783
775 EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>()); 784 EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>());
776 EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)) 785 EXPECT_CALL(*video_renderer_, StartPlayingFrom(_))
777 .Times(1) 786 .Times(1)
778 .WillOnce(DoAll( 787 .WillOnce(DoAll(
779 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), 788 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH),
780 PostQuitWhenIdle())); 789 PostQuitWhenIdle()));
781 790
782 video_stream_status_change_cb.Run(false, base::TimeDelta()); 791 stream_status_change_cb.Run(video_stream_.get(), false, base::TimeDelta());
783 base::RunLoop().Run(); 792 base::RunLoop().Run();
784 } 793 }
785 794
786 // Stream status changes are handled asynchronously by the renderer and may take 795 // 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 796 // 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 797 // 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 798 // 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 799 // renderer may postpone processing status changes, but still must process all
791 // of them eventually. 800 // of them eventually.
792 TEST_F(RendererImplTest, PostponedStreamStatusNotificationHandling) { 801 TEST_F(RendererImplTest, PostponedStreamStatusNotificationHandling) {
793 CreateAudioAndVideoStream(); 802 CreateAudioAndVideoStream();
794 803
795 DemuxerStream::StreamStatusChangeCB audio_stream_status_change_cb; 804 StreamStatusChangeCB stream_status_change_cb;
796 DemuxerStream::StreamStatusChangeCB video_stream_status_change_cb; 805 EXPECT_CALL(*demuxer_, SetStreamStatusChangeCB(_))
797 EXPECT_CALL(*audio_stream_, SetStreamStatusChangeCB(_)) 806 .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); 807 SetAudioRendererInitializeExpectations(PIPELINE_OK);
802 SetVideoRendererInitializeExpectations(PIPELINE_OK); 808 SetVideoRendererInitializeExpectations(PIPELINE_OK);
803 InitializeAndExpect(PIPELINE_OK); 809 InitializeAndExpect(PIPELINE_OK);
804 Play(); 810 Play();
805 811
806 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)) 812 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
807 .Times(2); 813 .Times(2);
808 814
809 EXPECT_CALL(time_source_, StopTicking()).Times(2); 815 EXPECT_CALL(time_source_, StopTicking()).Times(2);
810 EXPECT_CALL(time_source_, StartTicking()).Times(2); 816 EXPECT_CALL(time_source_, StartTicking()).Times(2);
811 EXPECT_CALL(*audio_renderer_, Flush(_)) 817 EXPECT_CALL(*audio_renderer_, Flush(_))
812 .Times(2) 818 .Times(2)
813 .WillRepeatedly(DoAll( 819 .WillRepeatedly(DoAll(
814 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_NOTHING), 820 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_NOTHING),
815 WithArg<0>(PostCallback()))); 821 WithArg<0>(PostCallback())));
816 EXPECT_CALL(*audio_renderer_, StartPlaying()) 822 EXPECT_CALL(*audio_renderer_, StartPlaying())
817 .Times(2) 823 .Times(2)
818 .WillOnce( 824 .WillOnce(
819 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)) 825 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH))
820 .WillOnce(DoAll( 826 .WillOnce(DoAll(
821 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH), 827 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH),
822 PostQuitWhenIdle())); 828 PostQuitWhenIdle()));
823 // The first stream status change will be processed immediately. Each status 829 // The first stream status change will be processed immediately. Each status
824 // change processing involves Flush + StartPlaying when the Flush is done. The 830 // 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 831 // 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 832 // postponed by renderer until after processing the first one is finished. But
827 // we must still get two pairs of Flush/StartPlaying calls eventually. 833 // we must still get two pairs of Flush/StartPlaying calls eventually.
828 audio_stream_status_change_cb.Run(false, base::TimeDelta()); 834 stream_status_change_cb.Run(audio_stream_.get(), false, base::TimeDelta());
829 audio_stream_status_change_cb.Run(true, base::TimeDelta()); 835 stream_status_change_cb.Run(audio_stream_.get(), true, base::TimeDelta());
830 base::RunLoop().Run(); 836 base::RunLoop().Run();
831 837
832 EXPECT_CALL(*video_renderer_, Flush(_)) 838 EXPECT_CALL(*video_renderer_, Flush(_))
833 .Times(2) 839 .Times(2)
834 .WillRepeatedly(DoAll( 840 .WillRepeatedly(DoAll(
835 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_NOTHING), 841 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_NOTHING),
836 WithArg<0>(PostCallback()))); 842 WithArg<0>(PostCallback())));
837 EXPECT_CALL(*video_renderer_, StartPlayingFrom(base::TimeDelta())) 843 EXPECT_CALL(*video_renderer_, StartPlayingFrom(base::TimeDelta()))
838 .Times(2) 844 .Times(2)
839 .WillOnce( 845 .WillOnce(
840 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH)) 846 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH))
841 .WillOnce(DoAll( 847 .WillOnce(DoAll(
842 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), 848 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH),
843 PostQuitWhenIdle())); 849 PostQuitWhenIdle()));
844 // The first stream status change will be processed immediately. Each status 850 // The first stream status change will be processed immediately. Each status
845 // change processing involves Flush + StartPlaying when the Flush is done. The 851 // 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 852 // 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 853 // postponed by renderer until after processing the first one is finished. But
848 // we must still get two pairs of Flush/StartPlaying calls eventually. 854 // we must still get two pairs of Flush/StartPlaying calls eventually.
849 video_stream_status_change_cb.Run(false, base::TimeDelta()); 855 stream_status_change_cb.Run(video_stream_.get(), false, base::TimeDelta());
850 video_stream_status_change_cb.Run(true, base::TimeDelta()); 856 stream_status_change_cb.Run(video_stream_.get(), true, base::TimeDelta());
851 base::RunLoop().Run(); 857 base::RunLoop().Run();
852 } 858 }
853 859
854 } // namespace media 860 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698