OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include <stdlib.h> | 6 #include <stdlib.h> |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <limits> | 9 #include <limits> |
10 #include <memory> | 10 #include <memory> |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 | 48 |
49 void IgnoreEos() {} | 49 void IgnoreEos() {} |
50 | 50 |
51 class BufferFeeder : public MediaPipelineBackend::Decoder::Delegate { | 51 class BufferFeeder : public MediaPipelineBackend::Decoder::Delegate { |
52 public: | 52 public: |
53 BufferFeeder(const AudioConfig& config, | 53 BufferFeeder(const AudioConfig& config, |
54 bool effects_only, | 54 bool effects_only, |
55 const base::Closure& eos_cb); | 55 const base::Closure& eos_cb); |
56 ~BufferFeeder() override {} | 56 ~BufferFeeder() override {} |
57 | 57 |
58 void Initialize(); | 58 void Initialize(float playback_rate); |
59 void Start(); | 59 void Start(); |
60 void Stop(); | 60 void Stop(); |
61 | 61 |
62 int64_t max_rendering_delay_error_us() { | 62 int64_t max_rendering_delay_error_us() { |
63 return max_rendering_delay_error_us_; | 63 return max_rendering_delay_error_us_; |
64 } | 64 } |
65 | 65 |
66 int64_t max_positive_rendering_delay_error_us() { | 66 int64_t max_positive_rendering_delay_error_us() { |
67 return max_positive_rendering_delay_error_us_; | 67 return max_positive_rendering_delay_error_us_; |
68 } | 68 } |
(...skipping 26 matching lines...) Expand all Loading... |
95 DCHECK(thread_checker_.CalledOnValidThread()); | 95 DCHECK(thread_checker_.CalledOnValidThread()); |
96 ASSERT_TRUE(false); | 96 ASSERT_TRUE(false); |
97 } | 97 } |
98 void OnVideoResolutionChanged(const Size& size) override { | 98 void OnVideoResolutionChanged(const Size& size) override { |
99 DCHECK(thread_checker_.CalledOnValidThread()); | 99 DCHECK(thread_checker_.CalledOnValidThread()); |
100 } | 100 } |
101 | 101 |
102 const AudioConfig config_; | 102 const AudioConfig config_; |
103 const bool effects_only_; | 103 const bool effects_only_; |
104 const base::Closure eos_cb_; | 104 const base::Closure eos_cb_; |
| 105 double original_playback_rate_; |
| 106 double playback_rate_; |
105 int64_t max_rendering_delay_error_us_; | 107 int64_t max_rendering_delay_error_us_; |
106 int64_t max_positive_rendering_delay_error_us_; | 108 int64_t max_positive_rendering_delay_error_us_; |
107 int64_t max_negative_rendering_delay_error_us_; | 109 int64_t max_negative_rendering_delay_error_us_; |
108 int64_t total_rendering_delay_error_us_; | 110 int64_t total_rendering_delay_error_us_; |
109 size_t sample_count_; | 111 size_t sample_count_; |
110 bool feeding_completed_; | 112 bool feeding_completed_; |
111 std::unique_ptr<TaskRunnerImpl> task_runner_; | 113 std::unique_ptr<TaskRunnerImpl> task_runner_; |
112 std::unique_ptr<MediaPipelineBackend> backend_; | 114 std::unique_ptr<MediaPipelineBackend> backend_; |
113 MediaPipelineBackend::AudioDecoder* decoder_; | 115 MediaPipelineBackend::AudioDecoder* decoder_; |
114 int64_t push_limit_us_; | 116 int64_t push_limit_us_; |
115 int64_t last_push_length_us_; | 117 int64_t last_push_length_us_; |
116 int64_t pushed_us_; | 118 int64_t pushed_us_; |
117 int64_t next_push_playback_timestamp_; | 119 int64_t next_push_playback_timestamp_; |
118 scoped_refptr<DecoderBufferBase> pending_buffer_; | 120 scoped_refptr<DecoderBufferBase> pending_buffer_; |
119 base::ThreadChecker thread_checker_; | 121 base::ThreadChecker thread_checker_; |
120 | 122 |
121 DISALLOW_COPY_AND_ASSIGN(BufferFeeder); | 123 DISALLOW_COPY_AND_ASSIGN(BufferFeeder); |
122 }; | 124 }; |
123 | 125 |
124 } // namespace | 126 } // namespace |
125 | 127 |
126 class MultizoneBackendTest : public testing::TestWithParam<int> { | 128 using TestParams = std::tr1::tuple<int, // sample rate |
| 129 float>; // playback rate |
| 130 |
| 131 class MultizoneBackendTest : public testing::TestWithParam<TestParams> { |
127 public: | 132 public: |
128 MultizoneBackendTest(); | 133 MultizoneBackendTest(); |
129 ~MultizoneBackendTest() override; | 134 ~MultizoneBackendTest() override; |
130 | 135 |
131 void SetUp() override { | 136 void SetUp() override { |
132 srand(12345); | 137 srand(12345); |
133 CastMediaShlib::Initialize(base::CommandLine::ForCurrentProcess()->argv()); | 138 CastMediaShlib::Initialize(base::CommandLine::ForCurrentProcess()->argv()); |
134 } | 139 } |
135 | 140 |
136 void TearDown() override { | 141 void TearDown() override { |
137 // Pipeline must be destroyed before finalizing media shlib. | 142 // Pipeline must be destroyed before finalizing media shlib. |
138 audio_feeder_.reset(); | 143 audio_feeder_.reset(); |
139 effects_feeders_.clear(); | 144 effects_feeders_.clear(); |
140 CastMediaShlib::Finalize(); | 145 CastMediaShlib::Finalize(); |
141 } | 146 } |
142 | 147 |
143 void AddEffectsStreams(); | 148 void AddEffectsStreams(); |
144 | 149 |
145 void Initialize(int sample_rate); | 150 void Initialize(int sample_rate, float playback_rate); |
146 void Start(); | 151 void Start(); |
147 void OnEndOfStream(); | 152 void OnEndOfStream(); |
148 | 153 |
149 private: | 154 private: |
150 std::vector<std::unique_ptr<BufferFeeder>> effects_feeders_; | 155 std::vector<std::unique_ptr<BufferFeeder>> effects_feeders_; |
151 std::unique_ptr<BufferFeeder> audio_feeder_; | 156 std::unique_ptr<BufferFeeder> audio_feeder_; |
152 | 157 |
153 DISALLOW_COPY_AND_ASSIGN(MultizoneBackendTest); | 158 DISALLOW_COPY_AND_ASSIGN(MultizoneBackendTest); |
154 }; | 159 }; |
155 | 160 |
156 namespace { | 161 namespace { |
157 | 162 |
158 BufferFeeder::BufferFeeder(const AudioConfig& config, | 163 BufferFeeder::BufferFeeder(const AudioConfig& config, |
159 bool effects_only, | 164 bool effects_only, |
160 const base::Closure& eos_cb) | 165 const base::Closure& eos_cb) |
161 : config_(config), | 166 : config_(config), |
162 effects_only_(effects_only), | 167 effects_only_(effects_only), |
163 eos_cb_(eos_cb), | 168 eos_cb_(eos_cb), |
| 169 original_playback_rate_(1.0), |
| 170 playback_rate_(1.0), |
164 max_rendering_delay_error_us_(0), | 171 max_rendering_delay_error_us_(0), |
165 max_positive_rendering_delay_error_us_(0), | 172 max_positive_rendering_delay_error_us_(0), |
166 max_negative_rendering_delay_error_us_(0), | 173 max_negative_rendering_delay_error_us_(0), |
167 total_rendering_delay_error_us_(0), | 174 total_rendering_delay_error_us_(0), |
168 sample_count_(0), | 175 sample_count_(0), |
169 feeding_completed_(false), | 176 feeding_completed_(false), |
170 task_runner_(new TaskRunnerImpl()), | 177 task_runner_(new TaskRunnerImpl()), |
171 decoder_(nullptr), | 178 decoder_(nullptr), |
172 push_limit_us_(effects_only_ ? 0 : kPushTimeUs), | 179 push_limit_us_(effects_only_ ? 0 : kPushTimeUs), |
173 last_push_length_us_(0), | 180 last_push_length_us_(0), |
174 pushed_us_(0), | 181 pushed_us_(0), |
175 next_push_playback_timestamp_(kNoTimestamp) { | 182 next_push_playback_timestamp_(kNoTimestamp) { |
176 CHECK(!eos_cb_.is_null()); | 183 CHECK(!eos_cb_.is_null()); |
177 } | 184 } |
178 | 185 |
179 void BufferFeeder::Initialize() { | 186 void BufferFeeder::Initialize(float playback_rate) { |
| 187 original_playback_rate_ = playback_rate_ = playback_rate; |
180 MediaPipelineDeviceParams params( | 188 MediaPipelineDeviceParams params( |
181 MediaPipelineDeviceParams::kModeIgnorePts, | 189 MediaPipelineDeviceParams::kModeIgnorePts, |
182 effects_only_ ? MediaPipelineDeviceParams::kAudioStreamSoundEffects | 190 effects_only_ ? MediaPipelineDeviceParams::kAudioStreamSoundEffects |
183 : MediaPipelineDeviceParams::kAudioStreamNormal, | 191 : MediaPipelineDeviceParams::kAudioStreamNormal, |
184 task_runner_.get()); | 192 task_runner_.get()); |
185 backend_.reset(CastMediaShlib::CreateMediaPipelineBackend(params)); | 193 backend_.reset(CastMediaShlib::CreateMediaPipelineBackend(params)); |
186 CHECK(backend_); | 194 CHECK(backend_); |
187 | 195 |
188 decoder_ = backend_->CreateAudioDecoder(); | 196 decoder_ = backend_->CreateAudioDecoder(); |
189 CHECK(decoder_); | 197 CHECK(decoder_); |
190 ASSERT_TRUE(decoder_->SetConfig(config_)); | 198 ASSERT_TRUE(decoder_->SetConfig(config_)); |
191 decoder_->SetDelegate(this); | 199 decoder_->SetDelegate(this); |
192 | 200 |
193 ASSERT_TRUE(backend_->Initialize()); | 201 ASSERT_TRUE(backend_->Initialize()); |
| 202 ASSERT_TRUE(backend_->SetPlaybackRate(playback_rate)); |
194 } | 203 } |
195 | 204 |
196 void BufferFeeder::Start() { | 205 void BufferFeeder::Start() { |
197 ASSERT_TRUE(backend_->Start(kStartPts)); | 206 ASSERT_TRUE(backend_->Start(kStartPts)); |
198 base::ThreadTaskRunnerHandle::Get()->PostTask( | 207 base::ThreadTaskRunnerHandle::Get()->PostTask( |
199 FROM_HERE, base::Bind(&BufferFeeder::FeedBuffer, base::Unretained(this))); | 208 FROM_HERE, base::Bind(&BufferFeeder::FeedBuffer, base::Unretained(this))); |
200 } | 209 } |
201 | 210 |
202 void BufferFeeder::Stop() { | 211 void BufferFeeder::Stop() { |
203 feeding_completed_ = true; | 212 feeding_completed_ = true; |
204 ASSERT_TRUE(backend_->Stop()); | 213 backend_->Stop(); |
205 } | 214 } |
206 | 215 |
207 void BufferFeeder::FeedBuffer() { | 216 void BufferFeeder::FeedBuffer() { |
208 CHECK(decoder_); | 217 CHECK(decoder_); |
209 if (feeding_completed_) | 218 if (feeding_completed_) |
210 return; | 219 return; |
211 | 220 |
| 221 if (!effects_only_ && pushed_us_ >= push_limit_us_ / 2 && |
| 222 playback_rate_ == original_playback_rate_) { |
| 223 if (original_playback_rate_ < 1.0) { |
| 224 playback_rate_ = original_playback_rate_ * 2; |
| 225 ASSERT_TRUE(backend_->SetPlaybackRate(playback_rate_)); |
| 226 } else { |
| 227 playback_rate_ = original_playback_rate_ / 2; |
| 228 ASSERT_TRUE(backend_->SetPlaybackRate(playback_rate_)); |
| 229 } |
| 230 } |
| 231 |
212 if (!effects_only_ && pushed_us_ >= push_limit_us_) { | 232 if (!effects_only_ && pushed_us_ >= push_limit_us_) { |
213 pending_buffer_ = new media::DecoderBufferAdapter( | 233 pending_buffer_ = new media::DecoderBufferAdapter( |
214 ::media::DecoderBuffer::CreateEOSBuffer()); | 234 ::media::DecoderBuffer::CreateEOSBuffer()); |
215 feeding_completed_ = true; | 235 feeding_completed_ = true; |
216 last_push_length_us_ = 0; | 236 last_push_length_us_ = 0; |
217 } else { | 237 } else { |
218 int size_bytes = (rand() % 128 + 16) * 16; | 238 int size_bytes = (rand() % 96 + 32) * 16; |
219 int num_samples = | 239 int num_samples = |
220 size_bytes / (config_.bytes_per_channel * config_.channel_number); | 240 size_bytes / (config_.bytes_per_channel * config_.channel_number); |
221 last_push_length_us_ = | 241 last_push_length_us_ = num_samples * kMicrosecondsPerSecond / |
222 num_samples * kMicrosecondsPerSecond / config_.samples_per_second; | 242 (config_.samples_per_second * playback_rate_); |
223 scoped_refptr<::media::DecoderBuffer> silence_buffer( | 243 scoped_refptr<::media::DecoderBuffer> silence_buffer( |
224 new ::media::DecoderBuffer(size_bytes)); | 244 new ::media::DecoderBuffer(size_bytes)); |
225 memset(silence_buffer->writable_data(), 0, silence_buffer->data_size()); | 245 memset(silence_buffer->writable_data(), 0, silence_buffer->data_size()); |
226 pending_buffer_ = new media::DecoderBufferAdapter(silence_buffer); | 246 pending_buffer_ = new media::DecoderBufferAdapter(silence_buffer); |
227 pending_buffer_->set_timestamp( | 247 pending_buffer_->set_timestamp( |
228 base::TimeDelta::FromMicroseconds(pushed_us_)); | 248 base::TimeDelta::FromMicroseconds(pushed_us_)); |
229 } | 249 } |
230 BufferStatus status = decoder_->PushBuffer(pending_buffer_.get()); | 250 BufferStatus status = decoder_->PushBuffer(pending_buffer_.get()); |
231 ASSERT_NE(status, MediaPipelineBackend::kBufferFailed); | 251 ASSERT_NE(status, MediaPipelineBackend::kBufferFailed); |
232 if (status == MediaPipelineBackend::kBufferPending) | 252 if (status == MediaPipelineBackend::kBufferPending) |
233 return; | 253 return; |
234 OnPushBufferComplete(MediaPipelineBackend::kBufferSuccess); | 254 OnPushBufferComplete(MediaPipelineBackend::kBufferSuccess); |
235 } | 255 } |
236 | 256 |
237 void BufferFeeder::OnEndOfStream() { | 257 void BufferFeeder::OnEndOfStream() { |
238 DCHECK(thread_checker_.CalledOnValidThread()); | 258 DCHECK(thread_checker_.CalledOnValidThread()); |
239 eos_cb_.Run(); | 259 eos_cb_.Run(); |
240 } | 260 } |
241 | 261 |
242 void BufferFeeder::OnPushBufferComplete(BufferStatus status) { | 262 void BufferFeeder::OnPushBufferComplete(BufferStatus status) { |
243 DCHECK(thread_checker_.CalledOnValidThread()); | 263 DCHECK(thread_checker_.CalledOnValidThread()); |
244 pending_buffer_ = nullptr; | 264 pending_buffer_ = nullptr; |
245 ASSERT_NE(status, MediaPipelineBackend::kBufferFailed); | |
246 | 265 |
247 if (!effects_only_) { | 266 if (!effects_only_) { |
| 267 ASSERT_NE(status, MediaPipelineBackend::kBufferFailed); |
248 MediaPipelineBackend::AudioDecoder::RenderingDelay delay = | 268 MediaPipelineBackend::AudioDecoder::RenderingDelay delay = |
249 decoder_->GetRenderingDelay(); | 269 decoder_->GetRenderingDelay(); |
250 | 270 |
251 if (delay.timestamp_microseconds != kNoTimestamp) { | 271 if (delay.timestamp_microseconds != kNoTimestamp) { |
252 if (next_push_playback_timestamp_ == kNoTimestamp) { | 272 if (next_push_playback_timestamp_ == kNoTimestamp) { |
253 next_push_playback_timestamp_ = | 273 next_push_playback_timestamp_ = |
254 delay.timestamp_microseconds + delay.delay_microseconds; | 274 delay.timestamp_microseconds + delay.delay_microseconds; |
255 } else { | 275 } else { |
256 int64_t expected_next_push_playback_timestamp = | 276 int64_t expected_next_push_playback_timestamp = |
257 next_push_playback_timestamp_ + last_push_length_us_; | 277 next_push_playback_timestamp_ + last_push_length_us_; |
258 next_push_playback_timestamp_ = | 278 next_push_playback_timestamp_ = |
259 delay.timestamp_microseconds + delay.delay_microseconds; | 279 delay.timestamp_microseconds + delay.delay_microseconds; |
260 int64_t error = next_push_playback_timestamp_ - | 280 int64_t error = next_push_playback_timestamp_ - |
261 expected_next_push_playback_timestamp; | 281 expected_next_push_playback_timestamp; |
| 282 |
262 max_rendering_delay_error_us_ = | 283 max_rendering_delay_error_us_ = |
263 std::max(max_rendering_delay_error_us_, std::abs(error)); | 284 std::max(max_rendering_delay_error_us_, std::abs(error)); |
264 total_rendering_delay_error_us_ += std::abs(error); | 285 total_rendering_delay_error_us_ += std::abs(error); |
265 if (error >= 0) { | 286 if (error >= 0) { |
266 max_positive_rendering_delay_error_us_ = | 287 max_positive_rendering_delay_error_us_ = |
267 std::max(max_positive_rendering_delay_error_us_, error); | 288 std::max(max_positive_rendering_delay_error_us_, error); |
268 } else { | 289 } else { |
269 max_negative_rendering_delay_error_us_ = | 290 max_negative_rendering_delay_error_us_ = |
270 std::min(max_negative_rendering_delay_error_us_, error); | 291 std::min(max_negative_rendering_delay_error_us_, error); |
271 } | 292 } |
272 sample_count_++; | 293 sample_count_++; |
273 } | 294 } |
274 } | 295 } |
275 } | 296 } |
276 pushed_us_ += last_push_length_us_; | 297 pushed_us_ += last_push_length_us_; |
277 | 298 |
278 if (feeding_completed_) | 299 if (feeding_completed_) |
279 return; | 300 return; |
280 | 301 |
281 base::ThreadTaskRunnerHandle::Get()->PostTask( | 302 base::ThreadTaskRunnerHandle::Get()->PostTask( |
282 FROM_HERE, base::Bind(&BufferFeeder::FeedBuffer, base::Unretained(this))); | 303 FROM_HERE, base::Bind(&BufferFeeder::FeedBuffer, base::Unretained(this))); |
283 } | 304 } |
284 | 305 |
285 } // namespace | 306 } // namespace |
286 | 307 |
287 MultizoneBackendTest::MultizoneBackendTest() {} | 308 MultizoneBackendTest::MultizoneBackendTest() {} |
288 | 309 |
289 MultizoneBackendTest::~MultizoneBackendTest() {} | 310 MultizoneBackendTest::~MultizoneBackendTest() {} |
290 | 311 |
291 void MultizoneBackendTest::Initialize(int sample_rate) { | 312 void MultizoneBackendTest::Initialize(int sample_rate, float playback_rate) { |
292 AudioConfig config; | 313 AudioConfig config; |
293 config.codec = kCodecPCM; | 314 config.codec = kCodecPCM; |
294 config.sample_format = kSampleFormatS32; | 315 config.sample_format = kSampleFormatS32; |
295 config.channel_number = 2; | 316 config.channel_number = 2; |
296 config.bytes_per_channel = 4; | 317 config.bytes_per_channel = 4; |
297 config.samples_per_second = sample_rate; | 318 config.samples_per_second = sample_rate; |
298 | 319 |
299 audio_feeder_.reset( | 320 audio_feeder_.reset( |
300 new BufferFeeder(config, false /* effects_only */, | 321 new BufferFeeder(config, false /* effects_only */, |
301 base::Bind(&MultizoneBackendTest::OnEndOfStream, | 322 base::Bind(&MultizoneBackendTest::OnEndOfStream, |
302 base::Unretained(this)))); | 323 base::Unretained(this)))); |
303 audio_feeder_->Initialize(); | 324 audio_feeder_->Initialize(playback_rate); |
304 } | 325 } |
305 | 326 |
306 void MultizoneBackendTest::AddEffectsStreams() { | 327 void MultizoneBackendTest::AddEffectsStreams() { |
307 AudioConfig effects_config; | 328 AudioConfig effects_config; |
308 effects_config.codec = kCodecPCM; | 329 effects_config.codec = kCodecPCM; |
309 effects_config.sample_format = kSampleFormatS16; | 330 effects_config.sample_format = kSampleFormatS16; |
310 effects_config.channel_number = 2; | 331 effects_config.channel_number = 2; |
311 effects_config.bytes_per_channel = 2; | 332 effects_config.bytes_per_channel = 2; |
312 effects_config.samples_per_second = 48000; | 333 effects_config.samples_per_second = 48000; |
313 | 334 |
314 for (int i = 0; i < kNumEffectsStreams; ++i) { | 335 for (int i = 0; i < kNumEffectsStreams; ++i) { |
315 std::unique_ptr<BufferFeeder> feeder(new BufferFeeder( | 336 std::unique_ptr<BufferFeeder> feeder(new BufferFeeder( |
316 effects_config, true /* effects_only */, base::Bind(&IgnoreEos))); | 337 effects_config, true /* effects_only */, base::Bind(&IgnoreEos))); |
317 feeder->Initialize(); | 338 feeder->Initialize(1.0f); |
318 effects_feeders_.push_back(std::move(feeder)); | 339 effects_feeders_.push_back(std::move(feeder)); |
319 } | 340 } |
320 } | 341 } |
321 | 342 |
322 void MultizoneBackendTest::Start() { | 343 void MultizoneBackendTest::Start() { |
323 for (auto& feeder : effects_feeders_) | 344 for (auto& feeder : effects_feeders_) |
324 feeder->Start(); | 345 feeder->Start(); |
325 CHECK(audio_feeder_); | 346 CHECK(audio_feeder_); |
326 audio_feeder_->Start(); | 347 audio_feeder_->Start(); |
327 } | 348 } |
(...skipping 10 matching lines...) Expand all Loading... |
338 << "Max positive rendering delay error: " | 359 << "Max positive rendering delay error: " |
339 << audio_feeder_->max_positive_rendering_delay_error_us() | 360 << audio_feeder_->max_positive_rendering_delay_error_us() |
340 << "\nMax negative rendering delay error: " | 361 << "\nMax negative rendering delay error: " |
341 << audio_feeder_->max_negative_rendering_delay_error_us() | 362 << audio_feeder_->max_negative_rendering_delay_error_us() |
342 << "\nAverage rendering delay error: " | 363 << "\nAverage rendering delay error: " |
343 << audio_feeder_->average_rendering_delay_error_us(); | 364 << audio_feeder_->average_rendering_delay_error_us(); |
344 } | 365 } |
345 | 366 |
346 TEST_P(MultizoneBackendTest, RenderingDelay) { | 367 TEST_P(MultizoneBackendTest, RenderingDelay) { |
347 std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); | 368 std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| 369 const TestParams& params = GetParam(); |
| 370 int sample_rate = testing::get<0>(params); |
| 371 float playback_rate = testing::get<1>(params); |
348 | 372 |
349 Initialize(GetParam()); | 373 Initialize(sample_rate, playback_rate); |
350 AddEffectsStreams(); | 374 AddEffectsStreams(); |
351 Start(); | 375 Start(); |
352 base::RunLoop().Run(); | 376 base::RunLoop().Run(); |
353 } | 377 } |
354 | 378 |
355 INSTANTIATE_TEST_CASE_P(Required, | 379 INSTANTIATE_TEST_CASE_P( |
356 MultizoneBackendTest, | 380 Required, |
357 ::testing::Values(8000, | 381 MultizoneBackendTest, |
358 11025, | 382 testing::Combine(::testing::Values(8000, |
359 12000, | 383 11025, |
360 16000, | 384 12000, |
361 22050, | 385 16000, |
362 24000, | 386 22050, |
363 32000, | 387 24000, |
364 44100, | 388 32000, |
365 48000)); | 389 44100, |
| 390 48000), |
| 391 ::testing::Values(0.5f, 0.99f, 1.0f, 1.01f, 2.0f))); |
366 | 392 |
367 INSTANTIATE_TEST_CASE_P(Optional, | 393 INSTANTIATE_TEST_CASE_P( |
368 MultizoneBackendTest, | 394 Optional, |
369 ::testing::Values(64000, 88200, 96000)); | 395 MultizoneBackendTest, |
| 396 testing::Combine(::testing::Values(64000, 88200, 96000), |
| 397 ::testing::Values(0.5f, 0.99f, 1.0f, 1.01f, 2.0f))); |
370 | 398 |
371 } // namespace media | 399 } // namespace media |
372 } // namespace chromecast | 400 } // namespace chromecast |
OLD | NEW |