| 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);
|
|
|