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 #ifndef MEDIA_V4L2_DEVICE_H_
      6 #define MEDIA_V4L2_DEVICE_H_
      7 
      8 #include <errno.h>
      9 #include <fcntl.h>
     10 #include <linux/videodev2.h>
     11 #include <malloc.h>
     12 #include <stdint.h>
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 #include <sys/ioctl.h>
     17 #include <sys/mman.h>
     18 #include <unistd.h>
     19 
     20 #include <vector>
     21 
     22 class V4L2Device {
     23  public:
     24   enum IOMethod {
     25     IO_METHOD_UNDEFINED,
     26     IO_METHOD_MMAP,
     27     IO_METHOD_USERPTR,
     28   };
     29 
     30   enum ConstantFramerate {
     31     DEFAULT_FRAMERATE_SETTING,
     32     ENABLE_CONSTANT_FRAMERATE,
     33     DISABLE_CONSTANT_FRAMERATE,
     34   };
     35 
     36   struct Buffer {
     37     void* start;
     38     size_t length;
     39   };
     40 
     41   V4L2Device(const char* dev_name,
     42              uint32_t buffers);
     43   virtual ~V4L2Device();
     44 
     45   virtual bool OpenDevice();
     46   virtual void CloseDevice();
     47   // After this function is called, the driver may adjust the settings if they
     48   // are unsupported.  Caller can use GetV4L2Format() and GetFrameRate() to know
     49   // the actual settings.  If V4L2_CAP_TIMEPERFRAME is unsupported, fps will be
     50   // ignored.
     51   virtual bool InitDevice(IOMethod io,
     52                           uint32_t width,
     53                           uint32_t height,
     54                           uint32_t pixfmt,
     55                           float fps,
     56                           ConstantFramerate constant_framerate,
     57                           uint32_t num_skip_frames);
     58   virtual bool UninitDevice();
     59   virtual bool StartCapture();
     60   virtual bool StopCapture();
     61   virtual bool Run(uint32_t time_in_sec);
     62   virtual int32_t ReadOneFrame(uint32_t* buffer_index, uint32_t* data_size);
     63   virtual bool EnqueueBuffer(uint32_t buffer_index);
     64 
     65   // Helper methods.
     66   bool EnumInput();
     67   bool EnumStandard();
     68   bool EnumControl(bool show_menu = true);
     69   bool EnumControlMenu(const v4l2_queryctrl& query_ctrl);
     70   bool EnumFormat(uint32_t* num_formats, bool show_fmt = true);
     71   bool EnumFrameSize(
     72       uint32_t pixfmt, uint32_t* num_sizes, bool show_frmsize = true);
     73   bool EnumFrameInterval(uint32_t pixfmt, uint32_t width, uint32_t height,
     74                          uint32_t* num_intervals, bool show_intervals = true);
     75 
     76   bool QueryControl(uint32_t id, v4l2_queryctrl* ctrl);
     77   bool SetControl(uint32_t id, int32_t value);
     78   bool ProbeCaps(v4l2_capability* cap, bool show_caps = false);
     79   bool GetCropCap(v4l2_cropcap* cropcap);
     80   bool GetCrop(v4l2_crop* crop);
     81   bool SetCrop(v4l2_crop* crop);
     82   bool GetParam(v4l2_streamparm* param);
     83   bool SetParam(v4l2_streamparm* param);
     84   bool SetFrameRate(float fps);
     85   bool GetPixelFormat(uint32_t index, uint32_t* pixfmt);
     86   bool GetFrameSize(
     87       uint32_t index, uint32_t pixfmt, uint32_t *width, uint32_t *height);
     88   bool GetFrameInterval(
     89       uint32_t index, uint32_t pixfmt, uint32_t width, uint32_t height,
     90       float* frame_rate);
     91   float GetFrameRate();
     92   bool GetV4L2Format(v4l2_format* format);
     93   bool Stop();
     94 
     95   // Getter.
     96   uint32_t GetNumFrames() const { return frame_timestamps_.size(); }
     97 
     98   const std::vector<int64_t>& GetFrameTimestamps() const {
     99     return frame_timestamps_;
    100   }
    101 
    102   const Buffer& GetBufferInfo(uint32_t index) {
    103     return v4l2_buffers_[index];
    104   }
    105 
    106   static uint32_t MapFourCC(const char* fourcc);
    107 
    108   virtual void ProcessImage(const void* p);
    109 
    110  private:
    111   int32_t DoIoctl(int32_t request, void* arg);
    112   bool InitMmapIO();
    113   bool InitUserPtrIO(uint32_t buffer_size);
    114   bool AllocateBuffer(uint32_t buffer_count);
    115   bool FreeBuffer();
    116   uint64_t Now();
    117 
    118   const char* dev_name_;
    119   IOMethod io_;
    120   int32_t fd_;
    121   Buffer* v4l2_buffers_;
    122   uint32_t num_buffers_;  // Actual buffers allocation.
    123   uint32_t min_buffers_;  // Minimum buffers requirement.
    124   bool stopped_;
    125 
    126   // Sets to true when buffers are initialized.
    127   bool initialized_;
    128   // Sets to true if stream on.
    129   bool stream_on_;
    130   std::vector<int64_t> frame_timestamps_;
    131   // The number of frames should be skipped after stream on.
    132   uint32_t num_skip_frames_;
    133 };
    134 
    135 #endif  // MEDIA_V4L2_DEVICE_H_
    136