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

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
148 const WebString bad_combo(base::UTF8ToUTF16("video/vp8, audio/unsupported"));
149 EXPECT_FALSE(media_recorder_handler_->canSupportMimeType(bad_combo));
150
99 const WebString bad_mime_type(base::UTF8ToUTF16("video/unsupportedcodec")); 151 const WebString bad_mime_type(base::UTF8ToUTF16("video/unsupportedcodec"));
100 EXPECT_FALSE(media_recorder_handler_->canSupportMimeType(bad_mime_type)); 152 EXPECT_FALSE(media_recorder_handler_->canSupportMimeType(bad_mime_type));
101 153
102 const WebString empty_mime_type(base::UTF8ToUTF16("")); 154 const WebString empty_mime_type(base::UTF8ToUTF16(""));
103 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(empty_mime_type)); 155 EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(empty_mime_type));
104 } 156 }
105 157
106 // Checks that the initialization-destruction sequence works fine. 158 // Checks that the initialization-destruction sequence works fine.
107 TEST_P(MediaRecorderHandlerTest, InitializeStartStop) { 159 TEST_P(MediaRecorderHandlerTest, InitializeStartStop) {
160 AddTracks();
108 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type)); 161 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type));
109 EXPECT_TRUE(media_recorder_handler_->initialize(this, 162 EXPECT_TRUE(media_recorder_handler_->initialize(this,
110 registry_.test_stream(), 163 registry_.test_stream(),
111 mime_type)); 164 mime_type));
112 EXPECT_FALSE(recording()); 165 EXPECT_FALSE(recording());
113 EXPECT_FALSE(hasVideoRecorders()); 166 EXPECT_FALSE(hasVideoRecorders());
167 EXPECT_FALSE(hasAudioRecorders());
114 168
115 EXPECT_TRUE(media_recorder_handler_->start()); 169 EXPECT_TRUE(media_recorder_handler_->start());
116 EXPECT_TRUE(recording()); 170 EXPECT_TRUE(recording());
117 EXPECT_TRUE(hasVideoRecorders()); 171
172 EXPECT_TRUE(hasVideoRecorders() || !GetParam().has_video);
173 EXPECT_TRUE(hasAudioRecorders() || !GetParam().has_audio);
118 174
119 media_recorder_handler_->stop(); 175 media_recorder_handler_->stop();
120 EXPECT_FALSE(recording()); 176 EXPECT_FALSE(recording());
121 EXPECT_FALSE(hasVideoRecorders()); 177 EXPECT_FALSE(hasVideoRecorders());
178 EXPECT_FALSE(hasAudioRecorders());
122 179
123 // Expect a last call on destruction. 180 // Expect a last call on destruction.
124 EXPECT_CALL(*this, writeData(_, _, true)).Times(1); 181 EXPECT_CALL(*this, writeData(_, _, true)).Times(1);
125 media_recorder_handler_.reset(); 182 media_recorder_handler_.reset();
126 } 183 }
127 184
128 // Sends 2 frames and expect them as WebM contained encoded data in writeData(). 185 // Sends 2 frames and expect them as WebM contained encoded data in writeData().
129 TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) { 186 TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) {
187 // Video-only test.
188 if (GetParam().has_audio)
189 return;
190
191 AddTracks();
192
130 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type)); 193 const WebString mime_type(base::UTF8ToUTF16(GetParam().mime_type));
131 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(), 194 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(),
132 mime_type)); 195 mime_type));
133 EXPECT_TRUE(media_recorder_handler_->start()); 196 EXPECT_TRUE(media_recorder_handler_->start());
134 197
135 InSequence s; 198 InSequence s;
136 const scoped_refptr<media::VideoFrame> video_frame = 199 const scoped_refptr<media::VideoFrame> video_frame =
137 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80)); 200 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80));
138 201
139 { 202 {
140 base::RunLoop run_loop; 203 base::RunLoop run_loop;
141 base::Closure quit_closure = run_loop.QuitClosure(); 204 base::Closure quit_closure = run_loop.QuitClosure();
142 // writeData() is pinged a number of times as the WebM header is written; 205 // 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. 206 // the last time it is called it has the encoded data.
144 const size_t encoded_data_size = GetParam().first_encoded_frame_size; 207 const size_t encoded_data_size = GetParam().first_encoded_video_frame_size;
145 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _)) 208 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _))
146 .Times(AtLeast(1)); 209 .Times(AtLeast(1));
147 EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) 210 EXPECT_CALL(*this, writeData(_, encoded_data_size, _))
148 .Times(1) 211 .Times(1)
149 .WillOnce(RunClosure(quit_closure)); 212 .WillOnce(RunClosure(quit_closure));
150 213
151 OnVideoFrameForTesting(video_frame); 214 OnVideoFrameForTesting(video_frame);
152 run_loop.Run(); 215 run_loop.Run();
153 } 216 }
154 217
155 { 218 {
156 base::RunLoop run_loop; 219 base::RunLoop run_loop;
157 base::Closure quit_closure = run_loop.QuitClosure(); 220 base::Closure quit_closure = run_loop.QuitClosure();
158 // The second time around writeData() is called a number of times to write 221 // 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. 222 // the WebM frame header, and then is pinged with the encoded data.
160 const size_t encoded_data_size = GetParam().second_encoded_frame_size; 223 const size_t encoded_data_size = GetParam().second_encoded_video_frame_size;
161 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _)) 224 EXPECT_CALL(*this, writeData(_, Lt(encoded_data_size), _))
162 .Times(AtLeast(1)); 225 .Times(AtLeast(1));
163 EXPECT_CALL(*this, writeData(_, encoded_data_size, _)) 226 EXPECT_CALL(*this, writeData(_, encoded_data_size, _))
164 .Times(1) 227 .Times(1)
165 .WillOnce(RunClosure(quit_closure)); 228 .WillOnce(RunClosure(quit_closure));
166 229
167 OnVideoFrameForTesting(video_frame); 230 OnVideoFrameForTesting(video_frame);
168 run_loop.Run(); 231 run_loop.Run();
169 } 232 }
170 233
171 media_recorder_handler_->stop(); 234 media_recorder_handler_->stop();
172 235
173 // Expect a last call on destruction, with size 0 and |lastInSlice| true. 236 // Expect a last call on destruction, with size 0 and |lastInSlice| true.
174 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1); 237 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1);
175 media_recorder_handler_.reset(); 238 media_recorder_handler_.reset();
176 } 239 }
177 240
178 INSTANTIATE_TEST_CASE_P(, 241 INSTANTIATE_TEST_CASE_P(,
179 MediaRecorderHandlerTest, 242 MediaRecorderHandlerTest,
180 ValuesIn(kMediaRecorderTestParams)); 243 ValuesIn(kMediaRecorderTestParams));
181 244
245 // Sends 2 frames and expect them as WebM contained encoded data in writeData().
246 TEST_P(MediaRecorderHandlerTest, EncodeAudioFrames) {
247 // Audio-only test.
248 if (GetParam().has_video)
249 return;
250
251 AddTracks();
252
253 const WebString mime_type(base::UTF8ToUTF16("audio/opus"));
254 EXPECT_TRUE(media_recorder_handler_->initialize(this, registry_.test_stream(),
255 mime_type));
256 EXPECT_TRUE(media_recorder_handler_->start());
257
258 InSequence s;
259 const scoped_ptr<media::AudioBus> audio_bus1 = NextAudioBus();
260 const scoped_ptr<media::AudioBus> audio_bus2 = NextAudioBus();
261
262 media::AudioParameters params(
263 media::AudioParameters::AUDIO_PCM_LINEAR, media::CHANNEL_LAYOUT_STEREO,
264 kTestAudioSampleRate, kTestAudioBitsPerSample,
265 kTestAudioSampleRate * kTestAudioBufferDurationMS / 1000);
266 SetAudioFormatForTesting(params);
267
268 {
269 base::RunLoop run_loop;
270 base::Closure quit_closure = run_loop.QuitClosure();
271 // writeData() is pinged a number of times as the WebM header is written;
272 // the last time it is called it has the encoded data.
273 const size_t kEncodedDataSize = GetParam().first_encoded_audio_frame_size;
274 EXPECT_CALL(*this, writeData(_, Lt(kEncodedDataSize), _)).Times(AtLeast(1));
275 EXPECT_CALL(*this, writeData(_, kEncodedDataSize, _))
276 .Times(1)
277 .WillOnce(RunClosure(quit_closure));
278
279 OnAudioBusForTesting(*audio_bus1);
280 run_loop.Run();
281 }
282
283 {
284 base::RunLoop run_loop;
285 base::Closure quit_closure = run_loop.QuitClosure();
286 // The second time around writeData() is called a number of times to write
287 // the WebM frame header, and then is pinged with the encoded data.
288 const size_t kSecondEncodedDataSize =
289 GetParam().second_encoded_audio_frame_size;
290 EXPECT_CALL(*this, writeData(_, Lt(kSecondEncodedDataSize), _))
291 .Times(AtLeast(1));
292 EXPECT_CALL(*this, writeData(_, kSecondEncodedDataSize, _))
293 .Times(1)
294 .WillOnce(RunClosure(quit_closure));
295
296 OnAudioBusForTesting(*audio_bus2);
297 run_loop.Run();
298 }
299
300 media_recorder_handler_->stop();
301
302 // Expect a last call on destruction, with size 0 and |lastInSlice| true.
303 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1);
304 media_recorder_handler_.reset();
305 }
306
182 } // namespace content 307 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_recorder_handler.cc ('k') | content/renderer/media/mock_media_stream_registry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698