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

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

Issue 1407083006: Update MediaRecorderHandler to use AudioTrackRecorder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mcasas@'s comments Created 5 years, 1 month 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 "base/run_loop.h" 5 #include "base/run_loop.h"
6 #include "base/strings/utf_string_conversions.h" 6 #include "base/strings/utf_string_conversions.h"
7 #include "content/child/child_process.h" 7 #include "content/child/child_process.h"
8 #include "content/renderer/media/media_recorder_handler.h" 8 #include "content/renderer/media/media_recorder_handler.h"
9 #include "content/renderer/media/mock_media_stream_registry.h" 9 #include "content/renderer/media/mock_media_stream_registry.h"
10 #include "media/audio/simple_sources.h"
11 #include "media/base/audio_bus.h"
10 #include "media/base/video_frame.h" 12 #include "media/base/video_frame.h"
11 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" 15 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h"
14 #include "third_party/WebKit/public/platform/WebString.h" 16 #include "third_party/WebKit/public/platform/WebString.h"
15 #include "third_party/WebKit/public/web/WebHeap.h" 17 #include "third_party/WebKit/public/web/WebHeap.h"
16 18
17 using ::testing::_; 19 using ::testing::_;
18 using ::testing::AtLeast; 20 using ::testing::AtLeast;
19 using ::testing::InSequence; 21 using ::testing::InSequence;
20 using ::testing::Lt; 22 using ::testing::Lt;
21 using ::testing::Mock; 23 using ::testing::Mock;
22 using ::testing::TestWithParam; 24 using ::testing::TestWithParam;
23 using ::testing::ValuesIn; 25 using ::testing::ValuesIn;
24 26
25 using blink::WebString; 27 using blink::WebString;
26 28
27 namespace content { 29 namespace content {
28 30
29 ACTION_P(RunClosure, closure) { 31 ACTION_P(RunClosure, closure) {
30 closure.Run(); 32 closure.Run();
31 } 33 }
32 34
33 static const std::string kTestStreamUrl = "stream_url"; 35 static const std::string kTestStreamUrl = "stream_url";
34 static const std::string kTestVideoTrackId = "video_track_id"; 36 static const std::string kTestVideoTrackId = "video_track_id";
37 static const std::string kTestAudioTrackId = "audio_track_id";
38 static const int kTestAudioChannels = 2;
39 static const int kTestAudioBitsPerSample = 16;
40 static const int kTestAudioSampleRate = 48000;
41 static const int kTestAudioBufferDurationMS = 60;
35 42
36 struct MediaRecorderTestParams { 43 struct MediaRecorderTestParams {
44 const bool has_video;
45 const bool has_audio;
37 const char* const mime_type; 46 const char* const mime_type;
38 const size_t first_encoded_frame_size; 47 const size_t first_encoded_video_frame_size;
39 const size_t second_encoded_frame_size; 48 const size_t second_encoded_video_frame_size;
49 const size_t first_encoded_audio_frame_size;
50 const size_t second_encoded_audio_frame_size;
40 }; 51 };
41 52
42 static const MediaRecorderTestParams kMediaRecorderTestParams[] = { 53 static const MediaRecorderTestParams kMediaRecorderTestParams[] = {
43 {"video/vp8", 52, 32}, 54 {true, false, "video/vp8", 52, 32, 0, 0},
44 {"video/vp9", 33, 18}}; 55 {true, false, "video/vp9", 33, 18, 0, 0},
56 {false, true, "video/vp8", 0, 0, 990, 706}};
45 57
46 class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>, 58 class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>,
47 public blink::WebMediaRecorderHandlerClient { 59 public blink::WebMediaRecorderHandlerClient {
48 public: 60 public:
49 MediaRecorderHandlerTest() 61 MediaRecorderHandlerTest()
50 : media_recorder_handler_(new MediaRecorderHandler()) { 62 : media_recorder_handler_(new MediaRecorderHandler()),
63 audio_source_(kTestAudioChannels,
64 440 /* freq */,
65 kTestAudioSampleRate) {
51 EXPECT_FALSE(media_recorder_handler_->recording_); 66 EXPECT_FALSE(media_recorder_handler_->recording_);
52 67
53 registry_.Init(kTestStreamUrl); 68 registry_.Init(kTestStreamUrl);
54 registry_.AddVideoTrack(kTestVideoTrackId);
55 } 69 }
56 70
57 ~MediaRecorderHandlerTest() { 71 ~MediaRecorderHandlerTest() {
58 registry_.reset(); 72 registry_.reset();
59 blink::WebHeap::collectAllGarbageForTesting(); 73 blink::WebHeap::collectAllGarbageForTesting();
60 } 74 }
61 75
62 MOCK_METHOD3(writeData, void(const char*, size_t, bool)); 76 MOCK_METHOD3(writeData, void(const char*, size_t, bool));
63 MOCK_METHOD1(failOutOfMemory, void(const WebString& message)); 77 MOCK_METHOD1(failOutOfMemory, void(const WebString& message));
64 MOCK_METHOD1(failIllegalStreamModification, void(const WebString& message)); 78 MOCK_METHOD1(failIllegalStreamModification, void(const WebString& message));
65 MOCK_METHOD1(failOtherRecordingError, void(const WebString& message)); 79 MOCK_METHOD1(failOtherRecordingError, void(const WebString& message));
66 80
67 bool recording() const { return media_recorder_handler_->recording_; } 81 bool recording() const { return media_recorder_handler_->recording_; }
68 bool hasVideoRecorders() const { 82 bool hasVideoRecorders() const {
69 return !media_recorder_handler_->video_recorders_.empty(); 83 return !media_recorder_handler_->video_recorders_.empty();
70 } 84 }
85 bool hasAudioRecorders() const {
86 return !media_recorder_handler_->audio_recorders_.empty();
87 }
71 88
72 void OnVideoFrameForTesting(const scoped_refptr<media::VideoFrame>& frame) { 89 void OnVideoFrameForTesting(const scoped_refptr<media::VideoFrame>& frame) {
73 media_recorder_handler_->OnVideoFrameForTesting(frame, 90 media_recorder_handler_->OnVideoFrameForTesting(frame,
74 base::TimeTicks::Now()); 91 base::TimeTicks::Now());
75 } 92 }
93 void OnAudioBusForTesting(const media::AudioBus& audio_bus) {
94 media_recorder_handler_->OnAudioBusForTesting(audio_bus,
95 base::TimeTicks::Now());
96 }
97 void SetAudioFormatForTesting(const media::AudioParameters& params) {
98 media_recorder_handler_->SetAudioFormatForTesting(params);
99 }
100
101 void AddTracks() {
102 // Avoid issues with non-parameterized tests by calling this outside of ctr.
103 if (GetParam().has_video)
104 registry_.AddVideoTrack(kTestVideoTrackId);
105 if (GetParam().has_audio)
106 registry_.AddAudioTrack(kTestAudioTrackId);
107 }
108
109 scoped_ptr<media::AudioBus> NextAudioBus() {
110 scoped_ptr<media::AudioBus> bus(media::AudioBus::Create(
111 kTestAudioChannels,
112 kTestAudioSampleRate * kTestAudioBufferDurationMS / 1000));
113 audio_source_.OnMoreData(bus.get(), 0);
114 return bus.Pass();
115 }
76 116
77 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks 117 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
78 // and Sources in |registry_| into believing they are on the right threads. 118 // and Sources in |registry_| into believing they are on the right threads.
79 const base::MessageLoopForUI message_loop_; 119 const base::MessageLoopForUI message_loop_;
80 const ChildProcess child_process_; 120 const ChildProcess child_process_;
81 MockMediaStreamRegistry registry_; 121 MockMediaStreamRegistry registry_;
82 122
83 // The Class under test. Needs to be scoped_ptr to force its destruction. 123 // The Class under test. Needs to be scoped_ptr to force its destruction.
84 scoped_ptr<MediaRecorderHandler> media_recorder_handler_; 124 scoped_ptr<MediaRecorderHandler> media_recorder_handler_;
85 125
126 // For generating test AudioBuses
127 media::SineWaveAudioSource audio_source_;
128
86 private: 129 private:
87 DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandlerTest); 130 DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandlerTest);
88 }; 131 };
89 132
90 // Checks that canSupportMimeType() works as expected. 133 // Checks that canSupportMimeType() works as expected.
91 // TODO(mcasas): revisit this when canSupportMimeType() is fully implemented. 134 // TODO(mcasas): revisit this when canSupportMimeType() is fully implemented.
92 TEST_F(MediaRecorderHandlerTest, CanSupportMimeType) { 135 TEST_F(MediaRecorderHandlerTest, CanSupportMimeType) {
93 const WebString good_mime_type_vp8(base::UTF8ToUTF16("video/vp8")); 136 const WebString good_mime_type_vp8(base::UTF8ToUTF16("video/vp8"));
94 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(good_mime_type_vp8)); 137 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(good_mime_type_vp8));
95 138
96 const WebString good_mime_type_vp9(base::UTF8ToUTF16("video/vp9")); 139 const WebString good_mime_type_vp9(base::UTF8ToUTF16("video/vp9"));
97 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(good_mime_type_vp9)); 140 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(good_mime_type_vp9));
98 141
142 const WebString audio_mime_type(base::UTF8ToUTF16("audio/opus"));
143 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(audio_mime_type));
144
145 const WebString combo_mime_type(base::UTF8ToUTF16("video/vp8, audio/opus"));
146 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(combo_mime_type));
147
99 const WebString bad_mime_type(base::UTF8ToUTF16("video/unsupportedcodec")); 148 const WebString bad_mime_type(base::UTF8ToUTF16("video/unsupportedcodec"));
100 EXPECT_FALSE(media_recorder_handler_->canSupportMimeType(bad_mime_type)); 149 EXPECT_FALSE(media_recorder_handler_->canSupportMimeType(bad_mime_type));
101 150
102 const WebString empty_mime_type(base::UTF8ToUTF16("")); 151 const WebString empty_mime_type(base::UTF8ToUTF16(""));
103 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(empty_mime_type)); 152 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(empty_mime_type));
104 } 153 }
105 154
106 // Checks that the initialization-destruction sequence works fine. 155 // Checks that the initialization-destruction sequence works fine.
107 TEST_P(MediaRecorderHandlerTest, InitializeStartStop) { 156 TEST_P(MediaRecorderHandlerTest, InitializeStartStop) {
157 AddTracks();
108 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type)); 158 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type));
109 EXPECT_TRUE(media_recorder_handler_->initialize(this, 159 EXPECT_TRUE(media_recorder_handler_->initialize(this,
110 registry_.test_stream(), 160 registry_.test_stream(),
111 mime_type)); 161 mime_type));
112 EXPECT_FALSE(recording()); 162 EXPECT_FALSE(recording());
113 EXPECT_FALSE(hasVideoRecorders()); 163 EXPECT_FALSE(hasVideoRecorders());
164 EXPECT_FALSE(hasAudioRecorders());
114 165
115 EXPECT_TRUE(media_recorder_handler_->start()); 166 EXPECT_TRUE(media_recorder_handler_->start());
116 EXPECT_TRUE(recording()); 167 EXPECT_TRUE(recording());
117 EXPECT_TRUE(hasVideoRecorders()); 168
169 EXPECT_TRUE(hasVideoRecorders() || !GetParam().has_video);
170 EXPECT_TRUE(hasAudioRecorders() || !GetParam().has_audio);
118 171
119 media_recorder_handler_->stop(); 172 media_recorder_handler_->stop();
120 EXPECT_FALSE(recording()); 173 EXPECT_FALSE(recording());
121 EXPECT_FALSE(hasVideoRecorders()); 174 EXPECT_FALSE(hasVideoRecorders());
175 EXPECT_FALSE(hasAudioRecorders());
122 176
123 // Expect a last call on destruction. 177 // Expect a last call on destruction.
124 EXPECT_CALL(*this, writeData(_, _, true)).Times(1); 178 EXPECT_CALL(*this, writeData(_, _, true)).Times(1);
125 media_recorder_handler_.reset(); 179 media_recorder_handler_.reset();
126 } 180 }
127 181
128 // Sends 2 frames and expect them as WebM contained encoded data in writeData(). 182 // Sends 2 frames and expect them as WebM contained encoded data in writeData().
129 TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) { 183 TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) {
184 // Video-only test.
185 if (GetParam().has_audio)
186 return;
187
188 AddTracks();
189
130 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type)); 190 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type));
131 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(), 191 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(),
132 mime_type)); 192 mime_type));
133 EXPECT_TRUE(media_recorder_handler_->start()); 193 EXPECT_TRUE(media_recorder_handler_->start());
134 194
135 InSequence s; 195 InSequence s;
136 const scoped_refptr<media::VideoFrame> video_frame = 196 const scoped_refptr<media::VideoFrame> video_frame =
137 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80)); 197 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80));
138 198
139 { 199 {
140 base::RunLoop run_loop; 200 base::RunLoop run_loop;
141 base::Closure quit_closure = run_loop.QuitClosure(); 201 base::Closure quit_closure = run_loop.QuitClosure();
142 // writeData() is pinged a number of times as the WebM header is written; 202 // writeData() is pinged a number of times as the WebM header is written;
143 // the last time it is called it has the encoded data. 203 // the last time it is called it has the encoded data.
144 const size_t encoded_data_size = GetParam().first_encoded_frame_size; 204 const size_t encoded_data_size = GetParam().first_encoded_video_frame_size;
145 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _)) 205 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _))
146 .Times(AtLeast(1)); 206 .Times(AtLeast(1));
147 EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) 207 EXPECT_CALL(*this, writeData(_, encoded_data_size, _))
148 .Times(1) 208 .Times(1)
149 .WillOnce(RunClosure(quit_closure)); 209 .WillOnce(RunClosure(quit_closure));
150 210
151 OnVideoFrameForTesting(video_frame); 211 OnVideoFrameForTesting(video_frame);
152 run_loop.Run(); 212 run_loop.Run();
153 } 213 }
154 214
155 { 215 {
156 base::RunLoop run_loop; 216 base::RunLoop run_loop;
157 base::Closure quit_closure = run_loop.QuitClosure(); 217 base::Closure quit_closure = run_loop.QuitClosure();
158 // The second time around writeData() is called a number of times to write 218 // The second time around writeData() is called a number of times to write
159 // the WebM frame header, and then is pinged with the encoded data. 219 // the WebM frame header, and then is pinged with the encoded data.
160 const size_t encoded_data_size = GetParam().second_encoded_frame_size; 220 const size_t encoded_data_size = GetParam().second_encoded_video_frame_size;
161 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _)) 221 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _))
162 .Times(AtLeast(1)); 222 .Times(AtLeast(1));
163 EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) 223 EXPECT_CALL(*this, writeData(_, encoded_data_size, _))
164 .Times(1) 224 .Times(1)
165 .WillOnce(RunClosure(quit_closure)); 225 .WillOnce(RunClosure(quit_closure));
166 226
167 OnVideoFrameForTesting(video_frame); 227 OnVideoFrameForTesting(video_frame);
168 run_loop.Run(); 228 run_loop.Run();
169 } 229 }
170 230
171 media_recorder_handler_->stop(); 231 media_recorder_handler_->stop();
172 232
173 // Expect a last call on destruction, with size 0 and |lastInSlice| true. 233 // Expect a last call on destruction, with size 0 and |lastInSlice| true.
174 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1); 234 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1);
175 media_recorder_handler_.reset(); 235 media_recorder_handler_.reset();
176 } 236 }
177 237
178 INSTANTIATE_TEST_CASE_P(, 238 INSTANTIATE_TEST_CASE_P(,
179 MediaRecorderHandlerTest, 239 MediaRecorderHandlerTest,
180 ValuesIn(kMediaRecorderTestParams)); 240 ValuesIn(kMediaRecorderTestParams));
181 241
242 // Sends 2 frames and expect them as WebM contained encoded data in writeData().
243 TEST_P(MediaRecorderHandlerTest, EncodeAudioFrames) {
244 // Audio-only test.
245 if (GetParam().has_video)
246 return;
247
248 AddTracks();
249
250 const WebString mime_type(base::UTF8ToUTF16("audio/opus"));
251 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(),
252 mime_type));
253 EXPECT_TRUE(media_recorder_handler_->start());
254
255 InSequence s;
256 const scoped_ptr<media::AudioBus> audio_bus1 = NextAudioBus();
257 const scoped_ptr<media::AudioBus> audio_bus2 = NextAudioBus();
258
259 media::AudioParameters params(
260 media::AudioParameters::AUDIO_PCM_LINEAR, media::CHANNEL_LAYOUT_STEREO,
261 kTestAudioSampleRate, kTestAudioBitsPerSample,
262 kTestAudioSampleRate * kTestAudioBufferDurationMS / 1000);
263 SetAudioFormatForTesting(params);
264
265 {
266 base::RunLoop run_loop;
267 base::Closure quit_closure = run_loop.QuitClosure();
268 // writeData() is pinged a number of times as the WebM header is written;
269 // the last time it is called it has the encoded data.
270 const size_t kEncodedDataSize = GetParam().first_encoded_audio_frame_size;
271 EXPECT_CALL(*this, writeData(_, Lt(kEncodedDataSize), _)).Times(AtLeast(1));
272 EXPECT_CALL(*this, writeData(_, kEncodedDataSize, _))
273 .Times(1)
274 .WillOnce(RunClosure(quit_closure));
275
276 OnAudioBusForTesting(*audio_bus1);
277 run_loop.Run();
278 }
279
280 {
281 base::RunLoop run_loop;
282 base::Closure quit_closure = run_loop.QuitClosure();
283 // The second time around writeData() is called a number of times to write
284 // the WebM frame header, and then is pinged with the encoded data.
285 const size_t kSecondEncodedDataSize =
286 GetParam().second_encoded_audio_frame_size;
287 EXPECT_CALL(*this, writeData(_, Lt(kSecondEncodedDataSize), _))
288 .Times(AtLeast(1));
289 EXPECT_CALL(*this, writeData(_, kSecondEncodedDataSize, _))
290 .Times(1)
291 .WillOnce(RunClosure(quit_closure));
292
293 OnAudioBusForTesting(*audio_bus2);
294 run_loop.Run();
295 }
296
297 media_recorder_handler_->stop();
298
299 // Expect a last call on destruction, with size 0 and |lastInSlice| true.
300 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1);
301 media_recorder_handler_.reset();
302 }
303
182 } // namespace content 304 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698