OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/base64.h" | 7 #include "base/base64.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/environment.h" | 9 #include "base/environment.h" |
10 #include "base/files/file.h" | 10 #include "base/files/file.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 } | 46 } |
47 } // namespace | 47 } // namespace |
48 | 48 |
49 static const base::FilePath::CharType kFrameAnalyzerExecutable[] = | 49 static const base::FilePath::CharType kFrameAnalyzerExecutable[] = |
50 #if defined(OS_WIN) | 50 #if defined(OS_WIN) |
51 FILE_PATH_LITERAL("frame_analyzer.exe"); | 51 FILE_PATH_LITERAL("frame_analyzer.exe"); |
52 #else | 52 #else |
53 FILE_PATH_LITERAL("frame_analyzer"); | 53 FILE_PATH_LITERAL("frame_analyzer"); |
54 #endif | 54 #endif |
55 | 55 |
| 56 static const base::FilePath::CharType kArgbToI420ConverterExecutable[] = |
| 57 #if defined(OS_WIN) |
| 58 FILE_PATH_LITERAL("rgba_to_i420_converter.exe"); |
| 59 #else |
| 60 FILE_PATH_LITERAL("rgba_to_i420_converter"); |
| 61 #endif |
| 62 |
56 static const base::FilePath::CharType kCapturedYuvFileName[] = | 63 static const base::FilePath::CharType kCapturedYuvFileName[] = |
57 FILE_PATH_LITERAL("captured_video.yuv"); | 64 FILE_PATH_LITERAL("captured_video.yuv"); |
58 static const base::FilePath::CharType kCapturedWebmFileName[] = | |
59 FILE_PATH_LITERAL("captured_video.webm"); | |
60 static const base::FilePath::CharType kStatsFileName[] = | 65 static const base::FilePath::CharType kStatsFileName[] = |
61 FILE_PATH_LITERAL("stats.txt"); | 66 FILE_PATH_LITERAL("stats.txt"); |
62 static const char kMainWebrtcTestHtmlPage[] = | 67 static const char kMainWebrtcTestHtmlPage[] = |
63 "/webrtc/webrtc_jsep01_test.html"; | 68 "/webrtc/webrtc_jsep01_test.html"; |
64 static const char kCapturingWebrtcHtmlPage[] = | 69 static const char kCapturingWebrtcHtmlPage[] = |
65 "/webrtc/webrtc_video_quality_test.html"; | 70 "/webrtc/webrtc_video_quality_test.html"; |
66 | 71 |
67 static const struct VideoQualityTestConfig { | 72 static const struct VideoQualityTestConfig { |
68 const char* test_name; | 73 const char* test_name; |
69 int width; | 74 int width; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 .Append(test_config_.reference_video) | 125 .Append(test_config_.reference_video) |
121 .AddExtension(test::kY4mFileExtension); | 126 .AddExtension(test::kY4mFileExtension); |
122 command_line->AppendSwitchPath(switches::kUseFileForFakeVideoCapture, | 127 command_line->AppendSwitchPath(switches::kUseFileForFakeVideoCapture, |
123 webrtc_reference_video_y4m_); | 128 webrtc_reference_video_y4m_); |
124 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); | 129 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); |
125 | 130 |
126 // The video playback will not work without a GPU, so force its use here. | 131 // The video playback will not work without a GPU, so force its use here. |
127 command_line->AppendSwitch(switches::kUseGpuInTests); | 132 command_line->AppendSwitch(switches::kUseGpuInTests); |
128 } | 133 } |
129 | 134 |
130 // Writes the captured video to a webm file. | 135 // Writes all frames we've captured so far by grabbing them from the |
131 void WriteCapturedWebmVideo(content::WebContents* capturing_tab, | 136 // javascript and writing them to the temporary work directory. |
132 const base::FilePath& webm_video_filename) { | 137 void WriteCapturedFramesToWorkingDir(content::WebContents* capturing_tab) { |
133 std::string base64_encoded_video = | 138 int num_frames = 0; |
134 ExecuteJavascript("getRecordedVideoAsBase64()", capturing_tab); | 139 std::string response = |
135 std::string recorded_video; | 140 ExecuteJavascript("getTotalNumberCapturedFrames()", capturing_tab); |
136 ASSERT_TRUE(base::Base64Decode(base64_encoded_video, &recorded_video)); | 141 ASSERT_TRUE(base::StringToInt(response, &num_frames)) << |
137 base::File video_file(webm_video_filename, | 142 "Failed to retrieve frame count: got " << response; |
138 base::File::FLAG_CREATE | base::File::FLAG_WRITE); | 143 ASSERT_NE(0, num_frames) << "Failed to capture any frames."; |
139 size_t written = video_file.Write(0, recorded_video.c_str(), | 144 |
140 recorded_video.length()); | 145 for (int i = 0; i < num_frames; i++) { |
141 ASSERT_EQ(recorded_video.length(), written); | 146 std::string base64_encoded_frame = |
| 147 ExecuteJavascript(base::StringPrintf("getOneCapturedFrame(%d)", i), |
| 148 capturing_tab); |
| 149 std::string decoded_frame; |
| 150 ASSERT_TRUE(base::Base64Decode(base64_encoded_frame, &decoded_frame)) |
| 151 << "Failed to decode frame data '" << base64_encoded_frame << "'."; |
| 152 |
| 153 std::string file_name = base::StringPrintf("frame_%04d", i); |
| 154 base::File frame_file(GetWorkingDir().AppendASCII(file_name), |
| 155 base::File::FLAG_CREATE | base::File::FLAG_WRITE); |
| 156 size_t written = frame_file.Write(0, decoded_frame.c_str(), |
| 157 decoded_frame.length()); |
| 158 ASSERT_EQ(decoded_frame.length(), written); |
| 159 } |
142 } | 160 } |
143 | 161 |
144 // Runs ffmpeg on the captured webm video and writes it to a yuv video file. | 162 // Runs the RGBA to I420 converter on the video in |capture_video_filename|, |
145 bool RunWebmToI420Converter(const base::FilePath& webm_video_filename, | 163 // which should contain frames of size |width| x |height|. |
146 const base::FilePath& yuv_video_filename) { | 164 // |
147 base::FilePath path_to_ffmpeg = test::GetToolForPlatform("ffmpeg"); | 165 // The rgba_to_i420_converter is part of the webrtc_test_tools target which |
148 if (!base::PathExists(path_to_ffmpeg)) { | 166 // should be build prior to running this test. The resulting binary should |
149 LOG(ERROR) << "Missing ffmpeg: should be in " << path_to_ffmpeg.value(); | 167 // live next to Chrome. |
| 168 bool RunARGBtoI420Converter(int width, |
| 169 int height, |
| 170 const base::FilePath& captured_video_filename) { |
| 171 base::FilePath path_to_converter = |
| 172 GetBrowserDir().Append(kArgbToI420ConverterExecutable); |
| 173 |
| 174 if (!base::PathExists(path_to_converter)) { |
| 175 LOG(ERROR) << "Missing ARGB->I420 converter: should be in " |
| 176 << path_to_converter.value() |
| 177 << ". Try building the chromium_builder_webrtc target."; |
150 return false; | 178 return false; |
151 } | 179 } |
152 | 180 |
153 base::CommandLine ffmpeg_command(path_to_ffmpeg); | 181 base::CommandLine converter_command(path_to_converter); |
154 ffmpeg_command.AppendArg("-i"); | 182 converter_command.AppendSwitchPath("--frames_dir", GetWorkingDir()); |
155 ffmpeg_command.AppendArgPath(webm_video_filename); | 183 converter_command.AppendSwitchPath("--output_file", |
156 ffmpeg_command.AppendArgPath(yuv_video_filename); | 184 captured_video_filename); |
| 185 converter_command.AppendSwitchASCII("--width", base::IntToString(width)); |
| 186 converter_command.AppendSwitchASCII("--height", base::IntToString(height)); |
| 187 converter_command.AppendSwitchASCII("--delete_frames", "true"); |
157 | 188 |
158 // We produce an output file that will later be used as an input to the | 189 // We produce an output file that will later be used as an input to the |
159 // barcode decoder and frame analyzer tools. | 190 // barcode decoder and frame analyzer tools. |
160 DVLOG(0) << "Running " << ffmpeg_command.GetCommandLineString(); | 191 DVLOG(0) << "Running " << converter_command.GetCommandLineString(); |
161 std::string result; | 192 std::string result; |
162 bool ok = base::GetAppOutput(ffmpeg_command, &result); | 193 bool ok = base::GetAppOutput(converter_command, &result); |
163 DVLOG(0) << "Output was:\n\n" << result; | 194 DVLOG(0) << "Output was:\n\n" << result; |
164 return ok; | 195 return ok; |
165 } | 196 } |
166 | 197 |
167 // Compares the |captured_video_filename| with the |reference_video_filename|. | 198 // Compares the |captured_video_filename| with the |reference_video_filename|. |
168 // | 199 // |
169 // The barcode decoder decodes the captured video containing barcodes overlaid | 200 // The barcode decoder decodes the captured video containing barcodes overlaid |
170 // into every frame of the video (produced by rgba_to_i420_converter). It | 201 // into every frame of the video (produced by rgba_to_i420_converter). It |
171 // produces a set of PNG images and a |stats_file| that maps each captured | 202 // produces a set of PNG images and a |stats_file| that maps each captured |
172 // frame to a frame in the reference video. The frames should be of size | 203 // frame to a frame in the reference video. The frames should be of size |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 302 |
272 // Poll slower here to avoid flooding the log with messages: capturing and | 303 // Poll slower here to avoid flooding the log with messages: capturing and |
273 // sending frames take quite a bit of time. | 304 // sending frames take quite a bit of time. |
274 int polling_interval_msec = 1000; | 305 int polling_interval_msec = 1000; |
275 | 306 |
276 EXPECT_TRUE(test::PollingWaitUntil("doneFrameCapturing()", "done-capturing", | 307 EXPECT_TRUE(test::PollingWaitUntil("doneFrameCapturing()", "done-capturing", |
277 right_tab, polling_interval_msec)); | 308 right_tab, polling_interval_msec)); |
278 | 309 |
279 HangUp(left_tab); | 310 HangUp(left_tab); |
280 | 311 |
281 WriteCapturedWebmVideo( | 312 WriteCapturedFramesToWorkingDir(right_tab); |
282 right_tab, GetWorkingDir().Append(kCapturedWebmFileName)); | |
283 | 313 |
284 // Shut everything down to avoid having the javascript race with the | 314 // Shut everything down to avoid having the javascript race with the |
285 // analysis tools. For instance, dont have console log printouts interleave | 315 // analysis tools. For instance, dont have console log printouts interleave |
286 // with the RESULT lines from the analysis tools (crbug.com/323200). | 316 // with the RESULT lines from the analysis tools (crbug.com/323200). |
287 chrome::CloseWebContents(browser(), left_tab, false); | 317 chrome::CloseWebContents(browser(), left_tab, false); |
288 chrome::CloseWebContents(browser(), right_tab, false); | 318 chrome::CloseWebContents(browser(), right_tab, false); |
289 | 319 |
290 RunWebmToI420Converter(GetWorkingDir().Append(kCapturedWebmFileName), | 320 ASSERT_TRUE( |
291 GetWorkingDir().Append(kCapturedYuvFileName)); | 321 RunARGBtoI420Converter(test_config_.width, test_config_.height, |
| 322 GetWorkingDir().Append(kCapturedYuvFileName))); |
292 | 323 |
293 ASSERT_TRUE(CompareVideosAndPrintResult( | 324 ASSERT_TRUE(CompareVideosAndPrintResult( |
294 MakeLabel(test_config_.test_name, video_codec), test_config_.width, | 325 MakeLabel(test_config_.test_name, video_codec), test_config_.width, |
295 test_config_.height, GetWorkingDir().Append(kCapturedYuvFileName), | 326 test_config_.height, GetWorkingDir().Append(kCapturedYuvFileName), |
296 test::GetReferenceFilesDir() | 327 test::GetReferenceFilesDir() |
297 .Append(test_config_.reference_video) | 328 .Append(test_config_.reference_video) |
298 .AddExtension(test::kYuvFileExtension), | 329 .AddExtension(test::kYuvFileExtension), |
299 GetWorkingDir().Append(kStatsFileName))); | 330 GetWorkingDir().Append(kStatsFileName))); |
300 } | 331 } |
301 | 332 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 if (!base::FeatureList::IsEnabled(content::kWebRtcH264WithOpenH264FFmpeg)) { | 376 if (!base::FeatureList::IsEnabled(content::kWebRtcH264WithOpenH264FFmpeg)) { |
346 LOG(WARNING) << "Run-time feature WebRTC-H264WithOpenH264FFmpeg disabled. " | 377 LOG(WARNING) << "Run-time feature WebRTC-H264WithOpenH264FFmpeg disabled. " |
347 "Skipping WebRtcVideoQualityBrowserTest.MANUAL_TestVideoQualityH264 " | 378 "Skipping WebRtcVideoQualityBrowserTest.MANUAL_TestVideoQualityH264 " |
348 "(test \"OK\")"; | 379 "(test \"OK\")"; |
349 return; | 380 return; |
350 } | 381 } |
351 TestVideoQuality("H264"); | 382 TestVideoQuality("H264"); |
352 } | 383 } |
353 | 384 |
354 #endif // BUILDFLAG(RTC_USE_H264) | 385 #endif // BUILDFLAG(RTC_USE_H264) |
OLD | NEW |