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

Side by Side Diff: chromecast/media/cma/backend/multizone_backend_unittest.cc

Issue 2074473002: [Chromecast] Aggregate errors in multizone backend test. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <limits> 9 #include <limits>
9 #include <memory> 10 #include <memory>
10 #include <vector> 11 #include <vector>
11 12
12 #include "base/bind.h" 13 #include "base/bind.h"
13 #include "base/command_line.h" 14 #include "base/command_line.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/memory/ref_counted.h" 16 #include "base/memory/ref_counted.h"
16 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
17 #include "base/threading/thread_checker.h" 18 #include "base/threading/thread_checker.h"
(...skipping 17 matching lines...) Expand all
35 class MultizoneBackendTest; 36 class MultizoneBackendTest;
36 37
37 namespace { 38 namespace {
38 39
39 const int64_t kMicrosecondsPerSecond = 1000 * 1000; 40 const int64_t kMicrosecondsPerSecond = 1000 * 1000;
40 // Total length of test, in microseconds. 41 // Total length of test, in microseconds.
41 const int64_t kPushTimeUs = 2 * kMicrosecondsPerSecond; 42 const int64_t kPushTimeUs = 2 * kMicrosecondsPerSecond;
42 const int64_t kStartPts = 0; 43 const int64_t kStartPts = 0;
43 const int64_t kRenderingDelayGracePeriodUs = 250 * 1000; 44 const int64_t kRenderingDelayGracePeriodUs = 250 * 1000;
44 const int64_t kMaxRenderingDelayErrorUs = 200; 45 const int64_t kMaxRenderingDelayErrorUs = 200;
45 const int kNumEffectsStreams = 3; 46 const int kNumEffectsStreams = 1;
46 47
47 void IgnoreEos() {} 48 void IgnoreEos() {}
48 49
49 class BufferFeeder : public MediaPipelineBackend::Decoder::Delegate { 50 class BufferFeeder : public MediaPipelineBackend::Decoder::Delegate {
50 public: 51 public:
51 BufferFeeder(const AudioConfig& config, 52 BufferFeeder(const AudioConfig& config,
52 bool effects_only, 53 bool effects_only,
53 const base::Closure& eos_cb); 54 const base::Closure& eos_cb);
54 ~BufferFeeder() override {} 55 ~BufferFeeder() override {}
55 56
56 void Initialize(); 57 void Initialize();
57 void Start(); 58 void Start();
58 void Stop(); 59 void Stop();
59 60
61 int64_t max_rendering_delay_error_us() {
62 return max_rendering_delay_error_us_;
63 }
64
65 int64_t max_positive_rendering_delay_error_us() {
66 return max_positive_rendering_delay_error_us_;
67 }
68
69 int64_t max_negative_rendering_delay_error_us() {
70 return max_negative_rendering_delay_error_us_;
71 }
72
73 int64_t average_rendering_delay_error_us() {
74 return average_rendering_delay_error_us_;
75 }
76
60 private: 77 private:
61 void FeedBuffer(); 78 void FeedBuffer();
62 79
63 // MediaPipelineBackend::Decoder::Delegate implementation: 80 // MediaPipelineBackend::Decoder::Delegate implementation:
64 void OnPushBufferComplete(MediaPipelineBackend::BufferStatus status) override; 81 void OnPushBufferComplete(MediaPipelineBackend::BufferStatus status) override;
65 void OnEndOfStream() override; 82 void OnEndOfStream() override;
66 void OnDecoderError() override { 83 void OnDecoderError() override {
67 DCHECK(thread_checker_.CalledOnValidThread()); 84 DCHECK(thread_checker_.CalledOnValidThread());
68 if (effects_only_) { 85 if (effects_only_) {
69 feeding_completed_ = true; 86 feeding_completed_ = true;
70 } else { 87 } else {
71 ASSERT_TRUE(false); 88 ASSERT_TRUE(false);
72 } 89 }
73 } 90 }
74 void OnKeyStatusChanged(const std::string& key_id, 91 void OnKeyStatusChanged(const std::string& key_id,
75 CastKeyStatus key_status, 92 CastKeyStatus key_status,
76 uint32_t system_code) override { 93 uint32_t system_code) override {
77 DCHECK(thread_checker_.CalledOnValidThread()); 94 DCHECK(thread_checker_.CalledOnValidThread());
78 ASSERT_TRUE(false); 95 ASSERT_TRUE(false);
79 } 96 }
80 void OnVideoResolutionChanged(const Size& size) override { 97 void OnVideoResolutionChanged(const Size& size) override {
81 DCHECK(thread_checker_.CalledOnValidThread()); 98 DCHECK(thread_checker_.CalledOnValidThread());
82 } 99 }
83 100
84 const AudioConfig config_; 101 const AudioConfig config_;
85 const bool effects_only_; 102 const bool effects_only_;
86 const base::Closure eos_cb_; 103 const base::Closure eos_cb_;
104 int64_t max_rendering_delay_error_us_;
105 int64_t max_positive_rendering_delay_error_us_;
106 int64_t max_negative_rendering_delay_error_us_;
107 int64_t average_rendering_delay_error_us_;
108 size_t sample_count_;
87 bool feeding_completed_; 109 bool feeding_completed_;
88 std::unique_ptr<TaskRunnerImpl> task_runner_; 110 std::unique_ptr<TaskRunnerImpl> task_runner_;
89 std::unique_ptr<MediaPipelineBackend> backend_; 111 std::unique_ptr<MediaPipelineBackend> backend_;
90 MediaPipelineBackend::AudioDecoder* decoder_; 112 MediaPipelineBackend::AudioDecoder* decoder_;
91 int64_t push_limit_us_; 113 int64_t push_limit_us_;
92 int64_t last_push_length_us_; 114 int64_t last_push_length_us_;
93 int64_t pushed_us_; 115 int64_t pushed_us_;
94 int64_t next_push_playback_timestamp_; 116 int64_t next_push_playback_timestamp_;
95 scoped_refptr<DecoderBufferBase> pending_buffer_; 117 scoped_refptr<DecoderBufferBase> pending_buffer_;
96 base::ThreadChecker thread_checker_; 118 base::ThreadChecker thread_checker_;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 }; 153 };
132 154
133 namespace { 155 namespace {
134 156
135 BufferFeeder::BufferFeeder(const AudioConfig& config, 157 BufferFeeder::BufferFeeder(const AudioConfig& config,
136 bool effects_only, 158 bool effects_only,
137 const base::Closure& eos_cb) 159 const base::Closure& eos_cb)
138 : config_(config), 160 : config_(config),
139 effects_only_(effects_only), 161 effects_only_(effects_only),
140 eos_cb_(eos_cb), 162 eos_cb_(eos_cb),
163 max_rendering_delay_error_us_(0),
164 max_positive_rendering_delay_error_us_(0),
165 max_negative_rendering_delay_error_us_(0),
166 average_rendering_delay_error_us_(0),
167 sample_count_(0),
141 feeding_completed_(false), 168 feeding_completed_(false),
142 task_runner_(new TaskRunnerImpl()), 169 task_runner_(new TaskRunnerImpl()),
143 decoder_(nullptr), 170 decoder_(nullptr),
144 push_limit_us_(effects_only_ ? 0 : kPushTimeUs), 171 push_limit_us_(effects_only_ ? 0 : kPushTimeUs),
145 last_push_length_us_(0), 172 last_push_length_us_(0),
146 pushed_us_(0), 173 pushed_us_(0),
147 next_push_playback_timestamp_(0) { 174 next_push_playback_timestamp_(0) {
148 CHECK(!eos_cb_.is_null()); 175 CHECK(!eos_cb_.is_null());
149 } 176 }
150 177
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 decoder_->GetRenderingDelay(); 248 decoder_->GetRenderingDelay();
222 int64_t expected_next_push_playback_timestamp = 249 int64_t expected_next_push_playback_timestamp =
223 next_push_playback_timestamp_ + last_push_length_us_; 250 next_push_playback_timestamp_ + last_push_length_us_;
224 next_push_playback_timestamp_ = 251 next_push_playback_timestamp_ =
225 delay.timestamp_microseconds + delay.delay_microseconds; 252 delay.timestamp_microseconds + delay.delay_microseconds;
226 // Check rendering delay accuracy only if we have pushed more than 253 // Check rendering delay accuracy only if we have pushed more than
227 // kRenderingDelayGracePeriodUs of data. 254 // kRenderingDelayGracePeriodUs of data.
228 if (pushed_us_ > kRenderingDelayGracePeriodUs) { 255 if (pushed_us_ > kRenderingDelayGracePeriodUs) {
229 int64_t error = 256 int64_t error =
230 next_push_playback_timestamp_ - expected_next_push_playback_timestamp; 257 next_push_playback_timestamp_ - expected_next_push_playback_timestamp;
231 EXPECT_LT(std::abs(error), kMaxRenderingDelayErrorUs) 258 max_rendering_delay_error_us_ =
232 << "Bad rendering delay after " << pushed_us_ << " us"; 259 std::max(max_rendering_delay_error_us_, std::abs(error));
260 average_rendering_delay_error_us_ =
kmackay 2016/06/15 20:26:48 Seems like it would be more accurate to maintain t
jameswest 2016/06/15 21:41:00 Done.
261 (average_rendering_delay_error_us_ * sample_count_ +
262 std::abs(error)) /
263 (sample_count_ + 1);
264 if (error >= 0) {
265 max_positive_rendering_delay_error_us_ =
266 std::max(max_positive_rendering_delay_error_us_, error);
267 } else {
268 max_negative_rendering_delay_error_us_ =
269 std::min(max_negative_rendering_delay_error_us_, error);
270 }
271 sample_count_++;
233 } 272 }
234 } 273 }
235 pushed_us_ += last_push_length_us_; 274 pushed_us_ += last_push_length_us_;
236 275
237 if (feeding_completed_) 276 if (feeding_completed_)
238 return; 277 return;
239 278
240 base::ThreadTaskRunnerHandle::Get()->PostTask( 279 base::ThreadTaskRunnerHandle::Get()->PostTask(
241 FROM_HERE, base::Bind(&BufferFeeder::FeedBuffer, base::Unretained(this))); 280 FROM_HERE, base::Bind(&BufferFeeder::FeedBuffer, base::Unretained(this)));
242 } 281 }
243 282
244 } // namespace 283 } // namespace
245 284
246 MultizoneBackendTest::MultizoneBackendTest() {} 285 MultizoneBackendTest::MultizoneBackendTest() {}
247 286
248 MultizoneBackendTest::~MultizoneBackendTest() {} 287 MultizoneBackendTest::~MultizoneBackendTest() {}
249 288
250 void MultizoneBackendTest::Initialize(int sample_rate) { 289 void MultizoneBackendTest::Initialize(int sample_rate) {
251 AudioConfig config; 290 AudioConfig config;
252 config.codec = kCodecPCM; 291 config.codec = kCodecPCM;
253 config.sample_format = kSampleFormatPlanarF32; 292 config.sample_format = kSampleFormatS32;
254 config.channel_number = 2; 293 config.channel_number = 2;
255 config.bytes_per_channel = 4; 294 config.bytes_per_channel = 4;
256 config.samples_per_second = sample_rate; 295 config.samples_per_second = sample_rate;
257 296
258 audio_feeder_.reset( 297 audio_feeder_.reset(
259 new BufferFeeder(config, false /* effects_only */, 298 new BufferFeeder(config, false /* effects_only */,
260 base::Bind(&MultizoneBackendTest::OnEndOfStream, 299 base::Bind(&MultizoneBackendTest::OnEndOfStream,
261 base::Unretained(this)))); 300 base::Unretained(this))));
262 audio_feeder_->Initialize(); 301 audio_feeder_->Initialize();
263 } 302 }
(...skipping 20 matching lines...) Expand all
284 CHECK(audio_feeder_); 323 CHECK(audio_feeder_);
285 audio_feeder_->Start(); 324 audio_feeder_->Start();
286 } 325 }
287 326
288 void MultizoneBackendTest::OnEndOfStream() { 327 void MultizoneBackendTest::OnEndOfStream() {
289 audio_feeder_->Stop(); 328 audio_feeder_->Stop();
290 for (auto& feeder : effects_feeders_) 329 for (auto& feeder : effects_feeders_)
291 feeder->Stop(); 330 feeder->Stop();
292 331
293 base::MessageLoop::current()->QuitWhenIdle(); 332 base::MessageLoop::current()->QuitWhenIdle();
333
334 EXPECT_LT(audio_feeder_->max_rendering_delay_error_us(),
335 kMaxRenderingDelayErrorUs)
336 << "Max positive rendering delay error: "
337 << audio_feeder_->max_positive_rendering_delay_error_us()
338 << "\nMax negative rendering delay error: "
339 << audio_feeder_->max_negative_rendering_delay_error_us()
340 << "\nAverage rendering delay error: "
341 << audio_feeder_->average_rendering_delay_error_us();
294 } 342 }
295 343
296 TEST_P(MultizoneBackendTest, RenderingDelay) { 344 TEST_P(MultizoneBackendTest, RenderingDelay) {
297 std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 345 std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
298 346
299 Initialize(GetParam()); 347 Initialize(GetParam());
300 AddEffectsStreams(); 348 AddEffectsStreams();
301 Start(); 349 Start();
302 message_loop->Run(); 350 message_loop->Run();
303 } 351 }
304 352
305 INSTANTIATE_TEST_CASE_P(Required, 353 INSTANTIATE_TEST_CASE_P(Required,
306 MultizoneBackendTest, 354 MultizoneBackendTest,
307 ::testing::Values(8000, 355 ::testing::Values(8000,
308 11025, 356 11025,
309 12000, 357 12000,
310 16000, 358 16000,
311 22050, 359 22050,
312 24000, 360 24000,
313 32000, 361 32000,
314 44100, 362 44100,
315 48000)); 363 48000));
316 364
317 INSTANTIATE_TEST_CASE_P(Optional, 365 INSTANTIATE_TEST_CASE_P(Optional,
318 MultizoneBackendTest, 366 MultizoneBackendTest,
319 ::testing::Values(64000, 88200, 96000)); 367 ::testing::Values(64000, 88200, 96000));
320 368
321 } // namespace media 369 } // namespace media
322 } // namespace chromecast 370 } // namespace chromecast
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698