• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PrintUsage(int argc,char ** argv)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 
RunTest(V4L2Device * device,V4L2Device::IOMethod io,uint32_t buffers,uint32_t capture_time_in_sec,uint32_t width,uint32_t height,uint32_t pixfmt,float fps,V4L2Device::ConstantFramerate constant_framerate,uint32_t skip_frames)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 
GetSupportedFormats(V4L2Device * device,SupportedFormats * supported_formats)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 
GetMaximumResolution(const SupportedFormats & formats)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.
FindFormatByResolution(const SupportedFormats & formats,uint32_t width,uint32_t height)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.
FindFormatByFourcc(const SupportedFormats & formats,uint32_t fourcc)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 
GetResolutionForCropping(const SupportedFormats & formats,TestCropping cropping_profile)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.
CheckConstantFramerate(const std::vector<int64_t> & timestamps,float require_fps)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 
TestIO(const std::string & dev_name)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.
TestResolutions(const std::string & dev_name,bool check_1280x960,bool check_1600x1200,TestCropping cropping_profile,bool test_constant_framerate)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 
TestFirstFrameAfterStreamOn(const std::string & dev_name,uint32_t skip_frames)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.
TestMaximumSupportedResolution(const std::string & dev_name,uint32_t facing)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 
GetTestProfile(const std::string & dev_name,const std::string & usb_info,const std::string & test_list)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 
TEST(TestList,TestIO)664 TEST(TestList, TestIO) {
665   ASSERT_TRUE(TestIO(g_profile.dev_name));
666 }
667 
TEST(TestList,TestResolutions)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 
TEST(TestList,TestMaximumSupportedResolution)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 
TEST(TestList,TestFirstFrameAfterStreamOn)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 
main(int argc,char ** argv)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