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

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

Issue 1579693006: MediaRecorder: support sampling rate adaption in AudioTrackRecorder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: miu@s nit Created 4 years, 10 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
« no previous file with comments | « content/renderer/media/audio_track_recorder_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <stddef.h> 5 #include <stddef.h>
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "content/child/child_process.h" 10 #include "content/child/child_process.h"
11 #include "content/renderer/media/media_recorder_handler.h" 11 #include "content/renderer/media/media_recorder_handler.h"
12 #include "content/renderer/media/mock_media_stream_registry.h" 12 #include "content/renderer/media/mock_media_stream_registry.h"
13 #include "media/audio/simple_sources.h" 13 #include "media/audio/simple_sources.h"
14 #include "media/base/audio_bus.h" 14 #include "media/base/audio_bus.h"
15 #include "media/base/video_frame.h" 15 #include "media/base/video_frame.h"
16 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" 18 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h"
19 #include "third_party/WebKit/public/platform/WebString.h" 19 #include "third_party/WebKit/public/platform/WebString.h"
20 #include "third_party/WebKit/public/web/WebHeap.h" 20 #include "third_party/WebKit/public/web/WebHeap.h"
21 21
22 using ::testing::_; 22 using ::testing::_;
23 using ::testing::AtLeast; 23 using ::testing::AtLeast;
24 using ::testing::InSequence; 24 using ::testing::InSequence;
25 using ::testing::Gt;
25 using ::testing::Lt; 26 using ::testing::Lt;
26 using ::testing::Mock; 27 using ::testing::Mock;
27 using ::testing::TestWithParam; 28 using ::testing::TestWithParam;
28 using ::testing::ValuesIn; 29 using ::testing::ValuesIn;
29 30
30 using blink::WebString; 31 using blink::WebString;
31 32
32 namespace content { 33 namespace content {
33 34
34 ACTION_P(RunClosure, closure) { 35 ACTION_P(RunClosure, closure) {
35 closure.Run(); 36 closure.Run();
36 } 37 }
37 38
38 static const std::string kTestStreamUrl = "stream_url"; 39 static const std::string kTestStreamUrl = "stream_url";
39 static const std::string kTestVideoTrackId = "video_track_id"; 40 static const std::string kTestVideoTrackId = "video_track_id";
40 static const std::string kTestAudioTrackId = "audio_track_id"; 41 static const std::string kTestAudioTrackId = "audio_track_id";
41 static const int kTestAudioChannels = 2; 42 static const int kTestAudioChannels = 2;
42 static const int kTestAudioBitsPerSample = 16; 43 static const int kTestAudioBitsPerSample = 16;
43 static const int kTestAudioSampleRate = 48000; 44 static const int kTestAudioSampleRate = 48000;
44 static const int kTestAudioBufferDurationMS = 60; 45 static const int kTestAudioBufferDurationMs = 10;
46 // Opus works with 60ms buffers, so 6 MediaStreamAudioTrack Buffers are needed
47 // to encode one output buffer.
48 static const int kRatioOpusToTestAudioBuffers = 6;
45 49
46 struct MediaRecorderTestParams { 50 struct MediaRecorderTestParams {
47 const bool has_video; 51 const bool has_video;
48 const bool has_audio; 52 const bool has_audio;
49 const char* const mime_type; 53 const char* const mime_type;
50 const char* const codecs; 54 const char* const codecs;
51 const size_t first_encoded_video_frame_size;
52 const size_t second_encoded_video_frame_size;
53 const size_t first_encoded_audio_frame_size;
54 const size_t second_encoded_audio_frame_size;
55 }; 55 };
56 56
57 // Array of valid combinations of video/audio/codecs and expected collected 57 // Array of valid combinations of video/audio/codecs and expected collected
58 // encoded sizes to use for parameterizing MediaRecorderHandlerTest. 58 // encoded sizes to use for parameterizing MediaRecorderHandlerTest.
59 static const MediaRecorderTestParams kMediaRecorderTestParams[] = { 59 static const MediaRecorderTestParams kMediaRecorderTestParams[] = {
60 {true, false, "video/webm", "vp8", 52, 32, 0, 0}, 60 {true, false, "video/webm", "vp8"},
61 {true, false, "video/webm", "vp9", 33, 18, 0, 0}, 61 {true, false, "video/webm", "vp9"},
62 {false, true, "video/webm", "vp8", 0, 0, 990, 706}}; 62 {false, true, "video/webm", "vp8"}};
63 63
64 class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>, 64 class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>,
65 public blink::WebMediaRecorderHandlerClient { 65 public blink::WebMediaRecorderHandlerClient {
66 public: 66 public:
67 MediaRecorderHandlerTest() 67 MediaRecorderHandlerTest()
68 : media_recorder_handler_(new MediaRecorderHandler()), 68 : media_recorder_handler_(new MediaRecorderHandler()),
69 audio_source_(kTestAudioChannels, 69 audio_source_(kTestAudioChannels,
70 440 /* freq */, 70 440 /* freq */,
71 kTestAudioSampleRate) { 71 kTestAudioSampleRate) {
72 EXPECT_FALSE(media_recorder_handler_->recording_); 72 EXPECT_FALSE(media_recorder_handler_->recording_);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // Avoid issues with non-parameterized tests by calling this outside of ctr. 106 // Avoid issues with non-parameterized tests by calling this outside of ctr.
107 if (GetParam().has_video) 107 if (GetParam().has_video)
108 registry_.AddVideoTrack(kTestVideoTrackId); 108 registry_.AddVideoTrack(kTestVideoTrackId);
109 if (GetParam().has_audio) 109 if (GetParam().has_audio)
110 registry_.AddAudioTrack(kTestAudioTrackId); 110 registry_.AddAudioTrack(kTestAudioTrackId);
111 } 111 }
112 112
113 scoped_ptr<media::AudioBus> NextAudioBus() { 113 scoped_ptr<media::AudioBus> NextAudioBus() {
114 scoped_ptr<media::AudioBus> bus(media::AudioBus::Create( 114 scoped_ptr<media::AudioBus> bus(media::AudioBus::Create(
115 kTestAudioChannels, 115 kTestAudioChannels,
116 kTestAudioSampleRate * kTestAudioBufferDurationMS / 1000)); 116 kTestAudioSampleRate * kTestAudioBufferDurationMs / 1000));
117 audio_source_.OnMoreData(bus.get(), 0, 0); 117 audio_source_.OnMoreData(bus.get(), 0, 0);
118 return bus; 118 return bus;
119 } 119 }
120 120
121 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks 121 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
122 // and Sources in |registry_| into believing they are on the right threads. 122 // and Sources in |registry_| into believing they are on the right threads.
123 const base::MessageLoopForUI message_loop_; 123 const base::MessageLoopForUI message_loop_;
124 const ChildProcess child_process_; 124 const ChildProcess child_process_;
125 MockMediaStreamRegistry registry_; 125 MockMediaStreamRegistry registry_;
126 126
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type)); 214 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type));
215 const WebString codecs(base::UTF8ToUTF16(GetParam().codecs)); 215 const WebString codecs(base::UTF8ToUTF16(GetParam().codecs));
216 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(), 216 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(),
217 mime_type, codecs, 0, 0)); 217 mime_type, codecs, 0, 0));
218 EXPECT_TRUE(media_recorder_handler_->start()); 218 EXPECT_TRUE(media_recorder_handler_->start());
219 219
220 InSequence s; 220 InSequence s;
221 const scoped_refptr<media::VideoFrame> video_frame = 221 const scoped_refptr<media::VideoFrame> video_frame =
222 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80)); 222 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80));
223 223
224 const size_t kEncodedSizeThreshold = 16;
224 { 225 {
225 base::RunLoop run_loop; 226 base::RunLoop run_loop;
226 base::Closure quit_closure = run_loop.QuitClosure(); 227 base::Closure quit_closure = run_loop.QuitClosure();
227 // writeData() is pinged a number of times as the WebM header is written; 228 // writeData() is pinged a number of times as the WebM header is written;
228 // the last time it is called it has the encoded data. 229 // the last time it is called it has the encoded data.
229 const size_t encoded_data_size = GetParam().first_encoded_video_frame_size; 230 EXPECT_CALL(*this, writeData(_, Lt(kEncodedSizeThreshold), _))
230 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _))
231 .Times(AtLeast(1)); 231 .Times(AtLeast(1));
232 EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) 232 EXPECT_CALL(*this, writeData(_, Gt(kEncodedSizeThreshold), _))
233 .Times(1) 233 .Times(1)
234 .WillOnce(RunClosure(quit_closure)); 234 .WillOnce(RunClosure(quit_closure));
235 235
236 OnVideoFrameForTesting(video_frame); 236 OnVideoFrameForTesting(video_frame);
237 run_loop.Run(); 237 run_loop.Run();
238 } 238 }
239 Mock::VerifyAndClearExpectations(this);
239 240
240 { 241 {
241 base::RunLoop run_loop; 242 base::RunLoop run_loop;
242 base::Closure quit_closure = run_loop.QuitClosure(); 243 base::Closure quit_closure = run_loop.QuitClosure();
243 // The second time around writeData() is called a number of times to write 244 // The second time around writeData() is called a number of times to write
244 // the WebM frame header, and then is pinged with the encoded data. 245 // the WebM frame header, and then is pinged with the encoded data.
245 const size_t encoded_data_size = GetParam().second_encoded_video_frame_size; 246 EXPECT_CALL(*this, writeData(_, Lt(kEncodedSizeThreshold), _))
246 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _))
247 .Times(AtLeast(1)); 247 .Times(AtLeast(1));
248 EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) 248 EXPECT_CALL(*this, writeData(_, Gt(kEncodedSizeThreshold), _))
249 .Times(1) 249 .Times(1)
250 .WillOnce(RunClosure(quit_closure)); 250 .WillOnce(RunClosure(quit_closure));
251 251
252 OnVideoFrameForTesting(video_frame); 252 OnVideoFrameForTesting(video_frame);
253 run_loop.Run(); 253 run_loop.Run();
254 } 254 }
255 255
256 media_recorder_handler_->stop(); 256 media_recorder_handler_->stop();
257 257
258 // Expect a last call on destruction, with size 0 and |lastInSlice| true. 258 // Expect a last call on destruction, with size 0 and |lastInSlice| true.
(...skipping 18 matching lines...) Expand all
277 this, registry_.test_stream(), mime_type, WebString(), 0, 0)); 277 this, registry_.test_stream(), mime_type, WebString(), 0, 0));
278 EXPECT_TRUE(media_recorder_handler_->start()); 278 EXPECT_TRUE(media_recorder_handler_->start());
279 279
280 InSequence s; 280 InSequence s;
281 const scoped_ptr<media::AudioBus> audio_bus1 = NextAudioBus(); 281 const scoped_ptr<media::AudioBus> audio_bus1 = NextAudioBus();
282 const scoped_ptr<media::AudioBus> audio_bus2 = NextAudioBus(); 282 const scoped_ptr<media::AudioBus> audio_bus2 = NextAudioBus();
283 283
284 media::AudioParameters params( 284 media::AudioParameters params(
285 media::AudioParameters::AUDIO_PCM_LINEAR, media::CHANNEL_LAYOUT_STEREO, 285 media::AudioParameters::AUDIO_PCM_LINEAR, media::CHANNEL_LAYOUT_STEREO,
286 kTestAudioSampleRate, kTestAudioBitsPerSample, 286 kTestAudioSampleRate, kTestAudioBitsPerSample,
287 kTestAudioSampleRate * kTestAudioBufferDurationMS / 1000); 287 kTestAudioSampleRate * kTestAudioBufferDurationMs / 1000);
288 SetAudioFormatForTesting(params); 288 SetAudioFormatForTesting(params);
289 289
290 const size_t kEncodedSizeThreshold = 24;
290 { 291 {
291 base::RunLoop run_loop; 292 base::RunLoop run_loop;
292 base::Closure quit_closure = run_loop.QuitClosure(); 293 base::Closure quit_closure = run_loop.QuitClosure();
293 // writeData() is pinged a number of times as the WebM header is written; 294 // writeData() is pinged a number of times as the WebM header is written;
294 // the last time it is called it has the encoded data. 295 // the last time it is called it has the encoded data.
295 const size_t kEncodedDataSize = GetParam().first_encoded_audio_frame_size; 296 EXPECT_CALL(*this, writeData(_, Lt(kEncodedSizeThreshold), _))
296 EXPECT_CALL(*this, writeData(_, Lt(kEncodedDataSize), _)).Times(AtLeast(1)); 297 .Times(AtLeast(1));
297 EXPECT_CALL(*this, writeData(_, kEncodedDataSize, _)) 298 EXPECT_CALL(*this, writeData(_, Gt(kEncodedSizeThreshold), _))
298 .Times(1) 299 .Times(1)
299 .WillOnce(RunClosure(quit_closure)); 300 .WillOnce(RunClosure(quit_closure));
300 301
301 OnAudioBusForTesting(*audio_bus1); 302 for (int i = 0; i < kRatioOpusToTestAudioBuffers; ++i)
303 OnAudioBusForTesting(*audio_bus1);
302 run_loop.Run(); 304 run_loop.Run();
303 } 305 }
306 Mock::VerifyAndClearExpectations(this);
304 307
305 { 308 {
306 base::RunLoop run_loop; 309 base::RunLoop run_loop;
307 base::Closure quit_closure = run_loop.QuitClosure(); 310 base::Closure quit_closure = run_loop.QuitClosure();
308 // The second time around writeData() is called a number of times to write 311 // The second time around writeData() is called a number of times to write
309 // the WebM frame header, and then is pinged with the encoded data. 312 // the WebM frame header, and then is pinged with the encoded data.
310 const size_t kSecondEncodedDataSize = 313 EXPECT_CALL(*this, writeData(_, Lt(kEncodedSizeThreshold), _))
311 GetParam().second_encoded_audio_frame_size;
312 EXPECT_CALL(*this, writeData(_, Lt(kSecondEncodedDataSize), _))
313 .Times(AtLeast(1)); 314 .Times(AtLeast(1));
314 EXPECT_CALL(*this, writeData(_, kSecondEncodedDataSize, _)) 315 EXPECT_CALL(*this, writeData(_, Gt(kEncodedSizeThreshold), _))
315 .Times(1) 316 .Times(1)
316 .WillOnce(RunClosure(quit_closure)); 317 .WillOnce(RunClosure(quit_closure));
317 318
318 OnAudioBusForTesting(*audio_bus2); 319 for (int i = 0; i < kRatioOpusToTestAudioBuffers; ++i)
320 OnAudioBusForTesting(*audio_bus2);
319 run_loop.Run(); 321 run_loop.Run();
320 } 322 }
321 323
322 media_recorder_handler_->stop(); 324 media_recorder_handler_->stop();
323 325
324 // Expect a last call on destruction, with size 0 and |lastInSlice| true. 326 // Expect a last call on destruction, with size 0 and |lastInSlice| true.
325 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1); 327 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1);
326 media_recorder_handler_.reset(); 328 media_recorder_handler_.reset();
327 } 329 }
328 330
329 } // namespace content 331 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/audio_track_recorder_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698