Chromium Code Reviews| Index: content/renderer/media/audio_track_recorder_unittest.cc |
| diff --git a/content/renderer/media/audio_track_recorder_unittest.cc b/content/renderer/media/audio_track_recorder_unittest.cc |
| index 07c0b5339e3ca15da2a6ac228eec662ccb14655c..7a7564dc6d82ada8b9baa0f910e655fa3254b77a 100644 |
| --- a/content/renderer/media/audio_track_recorder_unittest.cc |
| +++ b/content/renderer/media/audio_track_recorder_unittest.cc |
| @@ -31,14 +31,19 @@ using ::testing::ValuesIn; |
| namespace { |
| -// Input audio format. |
| -const media::AudioParameters::Format kDefaultInputFormat = |
| - media::AudioParameters::AUDIO_PCM_LOW_LATENCY; |
| const int kDefaultBitsPerSample = 16; |
| const int kDefaultSampleRate = 48000; |
| // The |frames_per_buffer| field of AudioParameters is not used by ATR. |
| const int kIgnoreFramesPerBuffer = 1; |
| -const int kOpusMaxBufferDurationMS = 120; |
| + |
| +// The following parameters replicate those in audio_track_recorder.cc, see this |
| +// file for explanations. |
| +const int kMediaStreamAudioTrackBufferDurationMs = 10; |
| +const int kOpusBufferDurationMs = 60; |
| +const int kRatioInputToOutputFrames = |
| + kOpusBufferDurationMs / kMediaStreamAudioTrackBufferDurationMs; |
| + |
| +const int kFramesPerBuffer = kOpusBufferDurationMs * kDefaultSampleRate / 1000; |
| } // namespace |
| @@ -62,13 +67,32 @@ const ATRTestParams kATRTestParams[] = { |
| kDefaultSampleRate, /* sample rate */ |
| kDefaultBitsPerSample}, /* bits per sample */ |
| // Change to mono: |
| - {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, |
| - kDefaultSampleRate, kDefaultBitsPerSample}, |
| + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| + media::CHANNEL_LAYOUT_MONO, |
| + kDefaultSampleRate, |
| + kDefaultBitsPerSample}, |
| // Different sampling rate as well: |
| - {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, |
| - 24000, kDefaultBitsPerSample}, |
| {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| - media::CHANNEL_LAYOUT_STEREO, 8000, kDefaultBitsPerSample}, |
| + media::CHANNEL_LAYOUT_MONO, |
| + 24000, |
| + kDefaultBitsPerSample}, |
| + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| + media::CHANNEL_LAYOUT_STEREO, |
| + 8000, |
| + kDefaultBitsPerSample}, |
| + // Using a non-default Opus sampling rate (48, 24, 16, 12, or 8 kHz). |
| + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| + media::CHANNEL_LAYOUT_MONO, |
| + 22050, |
| + kDefaultBitsPerSample}, |
| + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| + media::CHANNEL_LAYOUT_STEREO, |
| + 44100, |
| + kDefaultBitsPerSample}, |
| + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| + media::CHANNEL_LAYOUT_STEREO, |
| + 96000, |
| + kDefaultBitsPerSample}, |
| }; |
| class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { |
| @@ -81,7 +105,7 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { |
| GetParam().sample_rate, |
| GetParam().bits_per_sample, |
| kIgnoreFramesPerBuffer), |
| - second_params_(kDefaultInputFormat, |
| + second_params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| media::CHANNEL_LAYOUT_STEREO, |
| kDefaultSampleRate, |
| kDefaultBitsPerSample, |
| @@ -104,9 +128,11 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { |
| ~AudioTrackRecorderTest() { |
| opus_decoder_destroy(opus_decoder_); |
| opus_decoder_ = nullptr; |
| - audio_track_recorder_.reset(); |
| blink_track_.reset(); |
| blink::WebHeap::collectAllGarbageForTesting(); |
| + audio_track_recorder_.reset(); |
| + // Let the message loop run to finish destroying the recorder properly. |
| + base::RunLoop().RunUntilIdle(); |
| } |
| void ResetDecoder(const media::AudioParameters& params) { |
| @@ -117,31 +143,25 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { |
| int error; |
| opus_decoder_ = |
| - opus_decoder_create(params.sample_rate(), params.channels(), &error); |
| + opus_decoder_create(kDefaultSampleRate, params.channels(), &error); |
| EXPECT_TRUE(error == OPUS_OK && opus_decoder_); |
| - max_frames_per_buffer_ = |
| - kOpusMaxBufferDurationMS * params.sample_rate() / 1000; |
| - buffer_.reset(new float[max_frames_per_buffer_ * params.channels()]); |
| + buffer_.reset(new float[kFramesPerBuffer * params.channels()]); |
| } |
| scoped_ptr<media::AudioBus> GetFirstSourceAudioBus() { |
| scoped_ptr<media::AudioBus> bus(media::AudioBus::Create( |
| - first_params_.channels(), |
| - first_params_.sample_rate() * |
| - audio_track_recorder_->GetOpusBufferDuration( |
| - first_params_.sample_rate()) / |
| - 1000)); |
| + first_params_.channels(), first_params_.sample_rate() * |
| + kMediaStreamAudioTrackBufferDurationMs / |
| + base::Time::kMillisecondsPerSecond)); |
| first_source_.OnMoreData(bus.get(), 0, 0); |
| return bus; |
| } |
| scoped_ptr<media::AudioBus> GetSecondSourceAudioBus() { |
| scoped_ptr<media::AudioBus> bus(media::AudioBus::Create( |
| - second_params_.channels(), |
| - second_params_.sample_rate() * |
| - audio_track_recorder_->GetOpusBufferDuration( |
| - second_params_.sample_rate()) / |
| - 1000)); |
| + second_params_.channels(), second_params_.sample_rate() * |
| + kMediaStreamAudioTrackBufferDurationMs / |
| + base::Time::kMillisecondsPerSecond)); |
| second_source_.OnMoreData(bus.get(), 0, 0); |
| return bus; |
| } |
| @@ -155,17 +175,13 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { |
| scoped_ptr<std::string> encoded_data, |
| base::TimeTicks timestamp) { |
| EXPECT_TRUE(!encoded_data->empty()); |
| - |
| // Decode |encoded_data| and check we get the expected number of frames |
| // per buffer. |
| - EXPECT_EQ( |
| - params.sample_rate() * |
| - audio_track_recorder_->GetOpusBufferDuration(params.sample_rate()) / |
| - 1000, |
| - opus_decode_float( |
| - opus_decoder_, |
| - reinterpret_cast<uint8_t*>(string_as_array(encoded_data.get())), |
| - encoded_data->size(), buffer_.get(), max_frames_per_buffer_, 0)); |
| + EXPECT_EQ(kDefaultSampleRate * kOpusBufferDurationMs / 1000, |
| + opus_decode_float( |
| + opus_decoder_, reinterpret_cast<uint8_t*>( |
| + string_as_array(encoded_data.get())), |
| + encoded_data->size(), buffer_.get(), kFramesPerBuffer, 0)); |
| DoOnEncodedAudio(params, *encoded_data, timestamp); |
| } |
| @@ -186,7 +202,6 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { |
| // Decoder for verifying data was properly encoded. |
| OpusDecoder* opus_decoder_; |
| - int max_frames_per_buffer_; |
| scoped_ptr<float[]> buffer_; |
| private: |
| @@ -223,30 +238,50 @@ TEST_P(AudioTrackRecorderTest, OnData) { |
| // Give ATR initial audio parameters. |
| audio_track_recorder_->OnSetFormat(first_params_); |
| + |
| // TODO(ajose): consider adding WillOnce(SaveArg...) and inspecting, as done |
| // in VTR unittests. http://crbug.com/548856 |
| - const base::TimeTicks time1 = base::TimeTicks::Now(); |
| - EXPECT_CALL(*this, DoOnEncodedAudio(_, _, time1)).Times(1); |
| - audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time1); |
| + EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)).Times(1); |
| + audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), |
| + base::TimeTicks::Now()); |
| + for (int i = 0; i < kRatioInputToOutputFrames - 1; ++i) { |
| + audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), |
| + base::TimeTicks::Now()); |
| + } |
| - // Send more audio. |
| - const base::TimeTicks time2 = base::TimeTicks::Now(); |
| + // Send more audio. Expect the first OnDaata() timestamp. |
|
miu
2016/01/29 02:37:15
s/OnDaata/OnData/
mcasas
2016/01/29 20:37:34
Done. Actually, comment removed.
|
| EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)) |
| .Times(1) |
| // Only reset the decoder once we've heard back: |
| .WillOnce(RunClosure(base::Bind(&AudioTrackRecorderTest::ResetDecoder, |
| base::Unretained(this), second_params_))); |
| - audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time2); |
| + audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), |
| + base::TimeTicks::Now()); |
| + for (int i = 0; i < kRatioInputToOutputFrames - 1; ++i) { |
| + audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), |
| + base::TimeTicks::Now()); |
| + } |
| + |
| + // If the amount of samples/10ms buffer is not an integer (e.g. 22050Hz) we |
| + // need an extra OnData() to account for the round-off error. |
| + if (GetParam().sample_rate % 100) { |
| + audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), |
| + base::TimeTicks::Now()); |
| + } |
| // Give ATR new audio parameters. |
| audio_track_recorder_->OnSetFormat(second_params_); |
| - // Send audio with different params. |
| - const base::TimeTicks time3 = base::TimeTicks::Now(); |
| + // Send audio with different params. Expect the first OnData() timestamp. |
| EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)) |
| .Times(1) |
| .WillOnce(RunClosure(quit_closure)); |
| - audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), time3); |
| + audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), |
| + base::TimeTicks::Now()); |
| + for (int i = 0; i < kRatioInputToOutputFrames - 1; ++i) { |
| + audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), |
| + base::TimeTicks::Now()); |
| + } |
| run_loop.Run(); |
| Mock::VerifyAndClearExpectations(this); |