Home | History | Annotate | Download | only in src
      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