| 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 "media/filters/audio_timestamp_validator.h" | 5 #include "media/filters/audio_timestamp_validator.h" |
| 6 | 6 |
| 7 #include <tuple> | 7 #include <tuple> |
| 8 | 8 |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "media/base/audio_decoder_config.h" | 10 #include "media/base/audio_decoder_config.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 // Params are: | 34 // Params are: |
| 35 // 1. Output delay: number of encoded buffers before first decoded output | 35 // 1. Output delay: number of encoded buffers before first decoded output |
| 36 // 2. Codec delay: number of frames of codec delay in decoder config | 36 // 2. Codec delay: number of frames of codec delay in decoder config |
| 37 // 3. Front discard: front discard for the first buffer | 37 // 3. Front discard: front discard for the first buffer |
| 38 using ValidatorTestParams = testing::tuple<int, int, base::TimeDelta>; | 38 using ValidatorTestParams = testing::tuple<int, int, base::TimeDelta>; |
| 39 | 39 |
| 40 class AudioTimestampValidatorTest | 40 class AudioTimestampValidatorTest |
| 41 : public testing::Test, | 41 : public testing::Test, |
| 42 public ::testing::WithParamInterface<ValidatorTestParams> { | 42 public ::testing::WithParamInterface<ValidatorTestParams> { |
| 43 public: | 43 public: |
| 44 AudioTimestampValidatorTest() | 44 AudioTimestampValidatorTest() {} |
| 45 : media_log_(new testing::StrictMock<MockMediaLog>()) {} | |
| 46 | 45 |
| 47 protected: | 46 protected: |
| 48 void SetUp() override { | 47 void SetUp() override { |
| 49 output_delay_ = testing::get<0>(GetParam()); | 48 output_delay_ = testing::get<0>(GetParam()); |
| 50 codec_delay_ = testing::get<1>(GetParam()); | 49 codec_delay_ = testing::get<1>(GetParam()); |
| 51 front_discard_ = testing::get<2>(GetParam()); | 50 front_discard_ = testing::get<2>(GetParam()); |
| 52 } | 51 } |
| 53 | 52 |
| 54 int output_delay_; | 53 int output_delay_; |
| 55 | 54 |
| 56 int codec_delay_; | 55 int codec_delay_; |
| 57 | 56 |
| 58 base::TimeDelta front_discard_; | 57 base::TimeDelta front_discard_; |
| 59 | 58 |
| 60 scoped_refptr<testing::StrictMock<MockMediaLog>> media_log_; | 59 testing::StrictMock<MockMediaLog> media_log_; |
| 61 }; | 60 }; |
| 62 | 61 |
| 63 TEST_P(AudioTimestampValidatorTest, WarnForEraticTimes) { | 62 TEST_P(AudioTimestampValidatorTest, WarnForEraticTimes) { |
| 64 AudioDecoderConfig decoder_config; | 63 AudioDecoderConfig decoder_config; |
| 65 decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, | 64 decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, |
| 66 kSamplesPerSecond, EmptyExtraData(), Unencrypted(), | 65 kSamplesPerSecond, EmptyExtraData(), Unencrypted(), |
| 67 kSeekPreroll, codec_delay_); | 66 kSeekPreroll, codec_delay_); |
| 68 | 67 |
| 69 // Validator should fail to stabilize pattern for timestamp expectations. | 68 // Validator should fail to stabilize pattern for timestamp expectations. |
| 70 EXPECT_MEDIA_LOG( | 69 EXPECT_MEDIA_LOG( |
| 71 HasSubstr("Failed to reconcile encoded audio times " | 70 HasSubstr("Failed to reconcile encoded audio times " |
| 72 "with decoded output.")); | 71 "with decoded output.")); |
| 73 | 72 |
| 74 // No gap warnings should be emitted because the timestamps expectations never | 73 // No gap warnings should be emitted because the timestamps expectations never |
| 75 // stabilized. | 74 // stabilized. |
| 76 EXPECT_MEDIA_LOG(HasSubstr("timestamp gap detected")).Times(0); | 75 EXPECT_MEDIA_LOG(HasSubstr("timestamp gap detected")).Times(0); |
| 77 | 76 |
| 78 AudioTimestampValidator validator(decoder_config, media_log_); | 77 AudioTimestampValidator validator(decoder_config, &media_log_); |
| 79 | 78 |
| 80 const base::TimeDelta kRandomOffsets[] = { | 79 const base::TimeDelta kRandomOffsets[] = { |
| 81 base::TimeDelta::FromMilliseconds(100), | 80 base::TimeDelta::FromMilliseconds(100), |
| 82 base::TimeDelta::FromMilliseconds(350)}; | 81 base::TimeDelta::FromMilliseconds(350)}; |
| 83 | 82 |
| 84 for (int i = 0; i < 100; ++i) { | 83 for (int i = 0; i < 100; ++i) { |
| 85 // Each buffer's timestamp is kBufferDuration from the previous buffer. | 84 // Each buffer's timestamp is kBufferDuration from the previous buffer. |
| 86 scoped_refptr<DecoderBuffer> encoded_buffer = new DecoderBuffer(0); | 85 scoped_refptr<DecoderBuffer> encoded_buffer = new DecoderBuffer(0); |
| 87 | 86 |
| 88 // Ping-pong between two random offsets to prevent validator from | 87 // Ping-pong between two random offsets to prevent validator from |
| (...skipping 27 matching lines...) Expand all Loading... |
| 116 kSeekPreroll, codec_delay_); | 115 kSeekPreroll, codec_delay_); |
| 117 | 116 |
| 118 // Validator should quickly stabilize pattern for timestamp expectations. | 117 // Validator should quickly stabilize pattern for timestamp expectations. |
| 119 EXPECT_MEDIA_LOG(HasSubstr("Failed to reconcile encoded audio times " | 118 EXPECT_MEDIA_LOG(HasSubstr("Failed to reconcile encoded audio times " |
| 120 "with decoded output.")) | 119 "with decoded output.")) |
| 121 .Times(0); | 120 .Times(0); |
| 122 | 121 |
| 123 // Expect no gap warnings for series of buffers with valid timestamps. | 122 // Expect no gap warnings for series of buffers with valid timestamps. |
| 124 EXPECT_MEDIA_LOG(HasSubstr("timestamp gap detected")).Times(0); | 123 EXPECT_MEDIA_LOG(HasSubstr("timestamp gap detected")).Times(0); |
| 125 | 124 |
| 126 AudioTimestampValidator validator(decoder_config, media_log_); | 125 AudioTimestampValidator validator(decoder_config, &media_log_); |
| 127 | 126 |
| 128 for (int i = 0; i < 100; ++i) { | 127 for (int i = 0; i < 100; ++i) { |
| 129 // Each buffer's timestamp is kBufferDuration from the previous buffer. | 128 // Each buffer's timestamp is kBufferDuration from the previous buffer. |
| 130 scoped_refptr<DecoderBuffer> encoded_buffer = new DecoderBuffer(0); | 129 scoped_refptr<DecoderBuffer> encoded_buffer = new DecoderBuffer(0); |
| 131 encoded_buffer->set_timestamp(i * kBufferDuration); | 130 encoded_buffer->set_timestamp(i * kBufferDuration); |
| 132 | 131 |
| 133 if (i == 0) { | 132 if (i == 0) { |
| 134 encoded_buffer->set_discard_padding( | 133 encoded_buffer->set_discard_padding( |
| 135 std::make_pair(front_discard_, base::TimeDelta())); | 134 std::make_pair(front_discard_, base::TimeDelta())); |
| 136 } | 135 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 147 } | 146 } |
| 148 } | 147 } |
| 149 } | 148 } |
| 150 | 149 |
| 151 TEST_P(AudioTimestampValidatorTest, SingleWarnForSingleLargeGap) { | 150 TEST_P(AudioTimestampValidatorTest, SingleWarnForSingleLargeGap) { |
| 152 AudioDecoderConfig decoder_config; | 151 AudioDecoderConfig decoder_config; |
| 153 decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, | 152 decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, |
| 154 kSamplesPerSecond, EmptyExtraData(), Unencrypted(), | 153 kSamplesPerSecond, EmptyExtraData(), Unencrypted(), |
| 155 kSeekPreroll, codec_delay_); | 154 kSeekPreroll, codec_delay_); |
| 156 | 155 |
| 157 AudioTimestampValidator validator(decoder_config, media_log_); | 156 AudioTimestampValidator validator(decoder_config, &media_log_); |
| 158 | 157 |
| 159 // Validator should quickly stabilize pattern for timestamp expectations. | 158 // Validator should quickly stabilize pattern for timestamp expectations. |
| 160 EXPECT_MEDIA_LOG(HasSubstr("Failed to reconcile encoded audio times " | 159 EXPECT_MEDIA_LOG(HasSubstr("Failed to reconcile encoded audio times " |
| 161 "with decoded output.")) | 160 "with decoded output.")) |
| 162 .Times(0); | 161 .Times(0); |
| 163 | 162 |
| 164 for (int i = 0; i < 100; ++i) { | 163 for (int i = 0; i < 100; ++i) { |
| 165 // Halfway through the stream, introduce sudden gap of 50 milliseconds. | 164 // Halfway through the stream, introduce sudden gap of 50 milliseconds. |
| 166 base::TimeDelta offset; | 165 base::TimeDelta offset; |
| 167 if (i >= 50) | 166 if (i >= 50) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 192 } | 191 } |
| 193 } | 192 } |
| 194 } | 193 } |
| 195 | 194 |
| 196 TEST_P(AudioTimestampValidatorTest, RepeatedWarnForSlowAccumulatingDrift) { | 195 TEST_P(AudioTimestampValidatorTest, RepeatedWarnForSlowAccumulatingDrift) { |
| 197 AudioDecoderConfig decoder_config; | 196 AudioDecoderConfig decoder_config; |
| 198 decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, | 197 decoder_config.Initialize(kCodec, kSampleFormat, kChannelLayout, |
| 199 kSamplesPerSecond, EmptyExtraData(), Unencrypted(), | 198 kSamplesPerSecond, EmptyExtraData(), Unencrypted(), |
| 200 kSeekPreroll, codec_delay_); | 199 kSeekPreroll, codec_delay_); |
| 201 | 200 |
| 202 AudioTimestampValidator validator(decoder_config, media_log_); | 201 AudioTimestampValidator validator(decoder_config, &media_log_); |
| 203 | 202 |
| 204 EXPECT_MEDIA_LOG(HasSubstr("Failed to reconcile encoded audio times " | 203 EXPECT_MEDIA_LOG(HasSubstr("Failed to reconcile encoded audio times " |
| 205 "with decoded output.")) | 204 "with decoded output.")) |
| 206 .Times(0); | 205 .Times(0); |
| 207 | 206 |
| 208 for (int i = 0; i < 100; ++i) { | 207 for (int i = 0; i < 100; ++i) { |
| 209 // Wait for delayed output to begin plus an additional two iterations to | 208 // Wait for delayed output to begin plus an additional two iterations to |
| 210 // start using drift offset. The the two iterations without offset will | 209 // start using drift offset. The the two iterations without offset will |
| 211 // allow the validator to stabilize the pattern of timestamps and begin | 210 // allow the validator to stabilize the pattern of timestamps and begin |
| 212 // checking for gaps. Once stable, increase offset by 1 millisecond for each | 211 // checking for gaps. Once stable, increase offset by 1 millisecond for each |
| (...skipping 30 matching lines...) Expand all Loading... |
| 243 INSTANTIATE_TEST_CASE_P( | 242 INSTANTIATE_TEST_CASE_P( |
| 244 , | 243 , |
| 245 AudioTimestampValidatorTest, | 244 AudioTimestampValidatorTest, |
| 246 ::testing::Combine( | 245 ::testing::Combine( |
| 247 ::testing::Values(0, 10), // output delay | 246 ::testing::Values(0, 10), // output delay |
| 248 ::testing::Values(0, 512), // codec delay | 247 ::testing::Values(0, 512), // codec delay |
| 249 ::testing::Values(base::TimeDelta(), // front discard | 248 ::testing::Values(base::TimeDelta(), // front discard |
| 250 base::TimeDelta::FromMilliseconds(65)))); | 249 base::TimeDelta::FromMilliseconds(65)))); |
| 251 | 250 |
| 252 } // namespace media | 251 } // namespace media |
| OLD | NEW |