1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <getopt.h> 6 #include <libyuv.h> 7 #include <math.h> 8 9 #include <cmath> 10 #include <limits> 11 #include <memory> 12 #include <string> 13 #include <vector> 14 15 #include "base/at_exit.h" 16 #include "base/command_line.h" 17 #include "base/files/file_path.h" 18 #include "base/files/file_util.h" 19 #include "gtest/gtest.h" 20 21 #include "camera_characteristics.h" 22 #include "common_types.h" 23 #include "media_v4l2_device.h" 24 25 struct TestCropping { 26 bool check_cropping = false; 27 uint32_t sensor_pixel_array_size_width = 0; 28 uint32_t sensor_pixel_array_size_height = 0; 29 }; 30 31 struct TestProfile { 32 std::string test_list; 33 std::string dev_name; 34 bool check_1280x960 = false; 35 bool check_1600x1200 = false; 36 bool check_constant_framerate = false; 37 bool check_maximum_resolution = false; 38 bool support_constant_framerate = false; 39 TestCropping cropping_profile; 40 uint32_t skip_frames = 0; 41 uint32_t lens_facing = FACING_FRONT; 42 }; 43 44 /* Test lists: 45 * default: for devices without ARC++, and devices with ARC++ which use 46 * camera HAL v1. 47 * halv3: for devices with ARC++ which use camera HAL v3. 48 * certification: for third-party labs to verify new camera modules. 49 */ 50 static const char kDefaultTestList[] = "default"; 51 static const char kHalv3TestList[] = "halv3"; 52 static const char kCertificationTestList[] = "certification"; 53 54 /* Camera Facing */ 55 static const char kFrontCamera[] = "user"; 56 static const char kBackCamera[] = "world"; 57 58 struct TestProfile g_profile; 59 60 static void PrintUsage(int argc, char** argv) { 61 printf("Usage: %s [options]\n\n" 62 "Options:\n" 63 "--help Print usage\n" 64 "--device=DEVICE_NAME Video device name [/dev/video]\n" 65 "--usb-info=VID:PID Device vendor id and product id\n" 66 "--test-list=TEST Select different test list\n" 67 " [%s | %s | %s]\n", 68 argv[0], kDefaultTestList, kHalv3TestList, 69 kCertificationTestList); 70 } 71 72 int RunTest(V4L2Device* device, V4L2Device::IOMethod io, 73 uint32_t buffers, uint32_t capture_time_in_sec, uint32_t width, 74 uint32_t height, uint32_t pixfmt, float fps, 75 V4L2Device::ConstantFramerate constant_framerate, 76 uint32_t skip_frames) { 77 int32_t retcode = 0; 78 if (!device->InitDevice(io, width, height, pixfmt, fps, constant_framerate, 79 skip_frames)) 80 retcode = 1; 81 82 if (!retcode && !device->StartCapture()) 83 retcode = 2; 84 85 if (!retcode && !device->Run(capture_time_in_sec)) 86 retcode = 3; 87 88 if (!device->StopCapture()) 89 retcode = 4; 90 91 if (!device->UninitDevice()) 92 retcode = 5; 93 94 return retcode; 95 } 96 97 bool GetSupportedFormats( 98 V4L2Device* device, SupportedFormats* supported_formats) { 99 supported_formats->clear(); 100 101 SupportedFormat format; 102 uint32_t num_format = 0; 103 device->EnumFormat(&num_format, false); 104 for (uint32_t i = 0; i < num_format; ++i) { 105 if (!device->GetPixelFormat(i, &format.fourcc)) { 106 printf("[Error] Get format error\n"); 107 return false; 108 } 109 uint32_t num_frame_size; 110 if (!device->EnumFrameSize(format.fourcc, &num_frame_size, false)) { 111 printf("[Error] Enumerate frame size error\n"); 112 return false; 113 }; 114 115 for (uint32_t j = 0; j < num_frame_size; ++j) { 116 if (!device->GetFrameSize(j, format.fourcc, &format.width, 117 &format.height)) { 118 printf("[Error] Get frame size error\n"); 119 return false; 120 }; 121 uint32_t num_frame_rate; 122 if (!device->EnumFrameInterval(format.fourcc, format.width, 123 format.height, &num_frame_rate, false)) { 124 printf("[Error] Enumerate frame interval error\n"); 125 return false; 126 }; 127 128 format.frame_rates.clear(); 129 float frame_rate; 130 for (uint32_t k = 0; k < num_frame_rate; ++k) { 131 if (!device->GetFrameInterval(k, format.fourcc, format.width, 132 format.height, &frame_rate)) { 133 printf("[Error] Get frame interval error\n"); 134 return false; 135 }; 136 // All supported resolution should have at least 1 fps. 137 if (frame_rate < 1.0) { 138 printf("[Error] Frame rate should be at least 1.\n"); 139 return false; 140 } 141 format.frame_rates.push_back(frame_rate); 142 } 143 supported_formats->push_back(format); 144 } 145 } 146 return true; 147 } 148 149 SupportedFormat GetMaximumResolution(const SupportedFormats& formats) { 150 SupportedFormat max_format; 151 memset(&max_format, 0, sizeof(max_format)); 152 for (const auto& format : formats) { 153 if (format.width >= max_format.width) { 154 max_format.width = format.width; 155 } 156 if (format.height >= max_format.height) { 157 max_format.height = format.height; 158 } 159 } 160 return max_format; 161 } 162 163 // Find format according to width and height. If multiple formats support the 164 // same resolution, choose V4L2_PIX_FMT_MJPEG first. 165 const SupportedFormat* FindFormatByResolution(const SupportedFormats& formats, 166 uint32_t width, 167 uint32_t height) { 168 const SupportedFormat* result_format = nullptr; 169 for (const auto& format : formats) { 170 if (format.width == width && format.height == height) { 171 if (!result_format || format.fourcc == V4L2_PIX_FMT_MJPEG) { 172 result_format = &format; 173 } 174 } 175 } 176 return result_format; 177 } 178 179 // Find format according to V4L2 fourcc. If multiple resolution support the 180 // same fourcc, choose the first one. 181 const SupportedFormat* FindFormatByFourcc(const SupportedFormats& formats, 182 uint32_t fourcc) { 183 for (const auto& format : formats) { 184 if (format.fourcc == fourcc) { 185 return &format; 186 } 187 } 188 return nullptr; 189 } 190 191 const SupportedFormat* GetResolutionForCropping( 192 const SupportedFormats& formats, 193 TestCropping cropping_profile) { 194 // FOV requirement cannot allow cropping twice. If two streams resolution are 195 // 1920x1080 and 1600x1200, we need a larger resolution which aspect ratio 196 // is the same as sensor aspect ratio. 197 float sensor_aspect_ratio = 198 static_cast<float>(cropping_profile.sensor_pixel_array_size_width) / 199 cropping_profile.sensor_pixel_array_size_height; 200 201 // We need to compare the aspect ratio from sensor resolution. 202 // The sensor resolution may not be just the size. It may be a little larger. 203 // Add a margin to check if the sensor aspect ratio fall in the specific 204 // aspect ratio. 205 // 16:9=1.778, 16:10=1.6, 3:2=1.5, 4:3=1.333 206 const float kAspectRatioMargin = 0.04; 207 const float kFrameRate = 30.0; 208 209 for (const auto& format : formats) { 210 if (format.width >= 1920 && format.height >= 1200) { 211 float aspect_ratio = static_cast<float>(format.width) / format.height; 212 if (std::fabs(sensor_aspect_ratio - aspect_ratio) < kAspectRatioMargin) { 213 for (const auto& frame_rate : format.frame_rates) { 214 if (std::fabs(frame_rate - kFrameRate) <= 215 std::numeric_limits<float>::epsilon()) { 216 return &format; 217 } 218 } 219 } 220 } 221 } 222 return nullptr; 223 } 224 225 // This is for Android testCameraToSurfaceTextureMetadata CTS test case. 226 bool CheckConstantFramerate(const std::vector<int64_t>& timestamps, 227 float require_fps) { 228 // Timestamps are from driver. We only allow 1.5% error buffer for the frame 229 // duration. The margin is aligned to CTS tests. 230 float slop_margin = 0.015; 231 float slop_max_frame_duration_ms = (1000.f / require_fps) * (1 + slop_margin); 232 float slop_min_frame_duration_ms = (1000.f / require_fps) * (1 - slop_margin); 233 234 for (size_t i = 1; i < timestamps.size(); i++) { 235 float frame_duration_ms = 236 (timestamps[i] - timestamps[i - 1]) / 1000000.f; 237 if (frame_duration_ms > slop_max_frame_duration_ms || 238 frame_duration_ms < slop_min_frame_duration_ms) { 239 printf("[Warning] Frame duration %f out of frame rate bounds [%f,%f]\n", 240 frame_duration_ms, slop_min_frame_duration_ms, 241 slop_max_frame_duration_ms); 242 return false; 243 } 244 } 245 return true; 246 } 247 248 bool TestIO(const std::string& dev_name) { 249 uint32_t buffers = 4; 250 uint32_t width = 640; 251 uint32_t height = 480; 252 uint32_t pixfmt = V4L2_PIX_FMT_YUYV; 253 float fps = 30.0; 254 uint32_t time_to_capture = 3; // The unit is second. 255 uint32_t skip_frames = 0; 256 V4L2Device::ConstantFramerate constant_framerate = 257 V4L2Device::DEFAULT_FRAMERATE_SETTING; 258 259 std::unique_ptr<V4L2Device> device( 260 new V4L2Device(dev_name.c_str(), buffers)); 261 262 if (!device->OpenDevice()) 263 return false; 264 265 v4l2_capability cap; 266 if (!device->ProbeCaps(&cap)) 267 return false; 268 269 if (cap.capabilities & V4L2_CAP_STREAMING) { 270 int mmap_ret = RunTest(device.get(), V4L2Device::IO_METHOD_MMAP, buffers, 271 time_to_capture, width, height, pixfmt, fps, constant_framerate, 272 skip_frames); 273 int userp_ret = RunTest(device.get(), V4L2Device::IO_METHOD_USERPTR, 274 buffers, time_to_capture, width, height, pixfmt, fps, 275 constant_framerate, skip_frames); 276 if (mmap_ret && userp_ret) { 277 printf("[Error] Stream I/O failed.\n"); 278 return false; 279 } 280 } else { 281 printf("[Error] Streaming capability is mandatory.\n"); 282 return false; 283 } 284 285 device->CloseDevice(); 286 return true; 287 } 288 289 // Test all required resolutions with 30 fps. 290 // If device supports constant framerate, the test will toggle the setting 291 // and check actual fps. Otherwise, use the default setting of 292 // V4L2_CID_EXPOSURE_AUTO_PRIORITY. 293 bool TestResolutions(const std::string& dev_name, 294 bool check_1280x960, 295 bool check_1600x1200, 296 TestCropping cropping_profile, 297 bool test_constant_framerate) { 298 const int kMaxRetryTimes = 5; 299 uint32_t buffers = 4; 300 uint32_t time_to_capture = 3; 301 uint32_t skip_frames = 0; 302 bool pass = true; 303 304 V4L2Device::IOMethod io = V4L2Device::IO_METHOD_MMAP; 305 std::unique_ptr<V4L2Device> device( 306 new V4L2Device(dev_name.c_str(), buffers)); 307 308 if (!device->OpenDevice()) 309 return false; 310 311 std::vector<V4L2Device::ConstantFramerate> constant_framerate_setting; 312 if (test_constant_framerate) { 313 constant_framerate_setting.push_back(V4L2Device::ENABLE_CONSTANT_FRAMERATE); 314 constant_framerate_setting.push_back( 315 V4L2Device::DISABLE_CONSTANT_FRAMERATE); 316 } else { 317 constant_framerate_setting.push_back( 318 V4L2Device::DEFAULT_FRAMERATE_SETTING); 319 } 320 321 SupportedFormats supported_formats; 322 if (!GetSupportedFormats(device.get(), &supported_formats)) { 323 printf("[Error] Get supported formats failed in %s.\n", dev_name.c_str()); 324 return false; 325 } 326 SupportedFormat max_resolution = GetMaximumResolution(supported_formats); 327 328 const float kFrameRate = 30.0; 329 SupportedFormats required_resolutions; 330 required_resolutions.push_back(SupportedFormat(320, 240, 0, kFrameRate)); 331 required_resolutions.push_back(SupportedFormat(640, 480, 0, kFrameRate)); 332 required_resolutions.push_back(SupportedFormat(1280, 720, 0, kFrameRate)); 333 required_resolutions.push_back(SupportedFormat(1920, 1080, 0, kFrameRate)); 334 if (check_1280x960) { 335 required_resolutions.push_back(SupportedFormat(1280, 960, 0, kFrameRate)); 336 } 337 if (check_1600x1200) { 338 required_resolutions.push_back(SupportedFormat(1600, 1200, 0, kFrameRate)); 339 } 340 if (cropping_profile.check_cropping) { 341 const SupportedFormat* cropping_resolution = 342 GetResolutionForCropping(supported_formats, cropping_profile); 343 if (cropping_resolution != nullptr) { 344 printf("[Info] Add resolution without cropping %dx%d.\n", 345 cropping_resolution->width, cropping_resolution->height); 346 required_resolutions.push_back(*cropping_resolution); 347 } else if (max_resolution.width >= 1920 && max_resolution.height >= 1200) { 348 printf("[Error] Can not find cropping resolution.\n"); 349 pass = false; 350 } 351 } 352 353 for (const auto& test_resolution : required_resolutions) { 354 // Skip the resolution that is larger than the maximum. 355 if (max_resolution.width < test_resolution.width || 356 max_resolution.height < test_resolution.height) { 357 continue; 358 } 359 360 const SupportedFormat* test_format = FindFormatByResolution( 361 supported_formats, test_resolution.width, test_resolution.height); 362 if (test_format == nullptr) { 363 printf("[Error] %dx%d not found in %s\n", test_resolution.width, 364 test_resolution.height, dev_name.c_str()); 365 pass = false; 366 continue; 367 } 368 369 bool frame_rate_30_supported = false; 370 for (const auto& frame_rate : test_format->frame_rates) { 371 if (std::fabs(frame_rate - kFrameRate) <= 372 std::numeric_limits<float>::epsilon()) { 373 frame_rate_30_supported = true; 374 break; 375 } 376 } 377 if (!frame_rate_30_supported) { 378 printf("[Error] Cannot test 30 fps for %dx%d (%08X) failed in %s\n", 379 test_format->width, test_format->height, test_format->fourcc, 380 dev_name.c_str()); 381 pass = false; 382 } 383 384 for (const auto& constant_framerate : constant_framerate_setting) { 385 int retry_count = 0; 386 387 if (!frame_rate_30_supported && constant_framerate == 388 V4L2Device::ENABLE_CONSTANT_FRAMERATE) { 389 continue; 390 } 391 392 for (retry_count = 0; retry_count < kMaxRetryTimes; retry_count++) { 393 if (RunTest(device.get(), io, buffers, time_to_capture, 394 test_format->width, test_format->height, test_format->fourcc, 395 kFrameRate, constant_framerate, skip_frames)) { 396 printf("[Error] Could not capture frames for %dx%d (%08X) in %s\n", 397 test_format->width, test_format->height, test_format->fourcc, 398 dev_name.c_str()); 399 pass = false; 400 break; 401 } 402 403 // Make sure the driver didn't adjust the format. 404 v4l2_format fmt; 405 if (!device->GetV4L2Format(&fmt)) { 406 pass = false; 407 break; 408 } else { 409 if (test_format->width != fmt.fmt.pix.width || 410 test_format->height != fmt.fmt.pix.height || 411 test_format->fourcc != fmt.fmt.pix.pixelformat || 412 std::fabs(kFrameRate - device->GetFrameRate()) > 413 std::numeric_limits<float>::epsilon()) { 414 printf("[Error] Capture test %dx%d (%08X) %.2f fps failed in %s\n", 415 test_format->width, test_format->height, test_format->fourcc, 416 kFrameRate, dev_name.c_str()); 417 pass = false; 418 break; 419 } 420 } 421 422 if (constant_framerate != V4L2Device::ENABLE_CONSTANT_FRAMERATE) { 423 break; 424 } 425 426 float actual_fps = (device->GetNumFrames() - 1) / 427 static_cast<float>(time_to_capture); 428 // 1 fps buffer is because |time_to_capture| may be too short. 429 // EX: 30 fps and capture 3 secs. We may get 89 frames or 91 frames. 430 // The actual fps will be 29.66 or 30.33. 431 if (fabsf(actual_fps - kFrameRate) > 1) { 432 printf("[Warning] Capture test %dx%d (%08X) failed with fps %.2f in " 433 "%s\n", test_format->width, test_format->height, 434 test_format->fourcc, actual_fps, dev_name.c_str()); 435 continue; 436 } 437 438 if (!CheckConstantFramerate(device->GetFrameTimestamps(), kFrameRate)) { 439 printf("[Warning] Capture test %dx%d (%08X) failed and didn't meet " 440 "constant framerate in %s\n", test_format->width, 441 test_format->height, test_format->fourcc, dev_name.c_str()); 442 continue; 443 } 444 break; 445 } 446 if (retry_count == kMaxRetryTimes) { 447 printf("[Error] Cannot meet constant framerate requirement %d times\n", 448 kMaxRetryTimes); 449 pass = false; 450 } 451 } 452 } 453 device->CloseDevice(); 454 return pass; 455 } 456 457 bool TestFirstFrameAfterStreamOn(const std::string& dev_name, 458 uint32_t skip_frames) { 459 uint32_t buffers = 4; 460 uint32_t pixfmt = V4L2_PIX_FMT_MJPEG; 461 uint32_t fps = 30; 462 V4L2Device::ConstantFramerate constant_framerate = 463 V4L2Device::DEFAULT_FRAMERATE_SETTING; 464 V4L2Device::IOMethod io = V4L2Device::IO_METHOD_MMAP; 465 466 std::unique_ptr<V4L2Device> device( 467 new V4L2Device(dev_name.c_str(), buffers)); 468 if (!device->OpenDevice()) 469 return false; 470 471 SupportedFormats supported_formats; 472 if (!GetSupportedFormats(device.get(), &supported_formats)) { 473 printf("[Error] Get supported formats failed in %s.\n", dev_name.c_str()); 474 return false; 475 } 476 const SupportedFormat* test_format = FindFormatByFourcc( 477 supported_formats, V4L2_PIX_FMT_MJPEG); 478 if (test_format == nullptr) { 479 printf("[Info] The camera doesn't support MJPEG format.\n"); 480 return true; 481 } 482 483 uint32_t width = test_format->width; 484 uint32_t height = test_format->height; 485 486 const size_t kTestLoop = 20; 487 for (size_t i = 0; i < kTestLoop; i++) { 488 if (!device->InitDevice(io, width, height, pixfmt, fps, constant_framerate, 489 skip_frames)) 490 return false; 491 492 if (!device->StartCapture()) 493 return false; 494 495 uint32_t buf_index, data_size; 496 int ret; 497 while ((ret = device->ReadOneFrame(&buf_index, &data_size)) == 0); 498 if (ret < 0) { 499 return false; 500 } 501 502 const V4L2Device::Buffer& buffer = device->GetBufferInfo(buf_index); 503 std::unique_ptr<uint8_t[]> yuv_buffer(new uint8_t[width * height * 2]); 504 505 int res = libyuv::MJPGToI420( 506 reinterpret_cast<uint8_t*>(buffer.start), data_size, 507 yuv_buffer.get(), width, 508 yuv_buffer.get() + width * height, width / 2, 509 yuv_buffer.get() + width * height * 5 / 4, width / 2, 510 width, height, width, height); 511 if (res) { 512 printf("[Error] First frame is not a valid mjpeg image.\n"); 513 base::WriteFile(base::FilePath("FirstFrame.jpg"), 514 static_cast<char*>(buffer.start), data_size); 515 return false; 516 } 517 518 if (!device->EnqueueBuffer(buf_index)) 519 return false; 520 521 if (!device->StopCapture()) 522 return false; 523 524 if (!device->UninitDevice()) 525 return false; 526 527 } 528 529 device->CloseDevice(); 530 return true; 531 } 532 533 // ChromeOS spec requires world-facing camera should be at least 1920x1080 and 534 // user-facing camera should be at least 1280x720. 535 bool TestMaximumSupportedResolution(const std::string& dev_name, 536 uint32_t facing) { 537 uint32_t buffers = 4; 538 std::unique_ptr<V4L2Device> device( 539 new V4L2Device(dev_name.c_str(), buffers)); 540 541 if (!device->OpenDevice()) 542 return false; 543 544 SupportedFormats supported_formats; 545 if (!GetSupportedFormats(device.get(), &supported_formats)) { 546 printf("[Error] Get supported formats failed in %s.\n", dev_name.c_str()); 547 return false; 548 } 549 device->CloseDevice(); 550 SupportedFormat max_resolution = GetMaximumResolution(supported_formats); 551 552 uint32_t required_width = 0, required_height = 0; 553 std::string facing_str = ""; 554 if (facing == FACING_FRONT) { 555 required_width = 1080; 556 required_height = 720; 557 facing_str = kFrontCamera; 558 } else if (facing == FACING_BACK) { 559 required_width = 1920; 560 required_height = 1080; 561 facing_str = kBackCamera; 562 } else { 563 printf("[Error] Undefined facing: %d\n", facing); 564 return false; 565 } 566 567 if (max_resolution.width < required_width || 568 max_resolution.height < required_height) { 569 printf("[Error] The maximum resolution %dx%d does not meet requirement " 570 "%dx%d for %s-facing\n", max_resolution.width, 571 max_resolution.height, required_width, required_height, 572 facing_str.c_str()); 573 return false; 574 } 575 return true; 576 } 577 578 const TestProfile GetTestProfile(const std::string& dev_name, 579 const std::string& usb_info, 580 const std::string& test_list) { 581 const int VID_PID_LENGTH = 9; // 0123:abcd format 582 const DeviceInfo* device_info = nullptr; 583 CameraCharacteristics characteristics; 584 if (!usb_info.empty()) { 585 if (usb_info.length() != VID_PID_LENGTH) { 586 printf("[Error] Invalid usb info: %s\n", usb_info.c_str()); 587 exit(EXIT_FAILURE); 588 } 589 device_info = characteristics.Find(usb_info.substr(0, 4), 590 usb_info.substr(5, 9)); 591 } 592 593 if (test_list != kDefaultTestList) { 594 if (!characteristics.ConfigFileExists()) { 595 printf("[Error] %s test list needs camera config file\n", 596 test_list.c_str()); 597 exit(EXIT_FAILURE); 598 } 599 if (device_info == nullptr) { 600 printf("[Error] %s is not described in camera config file\n", 601 usb_info.c_str()); 602 exit(EXIT_FAILURE); 603 } 604 } else { 605 if (!characteristics.ConfigFileExists()) { 606 printf("[Info] Camera config file doesn't exist\n"); 607 } else if (device_info == nullptr) { 608 printf("[Info] %s is not described in camera config file\n", 609 usb_info.c_str()); 610 } 611 } 612 613 TestProfile profile; 614 profile.test_list = test_list; 615 profile.dev_name = dev_name; 616 // Get parameter from config file. 617 if (device_info) { 618 profile.support_constant_framerate = 619 !device_info->constant_framerate_unsupported; 620 profile.skip_frames = device_info->frames_to_skip_after_streamon; 621 profile.lens_facing = device_info->lens_facing; 622 profile.check_maximum_resolution = true; 623 624 // If there is a camera config and test list is not HAL v1, then we can 625 // check cropping requirement according to the sensor physical size. 626 if (test_list != kDefaultTestList) { 627 profile.cropping_profile.check_cropping = true; 628 profile.cropping_profile.sensor_pixel_array_size_width = 629 device_info->sensor_info_pixel_array_size_width; 630 profile.cropping_profile.sensor_pixel_array_size_height = 631 device_info->sensor_info_pixel_array_size_height; 632 } 633 } 634 635 if (test_list == kDefaultTestList) { 636 profile.check_1280x960 = false; 637 profile.check_1600x1200 = false; 638 profile.check_constant_framerate = false; 639 } else if (test_list == kHalv3TestList) { 640 profile.check_1280x960 = true; 641 profile.check_1600x1200 = true; 642 profile.skip_frames = 0; 643 profile.check_constant_framerate = true; 644 } else if (test_list == kCertificationTestList) { 645 profile.check_1280x960 = true; 646 profile.check_1600x1200 = true; 647 profile.skip_frames = 0; 648 profile.check_maximum_resolution = false; 649 profile.check_constant_framerate = true; 650 } 651 652 printf("[Info] check 1280x960: %d\n", profile.check_1280x960); 653 printf("[Info] check 1600x1200: %d\n", profile.check_1600x1200); 654 printf("[Info] check constant framerate: %d\n", 655 profile.check_constant_framerate); 656 printf("[Info] check cropping: %d\n", 657 profile.cropping_profile.check_cropping); 658 printf("[Info] num of skip frames after stream on: %d\n", 659 profile.skip_frames); 660 661 return profile; 662 } 663 664 TEST(TestList, TestIO) { 665 ASSERT_TRUE(TestIO(g_profile.dev_name)); 666 } 667 668 TEST(TestList, TestResolutions) { 669 if (g_profile.test_list == kHalv3TestList && 670 !g_profile.support_constant_framerate) { 671 printf("[Error] Hal v3 should support constant framerate.\n"); 672 ASSERT_TRUE(false); 673 } 674 675 ASSERT_TRUE(TestResolutions(g_profile.dev_name, g_profile.check_1280x960, 676 g_profile.check_1600x1200, 677 g_profile.cropping_profile, 678 g_profile.check_constant_framerate)); 679 } 680 681 TEST(TestList, TestMaximumSupportedResolution) { 682 if (g_profile.test_list == kCertificationTestList) 683 return; 684 if (g_profile.check_maximum_resolution) { 685 ASSERT_TRUE(TestMaximumSupportedResolution(g_profile.dev_name, 686 g_profile.lens_facing)); 687 } 688 } 689 690 TEST(TestList, TestFirstFrameAfterStreamOn) { 691 if (g_profile.test_list == kDefaultTestList) 692 return; 693 ASSERT_TRUE(TestFirstFrameAfterStreamOn(g_profile.dev_name, 694 g_profile.skip_frames)); 695 } 696 697 int main(int argc, char** argv) { 698 ::testing::InitGoogleTest(&argc, argv); 699 base::CommandLine::Init(argc, argv); 700 base::ShadowingAtExitManager at_exit_manager; 701 702 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 703 DCHECK(cmd_line); 704 705 std::string dev_name = "/dev/video"; 706 std::string usb_info = ""; 707 std::string test_list = kDefaultTestList; 708 709 base::CommandLine::SwitchMap switches = cmd_line->GetSwitches(); 710 for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); 711 it != switches.end(); ++it) { 712 if (it->first == "h" || it->first == "help") { 713 PrintUsage(argc, argv); 714 return EXIT_SUCCESS; 715 } 716 if (it->first == "device") { 717 dev_name = it->second; 718 continue; 719 } 720 if (it->first == "usb-info") { 721 usb_info = it->second; 722 continue; 723 } 724 if (it->first == "test-list") { 725 test_list = it->second; 726 continue; 727 } 728 729 PrintUsage(argc, argv); 730 LOGF(ERROR) << "Unexpected switch: " << it->first << ":" << it->second; 731 return EXIT_FAILURE; 732 } 733 734 g_profile = GetTestProfile(dev_name, usb_info, test_list); 735 736 return RUN_ALL_TESTS(); 737 } 738