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 
      7 #include <string>
      8 
      9 #include "media_v4l2_device.h"
     10 
     11 void ExerciseControl(V4L2Device* v4l2_dev, uint32_t id, const char* control) {
     12   v4l2_queryctrl query_ctrl;
     13   if (v4l2_dev->QueryControl(id, &query_ctrl)) {
     14     if (!v4l2_dev->SetControl(id, query_ctrl.maximum))
     15       printf("[Warning] Can not set %s to maximum value\n", control);
     16     if (!v4l2_dev->SetControl(id, query_ctrl.minimum))
     17       printf("[Warning] Can not set %s to minimum value\n", control);
     18     if (!v4l2_dev->SetControl(id, query_ctrl.default_value))
     19       printf("[Warning] Can not set %s to default value\n", control);
     20   } else {
     21     printf("[Warning] Can not query control name :%s\n", control);
     22   }
     23 }
     24 
     25 void TestMultipleOpen(const char* dev_name, V4L2Device::IOMethod io) {
     26   V4L2Device v4l2_dev1(dev_name, io, 4);
     27   V4L2Device v4l2_dev2(dev_name, io, 4);
     28   if (!v4l2_dev1.OpenDevice()) {
     29     printf("[Error] Can not open device '%s' for the first time\n", dev_name);
     30   }
     31   if (!v4l2_dev2.OpenDevice()) {
     32     printf("[Error] Can not open device '%s' for the second time\n", dev_name);
     33     exit(EXIT_FAILURE);
     34   }
     35   v4l2_dev1.CloseDevice();
     36   v4l2_dev2.CloseDevice();
     37   printf("[OK ] V4L2DeviceTest.MultipleOpen\n");
     38 }
     39 
     40 void TestMultipleInit(const char* dev_name, V4L2Device::IOMethod io) {
     41   V4L2Device v4l2_dev1(dev_name, io, 4);
     42   V4L2Device v4l2_dev2(dev_name, io, 4);
     43   if (!v4l2_dev1.OpenDevice()) {
     44     printf("[Error] Can not open device '%s' for the first time\n", dev_name);
     45   }
     46   if (!v4l2_dev2.OpenDevice()) {
     47     printf("[Error] Can not open device '%s' for the second time\n", dev_name);
     48   }
     49 
     50   if (!v4l2_dev1.InitDevice(640, 480, V4L2_PIX_FMT_YUYV, 0)) {
     51     printf("[Error] Can not init device '%s' for the first time\n", dev_name);
     52   }
     53 
     54   // multiple streaming request should fail.
     55   if (v4l2_dev2.InitDevice(640, 480, V4L2_PIX_FMT_YUYV, 0)) {
     56     printf("[Error] Multiple init device '%s' should fail\n", dev_name);
     57     exit(EXIT_FAILURE);
     58   }
     59 
     60   v4l2_dev1.UninitDevice();
     61   v4l2_dev2.UninitDevice();
     62   v4l2_dev1.CloseDevice();
     63   v4l2_dev2.CloseDevice();
     64   printf("[OK ] V4L2DeviceTest.MultipleInit\n");
     65 }
     66 
     67 void TestEnumInputAndStandard(const char* dev_name, V4L2Device::IOMethod io) {
     68   V4L2Device v4l2_dev1(dev_name, io, 4);
     69   if (!v4l2_dev1.OpenDevice()) {
     70     printf("[Error] Can not open device '%s'\n", dev_name);
     71   }
     72   v4l2_dev1.EnumInput();
     73   v4l2_dev1.EnumStandard();
     74   v4l2_dev1.CloseDevice();
     75   printf("[OK ] V4L2DeviceTest.EnumInputAndStandard\n");
     76 }
     77 
     78 void TestEnumControl(const char* dev_name, V4L2Device::IOMethod io) {
     79   V4L2Device v4l2_dev(dev_name, io, 4);
     80   if (!v4l2_dev.OpenDevice()) {
     81     printf("[Error] Can not open device '%s'\n", dev_name);
     82   }
     83   v4l2_dev.EnumControl();
     84   v4l2_dev.CloseDevice();
     85   printf("[OK ] V4L2DeviceTest.EnumControl\n");
     86 }
     87 
     88 void TestSetControl(const char* dev_name, V4L2Device::IOMethod io) {
     89   V4L2Device v4l2_dev(dev_name, io, 4);
     90   if (!v4l2_dev.OpenDevice()) {
     91     printf("[Error] Can not open device '%s'\n", dev_name);
     92   }
     93   ExerciseControl(&v4l2_dev, V4L2_CID_BRIGHTNESS, "brightness");
     94   ExerciseControl(&v4l2_dev, V4L2_CID_CONTRAST, "contrast");
     95   ExerciseControl(&v4l2_dev, V4L2_CID_SATURATION, "saturation");
     96   ExerciseControl(&v4l2_dev, V4L2_CID_GAMMA, "gamma");
     97   ExerciseControl(&v4l2_dev, V4L2_CID_HUE, "hue");
     98   ExerciseControl(&v4l2_dev, V4L2_CID_GAIN, "gain");
     99   ExerciseControl(&v4l2_dev, V4L2_CID_SHARPNESS, "sharpness");
    100   v4l2_dev.CloseDevice();
    101   printf("[OK ] V4L2DeviceTest.SetControl\n");
    102 }
    103 
    104 void TestSetCrop(const char* dev_name, V4L2Device::IOMethod io) {
    105   V4L2Device v4l2_dev(dev_name, io, 4);
    106   if (!v4l2_dev.OpenDevice()) {
    107     printf("[Error] Can not open device '%s'\n", dev_name);
    108   }
    109   v4l2_cropcap cropcap;
    110   memset(&cropcap, 0, sizeof(cropcap));
    111   if (v4l2_dev.GetCropCap(&cropcap)) {
    112     v4l2_crop crop;
    113     memset(&crop, 0, sizeof(crop));
    114     crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    115     crop.c = cropcap.defrect;
    116     v4l2_dev.SetCrop(&crop);
    117   }
    118   v4l2_dev.CloseDevice();
    119   printf("[OK ] V4L2DeviceTest.SetCrop\n");
    120 }
    121 
    122 void TestGetCrop(const char* dev_name, V4L2Device::IOMethod io) {
    123   V4L2Device v4l2_dev(dev_name, io, 4);
    124   if (!v4l2_dev.OpenDevice()) {
    125     printf("[Error] Can not open device '%s'\n", dev_name);
    126   }
    127   v4l2_crop crop;
    128   memset(&crop, 0, sizeof(crop));
    129   crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    130   v4l2_dev.GetCrop(&crop);
    131   v4l2_dev.CloseDevice();
    132   printf("[OK ] V4L2DeviceTest.GetCrop\n");
    133 }
    134 
    135 void TestProbeCaps(const char* dev_name, V4L2Device::IOMethod io) {
    136   V4L2Device v4l2_dev(dev_name, io, 4);
    137   if (!v4l2_dev.OpenDevice()) {
    138     printf("[Error] Can not open device '%s'\n", dev_name);
    139   }
    140   v4l2_capability caps;
    141   if (!v4l2_dev.ProbeCaps(&caps, true)) {
    142     printf("[Error] Can not probe caps on device '%s'\n", dev_name);
    143   }
    144   v4l2_dev.CloseDevice();
    145   printf("[OK ] V4L2DeviceTest.ProbeCaps\n");
    146 }
    147 
    148 void TestEnumFormats(const char* dev_name, V4L2Device::IOMethod io) {
    149   V4L2Device v4l2_dev(dev_name, io, 4);
    150   if (!v4l2_dev.OpenDevice()) {
    151     printf("[Error] Can not open device '%s'\n", dev_name);
    152   }
    153   v4l2_dev.EnumFormat(NULL);
    154   v4l2_dev.CloseDevice();
    155   printf("[OK ] V4L2DeviceTest.EnumFormats\n");
    156 }
    157 
    158 void TestEnumFrameSize(const char* dev_name, V4L2Device::IOMethod io) {
    159   V4L2Device v4l2_dev(dev_name, io, 4);
    160   if (!v4l2_dev.OpenDevice()) {
    161     printf("[Error] Can not open device '%s'\n", dev_name);
    162   }
    163   uint32_t format_count = 0;
    164   v4l2_dev.EnumFormat(&format_count);
    165   for (uint32_t i = 0; i < format_count; ++i) {
    166     uint32_t pixfmt = v4l2_dev.GetPixelFormat(i);
    167     if (pixfmt == 0xFFFFFFFF) {
    168       printf("[Error] Enumerate format error on device '%s'\n", dev_name);
    169       exit(EXIT_FAILURE);
    170     }
    171     if (!v4l2_dev.EnumFrameSize(pixfmt)) {
    172       printf("[Warning] Enumerate frame size error on device '%s'\n", dev_name);
    173     };
    174   }
    175   v4l2_dev.CloseDevice();
    176   printf("[OK ] V4L2DeviceTest.EnumFrameSize\n");
    177 }
    178 
    179 void TestFrameRate(const char* dev_name, V4L2Device::IOMethod io) {
    180   V4L2Device v4l2_dev(dev_name, io, 4);
    181   if (!v4l2_dev.OpenDevice()) {
    182     printf("[Error] Can not open device '%s'\n", dev_name);
    183   }
    184   v4l2_capability caps;
    185   if (!v4l2_dev.ProbeCaps(&caps, true)) {
    186     printf("[Error] Can not probe caps on device '%s'\n", dev_name);
    187     exit(EXIT_FAILURE);
    188   }
    189   // we only try to adjust frame rate when it claims can.
    190   if (caps.capabilities & V4L2_CAP_TIMEPERFRAME) {
    191     v4l2_streamparm param;
    192     if (!v4l2_dev.GetParam(&param)) {
    193       printf("[Error] Can not get stream param on device '%s'\n", dev_name);
    194       exit(EXIT_FAILURE);
    195     }
    196     if (!v4l2_dev.SetParam(&param)) {
    197       printf("[Error] Can not set stream param on device '%s'\n", dev_name);
    198       exit(EXIT_FAILURE);
    199     }
    200 
    201     if (!v4l2_dev.SetFrameRate(15)) {
    202       printf("[Error] SetFrameRate failed on '%s'\n", dev_name);
    203       exit(EXIT_FAILURE);
    204     }
    205     if (!v4l2_dev.GetParam(&param)) {
    206       printf("[Error] Can not get stream param on device '%s'\n", dev_name);
    207       exit(EXIT_FAILURE);
    208     }
    209     if (param.parm.capture.timeperframe.denominator !=
    210               param.parm.capture.timeperframe.numerator * 15) {
    211       printf("[Error] Can not set frame rate to 15 on '%s'\n", dev_name);
    212       exit(EXIT_FAILURE);
    213     }
    214 
    215     if (!v4l2_dev.SetFrameRate(10)) {
    216       printf("[Error] SetFrameRate failed on '%s'\n", dev_name);
    217       exit(EXIT_FAILURE);
    218     }
    219     if (!v4l2_dev.GetParam(&param)) {
    220       printf("[Error] Can not get stream param on device '%s'\n", dev_name);
    221       exit(EXIT_FAILURE);
    222     }
    223     if (param.parm.capture.timeperframe.denominator !=
    224               param.parm.capture.timeperframe.numerator * 10) {
    225       printf("[Error] Can not set frame rate to 10 on '%s'\n", dev_name);
    226       exit(EXIT_FAILURE);
    227     }
    228   }
    229 
    230   v4l2_dev.CloseDevice();
    231   printf("[OK ] V4L2DeviceTest.FrameRate\n");
    232 }
    233 
    234 static void PrintUsage() {
    235   printf("Usage: media_v4l2_unittest [options]\n\n"
    236          "Options:\n"
    237          "--device=DEVICE_NAME   Video device name [/dev/video]\n"
    238          "--help                 Print usage\n"
    239          "--buffer-io=mmap       Use memory mapped buffers\n"
    240          "--buffer-io=read       Use read() calls\n"
    241          "--buffer-io=userp      Use application allocated buffers\n");
    242 }
    243 
    244 static const char short_options[] = "d:?b";
    245 static const struct option long_options[] = {
    246         { "device",       required_argument, NULL, 'd' },
    247         { "help",         no_argument,       NULL, '?' },
    248         { "buffer-io",    required_argument, NULL, 'b' },
    249 };
    250 
    251 int main(int argc, char** argv) {
    252   std::string dev_name = "/dev/video", io_name;
    253   V4L2Device::IOMethod io = V4L2Device::IO_METHOD_MMAP;
    254 
    255   // Parse the command line.
    256   for (;;) {
    257     int32_t index;
    258     int32_t c = getopt_long(argc, argv, short_options, long_options, &index);
    259     if (-1 == c)
    260       break;
    261     switch (c) {
    262       case 0:  // getopt_long() flag.
    263         break;
    264       case 'd':
    265         // Initialize default v4l2 device name.
    266         dev_name = strdup(optarg);
    267         break;
    268       case '?':
    269         PrintUsage();
    270         exit (EXIT_SUCCESS);
    271       case 'b':
    272         io_name = strdup(optarg);
    273         if (io_name == "mmap") {
    274           io = V4L2Device::IO_METHOD_MMAP;
    275         } else if (io_name == "read") {
    276           io = V4L2Device::IO_METHOD_READ;
    277         } else if (io_name == "userp") {
    278           io = V4L2Device::IO_METHOD_USERPTR;
    279         } else {
    280           PrintUsage();
    281           exit(EXIT_FAILURE);
    282         }
    283         break;
    284       default:
    285         PrintUsage();
    286         exit(EXIT_FAILURE);
    287     }
    288   }
    289 
    290   TestMultipleOpen(dev_name.c_str(), io);
    291   TestMultipleInit(dev_name.c_str(), io);
    292   TestEnumInputAndStandard(dev_name.c_str(), io);
    293   TestEnumControl(dev_name.c_str(), io);
    294   TestSetControl(dev_name.c_str(), io);
    295   TestSetCrop(dev_name.c_str(), io);
    296   TestGetCrop(dev_name.c_str(), io);
    297   TestProbeCaps(dev_name.c_str(), io);
    298   TestEnumFormats(dev_name.c_str(), io);
    299   TestEnumFrameSize(dev_name.c_str(), io);
    300   TestFrameRate(dev_name.c_str(), io);
    301 }
    302 
    303