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

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

Issue 2684103005: Allow media track switching. (Closed)
Patch Set: Updated GpuMemoryBufferVideoFramePool comment Created 3 years, 8 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderers/audio_renderer_impl.h" 5 #include "media/renderers/audio_renderer_impl.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 static double kOutputMicrosPerFrame = 59 static double kOutputMicrosPerFrame =
60 static_cast<double>(base::Time::kMicrosecondsPerSecond) / 60 static_cast<double>(base::Time::kMicrosecondsPerSecond) /
61 kOutputSamplesPerSecond; 61 kOutputSamplesPerSecond;
62 62
63 ACTION_P(EnterPendingDecoderInitStateAction, test) { 63 ACTION_P(EnterPendingDecoderInitStateAction, test) {
64 test->EnterPendingDecoderInitState(arg2); 64 test->EnterPendingDecoderInitState(arg2);
65 } 65 }
66 66
67 class AudioRendererImplTest : public ::testing::Test, public RendererClient { 67 class AudioRendererImplTest : public ::testing::Test, public RendererClient {
68 public: 68 public:
69 ScopedVector<AudioDecoder> CreateAudioDecoderForTest() {
70 MockAudioDecoder* decoder = new MockAudioDecoder();
71 if (!enter_pending_decoder_init_) {
72 EXPECT_CALL(*decoder, Initialize(_, _, _, _))
73 .WillOnce(DoAll(SaveArg<3>(&output_cb_),
74 RunCallback<2>(expected_init_result_)));
75 } else {
76 EXPECT_CALL(*decoder, Initialize(_, _, _, _))
77 .WillOnce(EnterPendingDecoderInitStateAction(this));
78 }
79 EXPECT_CALL(*decoder, Decode(_, _))
80 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder));
81 EXPECT_CALL(*decoder, Reset(_))
82 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder));
83 ScopedVector<AudioDecoder> decoders;
84 decoders.push_back(decoder);
85 return decoders;
86 }
87
69 // Give the decoder some non-garbage media properties. 88 // Give the decoder some non-garbage media properties.
70 AudioRendererImplTest() 89 AudioRendererImplTest()
71 : hardware_params_(AudioParameters::AUDIO_PCM_LOW_LATENCY, 90 : hardware_params_(AudioParameters::AUDIO_PCM_LOW_LATENCY,
72 kChannelLayout, 91 kChannelLayout,
73 kOutputSamplesPerSecond, 92 kOutputSamplesPerSecond,
74 SampleFormatToBytesPerChannel(kSampleFormat) * 8, 93 SampleFormatToBytesPerChannel(kSampleFormat) * 8,
75 512), 94 512),
76 sink_(new FakeAudioRendererSink(hardware_params_)), 95 sink_(new FakeAudioRendererSink(hardware_params_)),
77 tick_clock_(new base::SimpleTestTickClock()), 96 tick_clock_(new base::SimpleTestTickClock()),
78 demuxer_stream_(DemuxerStream::AUDIO), 97 demuxer_stream_(DemuxerStream::AUDIO),
79 decoder_(new MockAudioDecoder()), 98 expected_init_result_(true),
99 enter_pending_decoder_init_(false),
80 ended_(false) { 100 ended_(false) {
81 AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout, 101 AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout,
82 kInputSamplesPerSecond, EmptyExtraData(), 102 kInputSamplesPerSecond, EmptyExtraData(),
83 Unencrypted()); 103 Unencrypted());
84 demuxer_stream_.set_audio_decoder_config(audio_config); 104 demuxer_stream_.set_audio_decoder_config(audio_config);
85 105
86 ConfigureDecoder();
87 ConfigureDemuxerStream(true); 106 ConfigureDemuxerStream(true);
88 107
89 AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY, 108 AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
90 kChannelLayout, 109 kChannelLayout,
91 kOutputSamplesPerSecond, 110 kOutputSamplesPerSecond,
92 SampleFormatToBytesPerChannel(kSampleFormat) * 8, 111 SampleFormatToBytesPerChannel(kSampleFormat) * 8,
93 512); 112 512);
94 ScopedVector<AudioDecoder> decoders; 113 renderer_.reset(new AudioRendererImpl(
95 decoders.push_back(decoder_); 114 message_loop_.task_runner(), sink_.get(),
96 renderer_.reset(new AudioRendererImpl(message_loop_.task_runner(), 115 base::Bind(&AudioRendererImplTest::CreateAudioDecoderForTest,
97 sink_.get(), std::move(decoders), 116 base::Unretained(this)),
98 new MediaLog())); 117 new MediaLog()));
99 renderer_->tick_clock_.reset(tick_clock_); 118 renderer_->tick_clock_.reset(tick_clock_);
100 tick_clock_->Advance(base::TimeDelta::FromSeconds(1)); 119 tick_clock_->Advance(base::TimeDelta::FromSeconds(1));
101 } 120 }
102 121
103 virtual ~AudioRendererImplTest() { 122 virtual ~AudioRendererImplTest() {
104 SCOPED_TRACE("~AudioRendererImplTest()"); 123 SCOPED_TRACE("~AudioRendererImplTest()");
105 } 124 }
106 125
107 // Used to save callbacks and run them at a later time.
108 void ConfigureDecoder() {
109 EXPECT_CALL(*decoder_, Decode(_, _))
110 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder));
111 EXPECT_CALL(*decoder_, Reset(_))
112 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder));
113 }
114
115 // Mock out demuxer reads. 126 // Mock out demuxer reads.
116 void ConfigureDemuxerStream(bool supports_config_changes) { 127 void ConfigureDemuxerStream(bool supports_config_changes) {
117 EXPECT_CALL(demuxer_stream_, Read(_)) 128 EXPECT_CALL(demuxer_stream_, Read(_))
118 .WillRepeatedly( 129 .WillRepeatedly(
119 RunCallback<0>(DemuxerStream::kOk, 130 RunCallback<0>(DemuxerStream::kOk,
120 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0)))); 131 scoped_refptr<DecoderBuffer>(new DecoderBuffer(0))));
121 EXPECT_CALL(demuxer_stream_, SupportsConfigChanges()) 132 EXPECT_CALL(demuxer_stream_, SupportsConfigChanges())
122 .WillRepeatedly(Return(supports_config_changes)); 133 .WillRepeatedly(Return(supports_config_changes));
123 } 134 }
124 135
125 // Reconfigures a renderer without config change support using given params. 136 // Reconfigures a renderer without config change support using given params.
126 void ConfigureBasicRenderer(const AudioParameters& params) { 137 void ConfigureBasicRenderer(const AudioParameters& params) {
127 hardware_params_ = params; 138 hardware_params_ = params;
128 sink_ = new FakeAudioRendererSink(hardware_params_); 139 sink_ = new FakeAudioRendererSink(hardware_params_);
129 decoder_ = new MockAudioDecoder(); 140 renderer_.reset(new AudioRendererImpl(
130 ConfigureDecoder(); 141 message_loop_.task_runner(), sink_.get(),
131 ScopedVector<AudioDecoder> decoders; 142 base::Bind(&AudioRendererImplTest::CreateAudioDecoderForTest,
132 decoders.push_back(decoder_); 143 base::Unretained(this)),
133 renderer_.reset(new AudioRendererImpl(message_loop_.task_runner(), 144 new MediaLog()));
134 sink_.get(), std::move(decoders),
135 new MediaLog()));
136 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_); 145 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_);
137 ConfigureDemuxerStream(false); 146 ConfigureDemuxerStream(false);
138 } 147 }
139 148
140 // Reconfigures a renderer with config change support using given params. 149 // Reconfigures a renderer with config change support using given params.
141 void ConfigureConfigChangeRenderer(const AudioParameters& params, 150 void ConfigureConfigChangeRenderer(const AudioParameters& params,
142 const AudioParameters& hardware_params) { 151 const AudioParameters& hardware_params) {
143 hardware_params_ = hardware_params; 152 hardware_params_ = hardware_params;
144 sink_ = new FakeAudioRendererSink(hardware_params_); 153 sink_ = new FakeAudioRendererSink(hardware_params_);
145 decoder_ = new MockAudioDecoder(); 154 renderer_.reset(new AudioRendererImpl(
146 ConfigureDecoder(); 155 message_loop_.task_runner(), sink_.get(),
147 ScopedVector<AudioDecoder> decoders; 156 base::Bind(&AudioRendererImplTest::CreateAudioDecoderForTest,
148 decoders.push_back(decoder_); 157 base::Unretained(this)),
149 renderer_.reset(new AudioRendererImpl(message_loop_.task_runner(), 158 new MediaLog()));
150 sink_.get(), std::move(decoders),
151 new MediaLog()));
152 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_); 159 testing::Mock::VerifyAndClearExpectations(&demuxer_stream_);
153 ConfigureDemuxerStream(true); 160 ConfigureDemuxerStream(true);
154 } 161 }
155 162
156 void ExpectUnsupportedAudioDecoder() {
157 EXPECT_CALL(*decoder_, Initialize(_, _, _, _))
158 .WillOnce(DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(false)));
159 }
160
161 // RendererClient implementation. 163 // RendererClient implementation.
162 MOCK_METHOD1(OnError, void(PipelineStatus)); 164 MOCK_METHOD1(OnError, void(PipelineStatus));
163 void OnEnded() override { 165 void OnEnded() override {
164 CHECK(!ended_); 166 CHECK(!ended_);
165 ended_ = true; 167 ended_ = true;
166 } 168 }
167 void OnStatisticsUpdate(const PipelineStatistics& stats) override { 169 void OnStatisticsUpdate(const PipelineStatistics& stats) override {
168 last_statistics_.audio_memory_usage += stats.audio_memory_usage; 170 last_statistics_.audio_memory_usage += stats.audio_memory_usage;
169 } 171 }
170 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); 172 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
171 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); 173 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));
172 MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&)); 174 MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
173 MOCK_METHOD1(OnVideoOpacityChange, void(bool)); 175 MOCK_METHOD1(OnVideoOpacityChange, void(bool));
174 MOCK_METHOD1(OnDurationChange, void(base::TimeDelta)); 176 MOCK_METHOD1(OnDurationChange, void(base::TimeDelta));
175 177
176 void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) { 178 void InitializeRenderer(DemuxerStream* demuxer_stream,
179 const PipelineStatusCB& pipeline_status_cb) {
177 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); 180 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
178 EXPECT_CALL(*this, OnVideoNaturalSizeChange(_)).Times(0); 181 EXPECT_CALL(*this, OnVideoNaturalSizeChange(_)).Times(0);
179 EXPECT_CALL(*this, OnVideoOpacityChange(_)).Times(0); 182 EXPECT_CALL(*this, OnVideoOpacityChange(_)).Times(0);
180 renderer_->Initialize(&demuxer_stream_, nullptr, this, pipeline_status_cb); 183 renderer_->Initialize(demuxer_stream, nullptr, this, pipeline_status_cb);
181 } 184 }
182 185
183 void Initialize() { 186 void Initialize() {
184 EXPECT_CALL(*decoder_, Initialize(_, _, _, _))
185 .WillOnce(DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(true)));
186 InitializeWithStatus(PIPELINE_OK); 187 InitializeWithStatus(PIPELINE_OK);
187 188
188 next_timestamp_.reset(new AudioTimestampHelper(kInputSamplesPerSecond)); 189 next_timestamp_.reset(new AudioTimestampHelper(kInputSamplesPerSecond));
189 } 190 }
190 191
191 void InitializeWithStatus(PipelineStatus expected) { 192 void InitializeWithStatus(PipelineStatus expected) {
192 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected)); 193 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected));
193 194
194 WaitableMessageLoopEvent event; 195 WaitableMessageLoopEvent event;
195 InitializeRenderer(event.GetPipelineStatusCB()); 196 InitializeRenderer(&demuxer_stream_, event.GetPipelineStatusCB());
196 event.RunAndWaitForStatus(expected); 197 event.RunAndWaitForStatus(expected);
197 198
198 // We should have no reads. 199 // We should have no reads.
199 EXPECT_TRUE(decode_cb_.is_null()); 200 EXPECT_TRUE(decode_cb_.is_null());
200 } 201 }
201 202
202 void InitializeAndDestroy() { 203 void InitializeAndDestroy() {
203 EXPECT_CALL(*decoder_, Initialize(_, _, _, _))
204 .WillOnce(RunCallback<2>(true));
205
206 WaitableMessageLoopEvent event; 204 WaitableMessageLoopEvent event;
207 InitializeRenderer(event.GetPipelineStatusCB()); 205 InitializeRenderer(&demuxer_stream_, event.GetPipelineStatusCB());
208 206
209 // Destroy the |renderer_| before we let the MessageLoop run, this simulates 207 // Destroy the |renderer_| before we let the MessageLoop run, this simulates
210 // an interleaving in which we end up destroying the |renderer_| while the 208 // an interleaving in which we end up destroying the |renderer_| while the
211 // OnDecoderSelected callback is in flight. 209 // OnDecoderSelected callback is in flight.
212 renderer_.reset(); 210 renderer_.reset();
213 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); 211 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
214 } 212 }
215 213
216 void InitializeAndDestroyDuringDecoderInit() { 214 void InitializeAndDestroyDuringDecoderInit() {
217 EXPECT_CALL(*decoder_, Initialize(_, _, _, _)) 215 enter_pending_decoder_init_ = true;
218 .WillOnce(EnterPendingDecoderInitStateAction(this));
219 216
220 WaitableMessageLoopEvent event; 217 WaitableMessageLoopEvent event;
221 InitializeRenderer(event.GetPipelineStatusCB()); 218 InitializeRenderer(&demuxer_stream_, event.GetPipelineStatusCB());
222 base::RunLoop().RunUntilIdle(); 219 base::RunLoop().RunUntilIdle();
223 DCHECK(!init_decoder_cb_.is_null()); 220 DCHECK(!init_decoder_cb_.is_null());
224 221
225 renderer_.reset(); 222 renderer_.reset();
226 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT); 223 event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
227 } 224 }
228 225
229 void EnterPendingDecoderInitState(const AudioDecoder::InitCB& cb) { 226 void EnterPendingDecoderInitState(const AudioDecoder::InitCB& cb) {
230 init_decoder_cb_ = cb; 227 init_decoder_cb_ = cb;
231 } 228 }
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 447
451 // Fixture members. 448 // Fixture members.
452 AudioParameters hardware_params_; 449 AudioParameters hardware_params_;
453 base::MessageLoop message_loop_; 450 base::MessageLoop message_loop_;
454 std::unique_ptr<AudioRendererImpl> renderer_; 451 std::unique_ptr<AudioRendererImpl> renderer_;
455 scoped_refptr<FakeAudioRendererSink> sink_; 452 scoped_refptr<FakeAudioRendererSink> sink_;
456 base::SimpleTestTickClock* tick_clock_; 453 base::SimpleTestTickClock* tick_clock_;
457 PipelineStatistics last_statistics_; 454 PipelineStatistics last_statistics_;
458 455
459 MockDemuxerStream demuxer_stream_; 456 MockDemuxerStream demuxer_stream_;
460 MockAudioDecoder* decoder_;
461 457
462 // Used for satisfying reads. 458 // Used for satisfying reads.
463 AudioDecoder::OutputCB output_cb_; 459 AudioDecoder::OutputCB output_cb_;
464 AudioDecoder::DecodeCB decode_cb_; 460 AudioDecoder::DecodeCB decode_cb_;
465 base::Closure reset_cb_; 461 base::Closure reset_cb_;
466 std::unique_ptr<AudioTimestampHelper> next_timestamp_; 462 std::unique_ptr<AudioTimestampHelper> next_timestamp_;
467 463
468 // Run during DecodeDecoder() to unblock WaitForPendingRead(). 464 // Run during DecodeDecoder() to unblock WaitForPendingRead().
469 base::Closure wait_for_pending_decode_cb_; 465 base::Closure wait_for_pending_decode_cb_;
470 466
471 AudioDecoder::InitCB init_decoder_cb_; 467 AudioDecoder::InitCB init_decoder_cb_;
468 bool expected_init_result_;
469 bool enter_pending_decoder_init_;
472 bool ended_; 470 bool ended_;
473 471
474 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); 472 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest);
475 }; 473 };
476 474
477 TEST_F(AudioRendererImplTest, Initialize_Successful) { 475 TEST_F(AudioRendererImplTest, Initialize_Successful) {
478 Initialize(); 476 Initialize();
479 } 477 }
480 478
481 TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) { 479 TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) {
482 ExpectUnsupportedAudioDecoder(); 480 expected_init_result_ = false;
483 InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED); 481 InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED);
484 } 482 }
485 483
DaleCurtis 2017/03/31 21:22:08 There needs to be a test for the track switch happ
servolk 2017/03/31 23:53:55 Done (in media/renderers/renderer_impl_unittest.cc
484 TEST_F(AudioRendererImplTest, ReinitializeForDifferentStream) {
485 // Initialize and start playback
486 Initialize();
487 Preroll();
488 StartTicking();
489 EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
490 WaitForPendingRead();
491
492 // Stop playback and flush
493 StopTicking();
494 EXPECT_TRUE(IsReadPending());
495 // Flush and expect to be notified that we have nothing.
496 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
497 FlushDuringPendingRead();
498
499 // Prepare a new demuxer stream.
500 MockDemuxerStream new_stream(DemuxerStream::AUDIO);
501 EXPECT_CALL(new_stream, SupportsConfigChanges()).WillOnce(Return(false));
502 AudioDecoderConfig audio_config(kCodec, kSampleFormat, kChannelLayout,
503 kInputSamplesPerSecond, EmptyExtraData(),
504 Unencrypted());
505 new_stream.set_audio_decoder_config(audio_config);
506
507 // The renderer is now in the flushed state and can be reinitialized.
508 WaitableMessageLoopEvent event;
509 InitializeRenderer(&new_stream, event.GetPipelineStatusCB());
510 event.RunAndWaitForStatus(PIPELINE_OK);
511 }
512
486 TEST_F(AudioRendererImplTest, Preroll) { 513 TEST_F(AudioRendererImplTest, Preroll) {
487 Initialize(); 514 Initialize();
488 Preroll(); 515 Preroll();
489 } 516 }
490 517
491 TEST_F(AudioRendererImplTest, StartTicking) { 518 TEST_F(AudioRendererImplTest, StartTicking) {
492 Initialize(); 519 Initialize();
493 Preroll(); 520 Preroll();
494 StartTicking(); 521 StartTicking();
495 522
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 // Advance far enough that we shouldn't be clamped to current time (tested 1090 // Advance far enough that we shouldn't be clamped to current time (tested
1064 // already above). 1091 // already above).
1065 tick_clock_->Advance(kOneSecond); 1092 tick_clock_->Advance(kOneSecond);
1066 EXPECT_EQ( 1093 EXPECT_EQ(
1067 current_time + timestamp_helper.GetFrameDuration(frames_to_consume.value), 1094 current_time + timestamp_helper.GetFrameDuration(frames_to_consume.value),
1068 CurrentMediaWallClockTime(&is_time_moving)); 1095 CurrentMediaWallClockTime(&is_time_moving));
1069 EXPECT_TRUE(is_time_moving); 1096 EXPECT_TRUE(is_time_moving);
1070 } 1097 }
1071 1098
1072 } // namespace media 1099 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698