Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: content/renderer/media/audio_track_recorder_unittest.cc

Issue 1579693006: MediaRecorder: support sampling rate adaption in AudioTrackRecorder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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 "content/renderer/media/audio_track_recorder.h" 5 #include "content/renderer/media/audio_track_recorder.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
(...skipping 20 matching lines...) Expand all
31 31
32 namespace { 32 namespace {
33 33
34 // Input audio format. 34 // Input audio format.
35 const media::AudioParameters::Format kDefaultInputFormat = 35 const media::AudioParameters::Format kDefaultInputFormat =
36 media::AudioParameters::AUDIO_PCM_LOW_LATENCY; 36 media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
37 const int kDefaultBitsPerSample = 16; 37 const int kDefaultBitsPerSample = 16;
38 const int kDefaultSampleRate = 48000; 38 const int kDefaultSampleRate = 48000;
39 // The |frames_per_buffer| field of AudioParameters is not used by ATR. 39 // The |frames_per_buffer| field of AudioParameters is not used by ATR.
40 const int kIgnoreFramesPerBuffer = 1; 40 const int kIgnoreFramesPerBuffer = 1;
41 const int kOpusMaxBufferDurationMS = 120; 41 const int kMediaStreamAudioTrackBufferDurationMs = 10;
42 42
43 const int kFramesPerBuffer =
44 kMediaStreamAudioTrackBufferDurationMs * kDefaultSampleRate / 1000;
43 } // namespace 45 } // namespace
44 46
45 namespace content { 47 namespace content {
46 48
47 ACTION_P(RunClosure, closure) { 49 ACTION_P(RunClosure, closure) {
48 closure.Run(); 50 closure.Run();
49 } 51 }
50 52
51 struct ATRTestParams { 53 struct ATRTestParams {
52 const media::AudioParameters::Format input_format; 54 const media::AudioParameters::Format input_format;
53 const media::ChannelLayout channel_layout; 55 const media::ChannelLayout channel_layout;
54 const int sample_rate; 56 const int sample_rate;
55 const int bits_per_sample; 57 const int bits_per_sample;
56 }; 58 };
57 59
58 const ATRTestParams kATRTestParams[] = { 60 const ATRTestParams kATRTestParams[] = {
59 // Equivalent to default settings: 61 // Equivalent to default settings:
60 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, /* input format */ 62 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, /* input format */
61 media::CHANNEL_LAYOUT_STEREO, /* channel layout */ 63 media::CHANNEL_LAYOUT_STEREO, /* channel layout */
62 kDefaultSampleRate, /* sample rate */ 64 kDefaultSampleRate, /* sample rate */
63 kDefaultBitsPerSample}, /* bits per sample */ 65 kDefaultBitsPerSample}, /* bits per sample */
64 // Change to mono: 66 // Change to mono:
65 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, 67 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
66 kDefaultSampleRate, kDefaultBitsPerSample}, 68 media::CHANNEL_LAYOUT_MONO,
69 kDefaultSampleRate,
70 kDefaultBitsPerSample},
67 // Different sampling rate as well: 71 // Different sampling rate as well:
68 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
69 24000, kDefaultBitsPerSample},
70 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 72 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
71 media::CHANNEL_LAYOUT_STEREO, 8000, kDefaultBitsPerSample}, 73 media::CHANNEL_LAYOUT_MONO,
74 24000,
75 kDefaultBitsPerSample},
76 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
77 media::CHANNEL_LAYOUT_STEREO,
78 8000,
79 kDefaultBitsPerSample},
80 // Using a non-default Opus sampling rate (48, 24, 16, 12, or 8 kHz).
81 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
82 media::CHANNEL_LAYOUT_MONO,
83 22050,
miu 2016/01/22 00:14:53 Note: Increasing the Opus frame duration (as I men
mcasas 2016/01/22 22:03:53 Acknowledged.
84 kDefaultBitsPerSample},
85 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
86 media::CHANNEL_LAYOUT_STEREO,
87 44100,
88 kDefaultBitsPerSample},
89 {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
90 media::CHANNEL_LAYOUT_STEREO,
91 96000,
92 kDefaultBitsPerSample},
72 }; 93 };
73 94
74 class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { 95 class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
75 public: 96 public:
76 // Initialize |first_params_| based on test parameters, and |second_params_| 97 // Initialize |first_params_| based on test parameters, and |second_params_|
77 // to always be the same thing. 98 // to always be the same thing.
78 AudioTrackRecorderTest() 99 AudioTrackRecorderTest()
79 : first_params_(GetParam().input_format, 100 : first_params_(GetParam().input_format,
80 GetParam().channel_layout, 101 GetParam().channel_layout,
81 GetParam().sample_rate, 102 GetParam().sample_rate,
(...skipping 14 matching lines...) Expand all
96 ResetDecoder(first_params_); 117 ResetDecoder(first_params_);
97 PrepareBlinkTrack(); 118 PrepareBlinkTrack();
98 audio_track_recorder_.reset(new AudioTrackRecorder( 119 audio_track_recorder_.reset(new AudioTrackRecorder(
99 blink_track_, base::Bind(&AudioTrackRecorderTest::OnEncodedAudio, 120 blink_track_, base::Bind(&AudioTrackRecorderTest::OnEncodedAudio,
100 base::Unretained(this)))); 121 base::Unretained(this))));
101 } 122 }
102 123
103 ~AudioTrackRecorderTest() { 124 ~AudioTrackRecorderTest() {
104 opus_decoder_destroy(opus_decoder_); 125 opus_decoder_destroy(opus_decoder_);
105 opus_decoder_ = nullptr; 126 opus_decoder_ = nullptr;
106 audio_track_recorder_.reset();
107 blink_track_.reset(); 127 blink_track_.reset();
108 blink::WebHeap::collectAllGarbageForTesting(); 128 blink::WebHeap::collectAllGarbageForTesting();
129 audio_track_recorder_.reset();
130 // Let the message loop run to finish destroying the recorder properly.
131 base::RunLoop().RunUntilIdle();
109 } 132 }
110 133
111 void ResetDecoder(const media::AudioParameters& params) { 134 void ResetDecoder(const media::AudioParameters& params) {
112 if (opus_decoder_) { 135 if (opus_decoder_) {
113 opus_decoder_destroy(opus_decoder_); 136 opus_decoder_destroy(opus_decoder_);
114 opus_decoder_ = nullptr; 137 opus_decoder_ = nullptr;
115 } 138 }
116 139
117 int error; 140 int error;
118 opus_decoder_ = 141 opus_decoder_ =
119 opus_decoder_create(params.sample_rate(), params.channels(), &error); 142 opus_decoder_create(kDefaultSampleRate, params.channels(), &error);
120 EXPECT_TRUE(error == OPUS_OK && opus_decoder_); 143 EXPECT_TRUE(error == OPUS_OK && opus_decoder_);
121 144
122 max_frames_per_buffer_ = 145 buffer_.reset(new float[kFramesPerBuffer * params.channels()]);
123 kOpusMaxBufferDurationMS * params.sample_rate() / 1000;
124 buffer_.reset(new float[max_frames_per_buffer_ * params.channels()]);
125 } 146 }
126 147
127 scoped_ptr<media::AudioBus> GetFirstSourceAudioBus() { 148 scoped_ptr<media::AudioBus> GetFirstSourceAudioBus() {
128 scoped_ptr<media::AudioBus> bus(media::AudioBus::Create( 149 scoped_ptr<media::AudioBus> bus(media::AudioBus::Create(
129 first_params_.channels(), 150 first_params_.channels(), first_params_.sample_rate() *
130 first_params_.sample_rate() * 151 kMediaStreamAudioTrackBufferDurationMs /
131 audio_track_recorder_->GetOpusBufferDuration( 152 1000));
132 first_params_.sample_rate()) /
133 1000));
134 first_source_.OnMoreData(bus.get(), 0, 0); 153 first_source_.OnMoreData(bus.get(), 0, 0);
135 return bus; 154 return bus;
136 } 155 }
137 scoped_ptr<media::AudioBus> GetSecondSourceAudioBus() { 156 scoped_ptr<media::AudioBus> GetSecondSourceAudioBus() {
138 scoped_ptr<media::AudioBus> bus(media::AudioBus::Create( 157 scoped_ptr<media::AudioBus> bus(media::AudioBus::Create(
139 second_params_.channels(), 158 second_params_.channels(), second_params_.sample_rate() *
140 second_params_.sample_rate() * 159 kMediaStreamAudioTrackBufferDurationMs /
141 audio_track_recorder_->GetOpusBufferDuration( 160 1000));
142 second_params_.sample_rate()) /
143 1000));
144 second_source_.OnMoreData(bus.get(), 0, 0); 161 second_source_.OnMoreData(bus.get(), 0, 0);
145 return bus; 162 return bus;
146 } 163 }
147 164
148 MOCK_METHOD3(DoOnEncodedAudio, 165 MOCK_METHOD3(DoOnEncodedAudio,
149 void(const media::AudioParameters& params, 166 void(const media::AudioParameters& params,
150 std::string encoded_data, 167 std::string encoded_data,
151 base::TimeTicks timestamp)); 168 base::TimeTicks timestamp));
152 169
153 void OnEncodedAudio(const media::AudioParameters& params, 170 void OnEncodedAudio(const media::AudioParameters& params,
154 scoped_ptr<std::string> encoded_data, 171 scoped_ptr<std::string> encoded_data,
155 base::TimeTicks timestamp) { 172 base::TimeTicks timestamp) {
156 EXPECT_TRUE(!encoded_data->empty()); 173 EXPECT_TRUE(!encoded_data->empty());
157
158 // Decode |encoded_data| and check we get the expected number of frames 174 // Decode |encoded_data| and check we get the expected number of frames
159 // per buffer. 175 // per buffer.
160 EXPECT_EQ( 176 EXPECT_EQ(
161 params.sample_rate() * 177 kDefaultSampleRate * kMediaStreamAudioTrackBufferDurationMs / 1000,
162 audio_track_recorder_->GetOpusBufferDuration(params.sample_rate()) /
163 1000,
164 opus_decode_float( 178 opus_decode_float(
165 opus_decoder_, 179 opus_decoder_,
166 reinterpret_cast<uint8_t*>(string_as_array(encoded_data.get())), 180 reinterpret_cast<uint8_t*>(string_as_array(encoded_data.get())),
167 encoded_data->size(), buffer_.get(), max_frames_per_buffer_, 0)); 181 encoded_data->size(), buffer_.get(), kFramesPerBuffer, 0));
168 182
169 DoOnEncodedAudio(params, *encoded_data, timestamp); 183 DoOnEncodedAudio(params, *encoded_data, timestamp);
170 } 184 }
171 185
172 const base::MessageLoop message_loop_; 186 const base::MessageLoop message_loop_;
173 187
174 // ATR and WebMediaStreamTrack for fooling it. 188 // ATR and WebMediaStreamTrack for fooling it.
175 scoped_ptr<AudioTrackRecorder> audio_track_recorder_; 189 scoped_ptr<AudioTrackRecorder> audio_track_recorder_;
176 blink::WebMediaStreamTrack blink_track_; 190 blink::WebMediaStreamTrack blink_track_;
177 191
178 // Two different sets of AudioParameters for testing re-init of ATR. 192 // Two different sets of AudioParameters for testing re-init of ATR.
179 const media::AudioParameters first_params_; 193 const media::AudioParameters first_params_;
180 const media::AudioParameters second_params_; 194 const media::AudioParameters second_params_;
181 195
182 // AudioSources for creating AudioBuses. 196 // AudioSources for creating AudioBuses.
183 media::SineWaveAudioSource first_source_; 197 media::SineWaveAudioSource first_source_;
184 media::SineWaveAudioSource second_source_; 198 media::SineWaveAudioSource second_source_;
185 199
186 // Decoder for verifying data was properly encoded. 200 // Decoder for verifying data was properly encoded.
187 OpusDecoder* opus_decoder_; 201 OpusDecoder* opus_decoder_;
188 int max_frames_per_buffer_;
189 scoped_ptr<float[]> buffer_; 202 scoped_ptr<float[]> buffer_;
190 203
191 private: 204 private:
192 // Prepares a blink track of a given MediaStreamType and attaches the native 205 // Prepares a blink track of a given MediaStreamType and attaches the native
193 // track, which can be used to capture audio data and pass it to the producer. 206 // track, which can be used to capture audio data and pass it to the producer.
194 // Adapted from media::WebRTCLocalAudioSourceProviderTest. 207 // Adapted from media::WebRTCLocalAudioSourceProviderTest.
195 void PrepareBlinkTrack() { 208 void PrepareBlinkTrack() {
196 MockMediaConstraintFactory constraint_factory; 209 MockMediaConstraintFactory constraint_factory;
197 scoped_refptr<WebRtcAudioCapturer> capturer( 210 scoped_refptr<WebRtcAudioCapturer> capturer(
198 WebRtcAudioCapturer::CreateCapturer( 211 WebRtcAudioCapturer::CreateCapturer(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 .WillOnce(RunClosure(quit_closure)); 260 .WillOnce(RunClosure(quit_closure));
248 audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), time3); 261 audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), time3);
249 262
250 run_loop.Run(); 263 run_loop.Run();
251 Mock::VerifyAndClearExpectations(this); 264 Mock::VerifyAndClearExpectations(this);
252 } 265 }
253 266
254 INSTANTIATE_TEST_CASE_P(, AudioTrackRecorderTest, ValuesIn(kATRTestParams)); 267 INSTANTIATE_TEST_CASE_P(, AudioTrackRecorderTest, ValuesIn(kATRTestParams));
255 268
256 } // namespace content 269 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698