Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/renderer/media/audio_track_recorder.h" | |
| 6 | |
| 7 #include "base/run_loop.h" | |
| 8 #include "base/strings/utf_string_conversions.h" | |
| 9 #include "content/renderer/media/media_stream_audio_source.h" | |
| 10 #include "content/renderer/media/mock_media_constraint_factory.h" | |
| 11 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" | |
| 12 #include "content/renderer/media/webrtc_local_audio_track.h" | |
| 13 #include "media/audio/simple_sources.h" | |
| 14 #include "testing/gmock/include/gmock/gmock.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 #include "third_party/WebKit/public/web/WebHeap.h" | |
| 17 | |
| 18 using ::testing::_; | |
| 19 using ::testing::DoAll; | |
| 20 using ::testing::InSequence; | |
| 21 using ::testing::Mock; | |
| 22 using ::testing::Return; | |
| 23 using ::testing::SaveArg; | |
| 24 using ::testing::TestWithParam; | |
| 25 using ::testing::ValuesIn; | |
| 26 | |
| 27 namespace { | |
| 28 | |
| 29 // Input audio format. | |
| 30 const media::AudioParameters::Format kDefaultInputFormat = | |
| 31 media::AudioParameters::AUDIO_PCM_LOW_LATENCY; | |
| 32 const int kDefaultBitsPerSample = 16; | |
| 33 const int kDefaultSamplingRate = 48000; | |
| 34 // The |frames_per_buffer| field of AudioParameters is not used by ATR. | |
| 35 const int kIgnoreFramesPerBuffer = 1; | |
| 36 | |
| 37 } // namespace | |
| 38 | |
| 39 namespace content { | |
| 40 | |
| 41 ACTION_P(RunClosure, closure) { | |
| 42 closure.Run(); | |
| 43 } | |
| 44 | |
| 45 struct ATRTestParams { | |
| 46 const media::AudioParameters::Format input_format; | |
| 47 const media::ChannelLayout channel_layout; | |
| 48 const int sample_rate; | |
| 49 const int bits_per_sample; | |
| 50 }; | |
| 51 | |
| 52 const ATRTestParams kATRTestParams[] = { | |
| 53 // Equivalent to default settings: | |
| 54 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, /* input format */ | |
| 55 media::CHANNEL_LAYOUT_STEREO, /* channel layout */ | |
| 56 48000, /* sample rate */ | |
|
mcasas
2015/11/13 00:25:46
Use |kDefaultSamplingRate|; the same
in l.60 and |
ajose
2015/11/14 04:36:52
Done.
| |
| 57 16 /* bits per sample */ }, | |
| 58 // Change to mono: | |
| 59 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | |
| 60 media::CHANNEL_LAYOUT_MONO, 48000, 16}, | |
| 61 // Different sampling rate as well: | |
| 62 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | |
| 63 media::CHANNEL_LAYOUT_MONO, 24000, 16}, | |
| 64 }; | |
| 65 | |
| 66 class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { | |
| 67 public: | |
| 68 // Initialize |first_params_| based on test parameters, and |second_params_| | |
| 69 // to always be the same thing. | |
| 70 AudioTrackRecorderTest() | |
| 71 : first_params_(GetParam().input_format, | |
| 72 GetParam().channel_layout, | |
| 73 GetParam().sample_rate, | |
| 74 GetParam().bits_per_sample, | |
| 75 kIgnoreFramesPerBuffer), | |
| 76 second_params_(kDefaultInputFormat, | |
| 77 media::CHANNEL_LAYOUT_STEREO, | |
| 78 kDefaultSamplingRate, | |
| 79 kDefaultBitsPerSample, | |
| 80 kIgnoreFramesPerBuffer), | |
| 81 first_source_(first_params_.channels(), /* # channels */ | |
| 82 440, /* frequency */ | |
| 83 first_params_.sample_rate() /* sample rate */ ), | |
| 84 second_source_(second_params_.channels(), | |
| 85 440, | |
| 86 second_params_.sample_rate()) { | |
| 87 PrepareBlinkTrack(); | |
| 88 audio_track_recorder_.reset(new AudioTrackRecorder( | |
| 89 blink_track_, base::Bind(&AudioTrackRecorderTest::OnEncodedAudio, | |
| 90 base::Unretained(this)))); | |
| 91 } | |
| 92 | |
| 93 ~AudioTrackRecorderTest() { | |
| 94 audio_track_recorder_.reset(); | |
| 95 blink_track_.reset(); | |
| 96 blink::WebHeap::collectAllGarbageForTesting(); | |
| 97 } | |
| 98 | |
| 99 // These return AudioBuses with more sample than strictly necessary, but | |
| 100 // ATR should be able to handle this. | |
| 101 scoped_ptr<media::AudioBus> GetFirstSourceAudioBus() { | |
| 102 scoped_ptr<media::AudioBus> bus( | |
| 103 media::AudioBus::Create(first_params_.channels(), | |
| 104 first_params_.sample_rate())); | |
| 105 first_source_.OnMoreData(bus.get(), 0); | |
| 106 return bus.Pass(); | |
| 107 } | |
| 108 scoped_ptr<media::AudioBus> GetSecondSourceAudioBus() { | |
| 109 scoped_ptr<media::AudioBus> bus( | |
| 110 media::AudioBus::Create(second_params_.channels(), | |
| 111 second_params_.sample_rate())); | |
| 112 second_source_.OnMoreData(bus.get(), 0); | |
| 113 return bus.Pass(); | |
| 114 } | |
| 115 | |
| 116 MOCK_METHOD3(DoOnEncodedAudio, | |
| 117 void(const media::AudioParameters& params, | |
| 118 std::string encoded_data, | |
| 119 base::TimeTicks timestamp)); | |
| 120 | |
| 121 void OnEncodedAudio(const media::AudioParameters& params, | |
| 122 scoped_ptr<std::string> encoded_data, | |
| 123 base::TimeTicks timestamp) { | |
| 124 EXPECT_TRUE(!encoded_data->empty()); | |
| 125 DoOnEncodedAudio(params, *encoded_data, timestamp); | |
| 126 } | |
| 127 | |
| 128 const base::MessageLoop message_loop_; | |
| 129 | |
| 130 // ATR and WebMediaStreamTrack for fooling it. | |
| 131 scoped_ptr<AudioTrackRecorder> audio_track_recorder_; | |
| 132 blink::WebMediaStreamTrack blink_track_; | |
| 133 | |
| 134 // Two different sets of AudioParameters for testing re-init of ATR. | |
| 135 const media::AudioParameters first_params_; | |
| 136 const media::AudioParameters second_params_; | |
| 137 | |
| 138 // AudioSources for creating AudioBuses. | |
| 139 media::SineWaveAudioSource first_source_; | |
| 140 media::SineWaveAudioSource second_source_; | |
| 141 | |
| 142 private: | |
| 143 // Prepares a blink track of a given MediaStreamType and attaches the native | |
| 144 // track, which can be used to capture audio data and pass it to the producer. | |
| 145 // Adapted from media::WebRTCLocalAudioSourceProviderTest. | |
| 146 void PrepareBlinkTrack() { | |
| 147 MockMediaConstraintFactory constraint_factory; | |
| 148 scoped_refptr<WebRtcAudioCapturer> capturer( | |
| 149 WebRtcAudioCapturer::CreateCapturer( | |
| 150 -1, StreamDeviceInfo(), | |
| 151 constraint_factory.CreateWebMediaConstraints(), NULL, NULL)); | |
| 152 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( | |
| 153 WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); | |
| 154 scoped_ptr<WebRtcLocalAudioTrack> native_track( | |
| 155 new WebRtcLocalAudioTrack(adapter.get(), capturer, NULL)); | |
| 156 blink::WebMediaStreamSource audio_source; | |
| 157 audio_source.initialize(base::UTF8ToUTF16("dummy_source_id"), | |
| 158 blink::WebMediaStreamSource::TypeAudio, | |
| 159 base::UTF8ToUTF16("dummy_source_name"), | |
| 160 false /* remote */, true /* readonly */); | |
| 161 blink_track_.initialize(blink::WebString::fromUTF8("audio_track"), | |
| 162 audio_source); | |
| 163 blink_track_.setExtraData(native_track.release()); | |
| 164 } | |
| 165 | |
| 166 DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorderTest); | |
| 167 }; | |
| 168 | |
| 169 TEST_P(AudioTrackRecorderTest, OnData) { | |
| 170 InSequence s; | |
| 171 base::RunLoop run_loop; | |
| 172 base::Closure quit_closure = run_loop.QuitClosure(); | |
| 173 | |
| 174 // Give ATR initial audio parameters. | |
| 175 audio_track_recorder_->OnSetFormat(first_params_); | |
| 176 // TODO(ajose): consider adding WillOnce(SaveArg...) and inspecting, as done | |
| 177 // in VTR unittests. http://crbug.com/548856 | |
| 178 const base::TimeTicks time1 = base::TimeTicks::Now(); | |
| 179 EXPECT_CALL(*this, DoOnEncodedAudio(_, _, time1)).Times(1); | |
| 180 audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time1); | |
| 181 | |
| 182 // Send more audio. | |
| 183 const base::TimeTicks time2 = base::TimeTicks::Now(); | |
| 184 EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)).Times(1); | |
| 185 audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time2); | |
| 186 | |
| 187 // Give ATR new audio parameters. | |
| 188 audio_track_recorder_->OnSetFormat(second_params_); | |
| 189 // Send audio with different params. | |
| 190 const base::TimeTicks time3 = base::TimeTicks::Now(); | |
| 191 EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)) | |
| 192 .Times(1) | |
| 193 .WillOnce(RunClosure(quit_closure)); | |
| 194 audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), time3); | |
| 195 | |
| 196 run_loop.Run(); | |
| 197 Mock::VerifyAndClearExpectations(this); | |
| 198 } | |
| 199 | |
| 200 INSTANTIATE_TEST_CASE_P(, | |
| 201 AudioTrackRecorderTest, | |
| 202 ValuesIn(kATRTestParams)); | |
| 203 | |
| 204 } // namespace content | |
| OLD | NEW |