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..2c5d23fb534be0631f1cbd15c5fdb9878fd4f1f5 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,49 @@ 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(); |
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(); |
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); |