| 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 "base/environment.h" | 5 #include "base/environment.h" |
| 6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
| 7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
| 8 #include "base/process/launch.h" | 8 #include "base/process/launch.h" |
| 9 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 static const char kHomeEnvName[] = | 54 static const char kHomeEnvName[] = |
| 55 #if defined(OS_WIN) | 55 #if defined(OS_WIN) |
| 56 "HOMEPATH"; | 56 "HOMEPATH"; |
| 57 #else | 57 #else |
| 58 "HOME"; | 58 "HOME"; |
| 59 #endif | 59 #endif |
| 60 | 60 |
| 61 // The working dir should be in the user's home folder. | 61 // The working dir should be in the user's home folder. |
| 62 static const base::FilePath::CharType kWorkingDirName[] = | 62 static const base::FilePath::CharType kWorkingDirName[] = |
| 63 FILE_PATH_LITERAL("webrtc_video_quality"); | 63 FILE_PATH_LITERAL("webrtc_video_quality"); |
| 64 static const base::FilePath::CharType kReferenceVideosDirName[] = | |
| 65 FILE_PATH_LITERAL("webrtc.DEPS/webrtc_videos"); | |
| 66 static const base::FilePath::CharType kReferenceFileName360p[] = | |
| 67 FILE_PATH_LITERAL("reference_video_640x360_30fps"); | |
| 68 static const base::FilePath::CharType kYuvFileExtension[] = | |
| 69 FILE_PATH_LITERAL("yuv"); | |
| 70 static const base::FilePath::CharType kY4mFileExtension[] = | |
| 71 FILE_PATH_LITERAL("y4m"); | |
| 72 static const base::FilePath::CharType kCapturedYuvFileName[] = | 64 static const base::FilePath::CharType kCapturedYuvFileName[] = |
| 73 FILE_PATH_LITERAL("captured_video.yuv"); | 65 FILE_PATH_LITERAL("captured_video.yuv"); |
| 74 static const base::FilePath::CharType kStatsFileName[] = | 66 static const base::FilePath::CharType kStatsFileName[] = |
| 75 FILE_PATH_LITERAL("stats.txt"); | 67 FILE_PATH_LITERAL("stats.txt"); |
| 76 static const char kMainWebrtcTestHtmlPage[] = | 68 static const char kMainWebrtcTestHtmlPage[] = |
| 77 "/webrtc/webrtc_jsep01_test.html"; | 69 "/webrtc/webrtc_jsep01_test.html"; |
| 78 static const char kCapturingWebrtcHtmlPage[] = | 70 static const char kCapturingWebrtcHtmlPage[] = |
| 79 "/webrtc/webrtc_video_quality_test.html"; | 71 "/webrtc/webrtc_video_quality_test.html"; |
| 80 static const int k360pWidth = 640; | 72 static const int k360pWidth = 640; |
| 81 static const int k360pHeight = 360; | 73 static const int k360pHeight = 360; |
| 82 | 74 |
| 83 // If you change the port number, don't forget to modify video_extraction.js | 75 // If you change the port number, don't forget to modify video_extraction.js |
| 84 // too! | 76 // too! |
| 85 static const char kPyWebSocketPortNumber[] = "12221"; | 77 static const char kPyWebSocketPortNumber[] = "12221"; |
| 86 | 78 |
| 87 const char kAdviseOnGclientSolution[] = | |
| 88 "You need to add this solution to your .gclient to run this test:\n" | |
| 89 "{\n" | |
| 90 " \"name\" : \"webrtc.DEPS\",\n" | |
| 91 " \"url\" : \"svn://svn.chromium.org/chrome/trunk/deps/" | |
| 92 "third_party/webrtc/webrtc.DEPS\",\n" | |
| 93 "}"; | |
| 94 | |
| 95 // Test the video quality of the WebRTC output. | 79 // Test the video quality of the WebRTC output. |
| 96 // | 80 // |
| 97 // Prerequisites: This test case must run on a machine with a chrome playing | 81 // Prerequisites: This test case must run on a machine with a chrome playing |
| 98 // the video from the reference files located int GetReferenceVideosDir(). | 82 // the video from the reference files located int GetReferenceVideosDir(). |
| 99 // The file kReferenceY4mFileName.kY4mFileExtension is played using a | 83 // The file kReferenceY4mFileName.kY4mFileExtension is played using a |
| 100 // FileVideoCaptureDevice and its sibling with kYuvFileExtension is used for | 84 // FileVideoCaptureDevice and its sibling with kYuvFileExtension is used for |
| 101 // comparison. | 85 // comparison. |
| 102 // | 86 // |
| 103 // You must also compile the chromium_builder_webrtc target before you run this | 87 // You must also compile the chromium_builder_webrtc target before you run this |
| 104 // test to get all the tools built. | 88 // test to get all the tools built. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 115 // frame_analyzer. Both tools can be found under third_party/webrtc/tools. The | 99 // frame_analyzer. Both tools can be found under third_party/webrtc/tools. The |
| 116 // test also runs a stand alone Python implementation of a WebSocket server | 100 // test also runs a stand alone Python implementation of a WebSocket server |
| 117 // (pywebsocket) and a barcode_decoder script. | 101 // (pywebsocket) and a barcode_decoder script. |
| 118 class WebRtcVideoQualityBrowserTest : public WebRtcTestBase { | 102 class WebRtcVideoQualityBrowserTest : public WebRtcTestBase { |
| 119 public: | 103 public: |
| 120 WebRtcVideoQualityBrowserTest() | 104 WebRtcVideoQualityBrowserTest() |
| 121 : pywebsocket_server_(0), | 105 : pywebsocket_server_(0), |
| 122 environment_(base::Environment::Create()) {} | 106 environment_(base::Environment::Create()) {} |
| 123 | 107 |
| 124 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { | 108 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { |
| 125 PeerConnectionServerRunner::KillAllPeerConnectionServersOnCurrentSystem(); | 109 test::PeerConnectionServerRunner::KillAllPeerConnectionServers(); |
| 126 DetectErrorsInJavaScript(); // Look for errors in our rather complex js. | 110 DetectErrorsInJavaScript(); // Look for errors in our rather complex js. |
| 127 } | 111 } |
| 128 | 112 |
| 129 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | 113 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
| 130 // Set up the command line option with the expected file name. We will check | 114 // Set up the command line option with the expected file name. We will check |
| 131 // its existence in HasAllRequiredResources(). | 115 // its existence in HasAllRequiredResources(). |
| 132 webrtc_reference_video_y4m_ = GetReferenceVideosDir() | 116 webrtc_reference_video_y4m_ = test::GetReferenceVideosDir() |
| 133 .Append(kReferenceFileName360p).AddExtension(kY4mFileExtension); | 117 .Append(test::kReferenceFileName360p) |
| 118 .AddExtension(test::kY4mFileExtension); |
| 134 command_line->AppendSwitchPath(switches::kUseFileForFakeVideoCapture, | 119 command_line->AppendSwitchPath(switches::kUseFileForFakeVideoCapture, |
| 135 webrtc_reference_video_y4m_); | 120 webrtc_reference_video_y4m_); |
| 136 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); | 121 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); |
| 137 | 122 |
| 138 // The video playback will not work without a GPU, so force its use here. | 123 // The video playback will not work without a GPU, so force its use here. |
| 139 command_line->AppendSwitch(switches::kUseGpuInTests); | 124 command_line->AppendSwitch(switches::kUseGpuInTests); |
| 140 } | 125 } |
| 141 | 126 |
| 142 bool HasAllRequiredResources() { | 127 bool HasAllRequiredResources() { |
| 143 if (!base::PathExists(GetWorkingDir())) { | 128 if (!base::PathExists(GetWorkingDir())) { |
| 144 LOG(ERROR) << "Cannot find the working directory for the temporary " | 129 LOG(ERROR) << "Cannot find the working directory for the temporary " |
| 145 "files:" << GetWorkingDir().value(); | 130 "files:" << GetWorkingDir().value(); |
| 146 return false; | 131 return false; |
| 147 } | 132 } |
| 148 if (!base::PathExists(GetReferenceVideosDir())) { | 133 |
| 149 LOG(ERROR) << "Cannot find the working directory for the reference video " | 134 // Ensure we have the required input files. |
| 150 "files, expected at " << GetReferenceVideosDir().value() << ". " << | 135 return test::HasReferenceFilesInCheckout(); |
| 151 kAdviseOnGclientSolution; | |
| 152 return false; | |
| 153 } | |
| 154 base::FilePath webrtc_reference_video_yuv = GetReferenceVideosDir() | |
| 155 .Append(kReferenceFileName360p).AddExtension(kYuvFileExtension); | |
| 156 if (!base::PathExists(webrtc_reference_video_yuv)) { | |
| 157 LOG(ERROR) << "Missing YUV reference video to be used for quality" | |
| 158 << " comparison, expected at " << webrtc_reference_video_yuv.value() | |
| 159 << ". " << kAdviseOnGclientSolution; | |
| 160 return false; | |
| 161 } | |
| 162 if (!base::PathExists(webrtc_reference_video_y4m_)) { | |
| 163 LOG(ERROR) << "Missing Y4M reference video to be used for quality" | |
| 164 << " comparison, expected at "<< webrtc_reference_video_y4m_.value() | |
| 165 << ". " << kAdviseOnGclientSolution; | |
| 166 return false; | |
| 167 } | |
| 168 return true; | |
| 169 } | 136 } |
| 170 | 137 |
| 171 bool StartPyWebSocketServer() { | 138 bool StartPyWebSocketServer() { |
| 172 base::FilePath path_pywebsocket_dir = | 139 base::FilePath path_pywebsocket_dir = |
| 173 GetSourceDir().Append(FILE_PATH_LITERAL("third_party/pywebsocket/src")); | 140 GetSourceDir().Append(FILE_PATH_LITERAL("third_party/pywebsocket/src")); |
| 174 base::FilePath pywebsocket_server = path_pywebsocket_dir.Append( | 141 base::FilePath pywebsocket_server = path_pywebsocket_dir.Append( |
| 175 FILE_PATH_LITERAL("mod_pywebsocket/standalone.py")); | 142 FILE_PATH_LITERAL("mod_pywebsocket/standalone.py")); |
| 176 base::FilePath path_to_data_handler = | 143 base::FilePath path_to_data_handler = |
| 177 GetSourceDir().Append(FILE_PATH_LITERAL("chrome/test/functional")); | 144 GetSourceDir().Append(FILE_PATH_LITERAL("chrome/test/functional")); |
| 178 | 145 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 } | 271 } |
| 305 | 272 |
| 306 base::FilePath GetWorkingDir() { | 273 base::FilePath GetWorkingDir() { |
| 307 std::string home_dir; | 274 std::string home_dir; |
| 308 environment_->GetVar(kHomeEnvName, &home_dir); | 275 environment_->GetVar(kHomeEnvName, &home_dir); |
| 309 base::FilePath::StringType native_home_dir(home_dir.begin(), | 276 base::FilePath::StringType native_home_dir(home_dir.begin(), |
| 310 home_dir.end()); | 277 home_dir.end()); |
| 311 return base::FilePath(native_home_dir).Append(kWorkingDirName); | 278 return base::FilePath(native_home_dir).Append(kWorkingDirName); |
| 312 } | 279 } |
| 313 | 280 |
| 314 base::FilePath GetReferenceVideosDir() { | 281 test::PeerConnectionServerRunner peerconnection_server_; |
| 315 // FilePath does not tolerate relative paths, and we want to hang the | |
| 316 // kReferenceVideosDirName at the same level as Chromium codebase, so we | |
| 317 // need to subtract the trailing .../src manually from the path. | |
| 318 const size_t src_token_length = 3u; | |
| 319 const base::FilePath::StringType src_token(FILE_PATH_LITERAL("src")); | |
| 320 base::FilePath::StringType path = GetSourceDir().value(); | |
| 321 DCHECK_GT(path.size(), src_token_length); | |
| 322 std::size_t found = path.rfind(src_token); | |
| 323 if (found != std::string::npos) | |
| 324 path.replace(found, | |
| 325 src_token_length, | |
| 326 base::FilePath::StringType(FILE_PATH_LITERAL(""))); | |
| 327 return base::FilePath(path).Append(kReferenceVideosDirName); | |
| 328 } | |
| 329 | |
| 330 PeerConnectionServerRunner peerconnection_server_; | |
| 331 | 282 |
| 332 private: | 283 private: |
| 333 base::FilePath GetSourceDir() { | 284 base::FilePath GetSourceDir() { |
| 334 base::FilePath source_dir; | 285 base::FilePath source_dir; |
| 335 PathService::Get(base::DIR_SOURCE_ROOT, &source_dir); | 286 PathService::Get(base::DIR_SOURCE_ROOT, &source_dir); |
| 336 return source_dir; | 287 return source_dir; |
| 337 } | 288 } |
| 338 | 289 |
| 339 base::FilePath GetBrowserDir() { | 290 base::FilePath GetBrowserDir() { |
| 340 base::FilePath browser_dir; | 291 base::FilePath browser_dir; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 OpenPageAndGetUserMediaInNewTabWithConstraints( | 323 OpenPageAndGetUserMediaInNewTabWithConstraints( |
| 373 embedded_test_server()->GetURL(kCapturingWebrtcHtmlPage), | 324 embedded_test_server()->GetURL(kCapturingWebrtcHtmlPage), |
| 374 kAudioVideoCallConstraints360p); | 325 kAudioVideoCallConstraints360p); |
| 375 | 326 |
| 376 EstablishCall(left_tab, right_tab); | 327 EstablishCall(left_tab, right_tab); |
| 377 | 328 |
| 378 // Poll slower here to avoid flooding the log with messages: capturing and | 329 // Poll slower here to avoid flooding the log with messages: capturing and |
| 379 // sending frames take quite a bit of time. | 330 // sending frames take quite a bit of time. |
| 380 int polling_interval_msec = 1000; | 331 int polling_interval_msec = 1000; |
| 381 | 332 |
| 382 EXPECT_TRUE(PollingWaitUntil( | 333 EXPECT_TRUE(test::PollingWaitUntil( |
| 383 "doneFrameCapturing()", "done-capturing", right_tab, | 334 "doneFrameCapturing()", "done-capturing", right_tab, |
| 384 polling_interval_msec)); | 335 polling_interval_msec)); |
| 385 | 336 |
| 386 HangUp(left_tab); | 337 HangUp(left_tab); |
| 387 WaitUntilHangupVerified(left_tab); | 338 WaitUntilHangupVerified(left_tab); |
| 388 WaitUntilHangupVerified(right_tab); | 339 WaitUntilHangupVerified(right_tab); |
| 389 | 340 |
| 390 EXPECT_TRUE(PollingWaitUntil( | 341 EXPECT_TRUE(test::PollingWaitUntil( |
| 391 "haveMoreFramesToSend()", "no-more-frames", right_tab, | 342 "haveMoreFramesToSend()", "no-more-frames", right_tab, |
| 392 polling_interval_msec)); | 343 polling_interval_msec)); |
| 393 | 344 |
| 394 // Shut everything down to avoid having the javascript race with the analysis | 345 // Shut everything down to avoid having the javascript race with the analysis |
| 395 // tools. For instance, dont have console log printouts interleave with the | 346 // tools. For instance, dont have console log printouts interleave with the |
| 396 // RESULT lines from the analysis tools (crbug.com/323200). | 347 // RESULT lines from the analysis tools (crbug.com/323200). |
| 397 ASSERT_TRUE(peerconnection_server_.Stop()); | 348 ASSERT_TRUE(peerconnection_server_.Stop()); |
| 398 ASSERT_TRUE(ShutdownPyWebSocketServer()); | 349 ASSERT_TRUE(ShutdownPyWebSocketServer()); |
| 399 | 350 |
| 400 chrome::CloseWebContents(browser(), left_tab, false); | 351 chrome::CloseWebContents(browser(), left_tab, false); |
| 401 chrome::CloseWebContents(browser(), right_tab, false); | 352 chrome::CloseWebContents(browser(), right_tab, false); |
| 402 | 353 |
| 403 RunARGBtoI420Converter( | 354 RunARGBtoI420Converter( |
| 404 k360pWidth, k360pHeight, GetWorkingDir().Append(kCapturedYuvFileName)); | 355 k360pWidth, k360pHeight, GetWorkingDir().Append(kCapturedYuvFileName)); |
| 405 ASSERT_TRUE(CompareVideosAndPrintResult( | 356 ASSERT_TRUE(CompareVideosAndPrintResult( |
| 406 k360pWidth, | 357 k360pWidth, |
| 407 k360pHeight, | 358 k360pHeight, |
| 408 GetWorkingDir().Append(kCapturedYuvFileName), | 359 GetWorkingDir().Append(kCapturedYuvFileName), |
| 409 GetReferenceVideosDir().Append(kReferenceFileName360p).AddExtension( | 360 test::GetReferenceVideosDir() |
| 410 kYuvFileExtension), | 361 .Append(test::kReferenceFileName360p) |
| 362 .AddExtension(test::kYuvFileExtension), |
| 411 GetWorkingDir().Append(kStatsFileName))); | 363 GetWorkingDir().Append(kStatsFileName))); |
| 412 } | 364 } |
| OLD | NEW |