// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media_v4l2_device.h"

#include <assert.h>
#include <poll.h>
#include <time.h>
#include <sys/stat.h>

#include <string>
#include <utility>

#define CHECK(a) assert(a)
#define MAJOR(dev) (((uint32_t)(dev)) >> 8)
#define MINOR(dev) (((uint32_t)(dev)) & 0xff)
#define V4L2_VIDEO_CAPTURE_MAJOR      81
#define V4L2_VIDEO_CAPTURE_MINOR_MIN  0
#define V4L2_VIDEO_CAPTURE_MINOR_MAX  64

V4L2Device::V4L2Device(const char* dev_name,
                       uint32_t buffers)
    : dev_name_(dev_name),
      io_(IO_METHOD_UNDEFINED),
      fd_(-1),
      v4l2_buffers_(NULL),
      num_buffers_(0),
      min_buffers_(buffers),
      stopped_(false),
      initialized_(false) {
}

V4L2Device::~V4L2Device() {
  if (initialized_) {
    if (stream_on_) {
      StopCapture();
    }
    UninitDevice();
  }
  CloseDevice();
}

bool V4L2Device::OpenDevice() {
  struct stat st;
  if (-1 == stat(dev_name_, &st)) {
    printf("<<< Error: could not find v4l2 device %s: (%d) %s.>>>\n",
           dev_name_, errno, strerror(errno));
    return false;
  }

  if (!S_ISCHR(st.st_mode)) {
    printf("<<< Error: specified v4l2 device %s is not char device.>>>\n",
           dev_name_);
    return false;
  }

  if (MAJOR(st.st_rdev) != V4L2_VIDEO_CAPTURE_MAJOR
      || MINOR(st.st_rdev) >= V4L2_VIDEO_CAPTURE_MINOR_MAX) {
    printf("<<< Error: specified v4l2 device %s is not v4l2 device.>>>\n",
           dev_name_);
    return false;
  }

  fd_ = open(dev_name_, O_RDWR | O_NONBLOCK, 0);
  if (-1 == fd_) {
    printf("<<< Error: specified v4l2 device %s could not be opened.>>>\n",
           dev_name_);
    return false;
  }

  v4l2_capability cap;
  if (!ProbeCaps(&cap))
    return false;

  if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
    printf("<<< Error: %s does not support video capture.>>>\n", dev_name_);
    return false;
  }

  return true;
}

void V4L2Device::CloseDevice() {
  if (fd_ != -1)
    close(fd_);
  fd_ = -1;
}

bool V4L2Device::InitDevice(IOMethod io,
                            uint32_t width,
                            uint32_t height,
                            uint32_t pixfmt,
                            float fps,
                            ConstantFramerate constant_framerate,
                            uint32_t num_skip_frames) {
  io_ = io;

  v4l2_format fmt;
  if (!GetV4L2Format(&fmt))
    return false;

  fmt.fmt.pix.width = width;
  fmt.fmt.pix.height = height;
  fmt.fmt.pix.pixelformat = pixfmt;
  fmt.fmt.pix.field = V4L2_FIELD_NONE;

  if (-1 == DoIoctl(VIDIOC_S_FMT, &fmt)) {
    printf("<<< Error: VIDIOC_S_FMT on %s.>>>\n", dev_name_);
    return false;
  }

  v4l2_capability cap;
  if (!ProbeCaps(&cap))
    return false;

  switch (io_) {
    case IO_METHOD_MMAP:
    case IO_METHOD_USERPTR:
      if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
        printf("<<< Error: %s does not support streaming.>>>\n", dev_name_);
        return false;
      }
      break;
    default:
      printf("<<< Error: IO method should be defined.>>>\n");
      return false;
  }

  v4l2_streamparm param;
  if (!GetParam(&param))
    return false;

  if (param.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
    if (fps > 0) {
      SetFrameRate(fps);
    } else {
      printf("<<< Error: fps %f should be a positive number.>>>\n", fps);
      return false;
    }
  }
  float actual_fps = GetFrameRate();

  int32_t constant_framerate_setting;
  std::string constant_framerate_msg = "";
  switch (constant_framerate) {
    case DEFAULT_FRAMERATE_SETTING:
      constant_framerate_setting = 1;
      break;
    case ENABLE_CONSTANT_FRAMERATE:
      constant_framerate_setting = 0;
      constant_framerate_msg = " with constant framerate";
      break;
    case DISABLE_CONSTANT_FRAMERATE:
      constant_framerate_setting = 1;
      constant_framerate_msg = " without constant framerate";
      break;
    default:
      printf("<<< Error: Invalid constant framerate setting: %d. >>>\n",
          constant_framerate);
      return false;
  }
  SetControl(V4L2_CID_EXPOSURE_AUTO_PRIORITY, constant_framerate_setting);

  printf("actual format for capture %dx%d %c%c%c%c picture at %.2f fps%s\n",
         fmt.fmt.pix.width, fmt.fmt.pix.height,
         (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
         (pixfmt >> 16) & 0xff, (pixfmt >> 24 ) & 0xff, actual_fps,
         constant_framerate_msg.c_str());
  frame_timestamps_.clear();
  num_skip_frames_ = num_skip_frames;

  bool ret = false;
  switch (io_) {
    case IO_METHOD_MMAP:
      ret = InitMmapIO();
      break;
    case IO_METHOD_USERPTR:
      ret = InitUserPtrIO(fmt.fmt.pix.sizeimage);
      break;
    default:
      printf("<<< Error: IO method should be defined.>>>\n");
      return false;
  }
  if (ret)
    initialized_ = true;
  return ret;
}

bool V4L2Device::UninitDevice() {
  if (!initialized_) {
    return true;
  }
  v4l2_requestbuffers req;
  memset(&req, 0, sizeof(req));
  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  switch (io_) {
    case IO_METHOD_MMAP:
      for (uint32_t i = 0; i < num_buffers_; ++i)
        if (-1 == munmap(v4l2_buffers_[i].start, v4l2_buffers_[i].length)) {
          printf("<<< Error: munmap() on %s failed.>>>\n", dev_name_);
          return false;
        }

      req.memory = V4L2_MEMORY_MMAP;
      if (-1 == DoIoctl(VIDIOC_REQBUFS, &req)) {
        printf("<<< Error: VIDIOC_REQBUFS for MMAP failed on %s: %s.>>>\n",
            dev_name_, strerror(errno));
        return false;
      }
      break;
    case IO_METHOD_USERPTR:
      req.memory = V4L2_MEMORY_USERPTR;
      if (-1 == DoIoctl(VIDIOC_REQBUFS, &req)) {
        printf("<<< Error: VIDIOC_REQBUFS for USERPTR failed on %s.: %s>>>\n",
            dev_name_, strerror(errno));
        return false;
      }

      for (uint32_t i = 0; i < num_buffers_; ++i)
        free(v4l2_buffers_[i].start);
      break;
    default:
      printf("<<< Error: IO method should be defined.>>>\n");
      return false;
  }
  FreeBuffer();
  initialized_ = false;
  return true;
}

bool V4L2Device::StartCapture() {
  for (uint32_t i = 0; i < num_buffers_; ++i) {
    if (!EnqueueBuffer(i))
      return false;
  }
  v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  if (-1 == DoIoctl(VIDIOC_STREAMON, &type)) {
    printf("<<< Error: VIDIOC_STREAMON on %s.>>>\n", dev_name_);
    return false;
  }
  stream_on_ = true;

  uint32_t buf_index, data_size;
  for (size_t i = 0; i < num_skip_frames_; i++) {
    int ret;
    while ((ret = ReadOneFrame(&buf_index, &data_size)) == 0);
    if (ret < 0)
      return false;
    if (!EnqueueBuffer(buf_index))
      return false;
  }

  return true;
}

bool V4L2Device::StopCapture() {
  if (!stream_on_) {
    return true;
  }
  v4l2_buf_type type;
  switch (io_) {
    case IO_METHOD_MMAP:
    case IO_METHOD_USERPTR:
      type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      if (-1 == DoIoctl(VIDIOC_STREAMOFF, &type)) {
        printf("<<< Error: VIDIOC_STREAMOFF on %s.>>>\n", dev_name_);
        return false;
      }
      break;
    default:
      printf("<<< Error: IO method should be defined.>>>\n");
      return false;
  }
  stream_on_ = false;
  return true;
}

void V4L2Device::ProcessImage(const void* p) {
  printf(".");
  fflush(stdout);
}

// Do capture for duration of |time_in_sec|.
bool V4L2Device::Run(uint32_t time_in_sec) {
  stopped_ = false;
  if (!time_in_sec)
    return false;

  uint64_t start_in_nanosec = 0;
  uint32_t buffer_index, data_size;
  while (!stopped_) {
    int32_t r = ReadOneFrame(&buffer_index, &data_size);
    if (r < 0)
      return false;
    if (r) {
      if (start_in_nanosec == 0)
        start_in_nanosec = Now();
      ProcessImage(v4l2_buffers_[buffer_index].start);
      if (!EnqueueBuffer(buffer_index))
        return false;
    }
    if (start_in_nanosec) {
      uint64_t end_in_nanosec = Now();
      if (end_in_nanosec - start_in_nanosec >= time_in_sec * 1000000000ULL)
        break;
    }
  }
  // All resolutions should have at least 1 fps.
  float actual_fps = static_cast<float>(GetNumFrames() - 1) / time_in_sec;
  printf("\n<<< Info: Actual fps is %f on %s.>>>\n", actual_fps, dev_name_);
  return true;
}

bool V4L2Device::Stop() {
  stopped_ = true;
  return true;
}

int32_t V4L2Device::DoIoctl(int32_t request, void* arg) {
  int32_t r;
  do {
    r = ioctl(fd_, request, arg);
  } while (-1 == r && EINTR == errno);
  return r;
}

// return 1 : successful to retrieve a frame from device
// return 0 : EAGAIN
// negative : error
int32_t V4L2Device::ReadOneFrame(uint32_t* buffer_index, uint32_t* data_size) {
  const int kCaptureTimeoutMs = 1000;
  pollfd device_pfd = {};
  device_pfd.fd = fd_;
  device_pfd.events = POLLIN;
  const int result = poll(&device_pfd, 1, kCaptureTimeoutMs);
  if (result < 0) {
    printf("<<< Error: poll() failed on %s: %s.>>>\n", dev_name_, strerror(errno));
    return -1;
  }
  if (result == 0) {
    return 0;
  }

  v4l2_buffer buf;
  int64_t ts;
  memset(&buf, 0, sizeof(buf));
  switch (io_) {
    case IO_METHOD_MMAP:
      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory = V4L2_MEMORY_MMAP;
      if (-1 == DoIoctl(VIDIOC_DQBUF, &buf)) {
        switch (errno) {
          case EAGAIN:
            return 0;
          case EIO:
            // Could ignore EIO, see spec.
            // Fall through.
          default:
            printf("<<< Error: VIDIOC_DQBUF failed on %s.>>>\n", dev_name_);
            return -2;
        }
      }
      // For checking constant frame rate, we have to use HW timestamp from
      // v4l2_buffer to get more stable timestamp.
      // Since kerenel after 3.18 have a fix to disable hardware timestamp
      // (https://patchwork.kernel.org/patch/6874491/), we have to manually
      // enable HW timestamp via /sys/module/uvcvideo/parameters/hwtimestamps.
      ts = buf.timestamp.tv_sec * 1000000000LL + buf.timestamp.tv_usec * 1000;
      frame_timestamps_.push_back(ts);
      CHECK(buf.index < num_buffers_);
      // TODO: uvcvideo driver ignores this field. This is negligible,
      // so disabling this for now until we get a fix into the upstream driver.
      // CHECK(buf.field == V4L2_FIELD_NONE);  // progressive only.
      break;
    case IO_METHOD_USERPTR:
      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory = V4L2_MEMORY_USERPTR;
      if (-1 == DoIoctl(VIDIOC_DQBUF, &buf)) {
        switch (errno) {
          case EAGAIN:
            return 0;
          case EIO:
            // Could ignore EIO, see spec.
            // Fall through.
          default:
            printf("<<< Error: VIDIOC_DQBUF failed on %s.>>>\n", dev_name_);
            return -2;
        }
      }
      ts = buf.timestamp.tv_sec * 1000000000LL + buf.timestamp.tv_usec * 1000;
      frame_timestamps_.push_back(ts);
      CHECK(buf.index < num_buffers_);
      break;
    default:
      printf("<<< Error: IO method should be defined.>>>\n");
      return -1;
  }
  if (buffer_index)
    *buffer_index = buf.index;
  if (data_size)
    *data_size = buf.bytesused;
  return 1;
}

bool V4L2Device::EnqueueBuffer(uint32_t buffer_index) {
  v4l2_buffer buf;
  memset(&buf, 0, sizeof(buf));
  switch (io_) {
    case IO_METHOD_MMAP:
      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory = V4L2_MEMORY_MMAP;
      buf.index = buffer_index;
      if (-1 == DoIoctl(VIDIOC_QBUF, &buf)) {
        printf("<<< Error: VIDIOC_QBUF failed on %s.>>>\n", dev_name_);
        return false;
      }
      break;
    case IO_METHOD_USERPTR:
      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory = V4L2_MEMORY_USERPTR;
      buf.index = buffer_index;
      buf.m.userptr = (unsigned long) v4l2_buffers_[buffer_index].start;
      buf.length = v4l2_buffers_[buffer_index].length;
      if (-1 == DoIoctl(VIDIOC_QBUF, &buf)) {
        printf("<<< Error: VIDIOC_QBUF failed on %s.>>>\n", dev_name_);
        return false;
      }
      break;
    default:
      printf("<<< Error: IO method should be defined.>>>\n");
      return false;
  }
  return true;
}

bool V4L2Device::AllocateBuffer(uint32_t buffer_count) {
  v4l2_buffers_ = new Buffer[buffer_count];
  if (!v4l2_buffers_) {
    printf("<<< Error: Out of memory.>>>\n");
    return false;
  }
  return true;
}

bool V4L2Device::FreeBuffer() {
  free(v4l2_buffers_);
  v4l2_buffers_ = NULL;
  return true;
}

bool V4L2Device::InitMmapIO() {
  v4l2_requestbuffers req;
  memset(&req, 0, sizeof(req));
  req.count = min_buffers_;
  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  req.memory = V4L2_MEMORY_MMAP;
  if (-1 == DoIoctl(VIDIOC_REQBUFS, &req)) {
    if (EINVAL == errno)
      printf("<<< Error: mmap() io is not supported on %s.>>>\n", dev_name_);
    else
      printf("<<< Error: VIDIOC_REQBUFS for MMAP(%d) failed on %s: %s.>>>\n",
          min_buffers_, dev_name_, strerror(errno));
    return false;
  }

  if (req.count < min_buffers_) {
    printf("<<< Error: Insufficient buffer memory on %s >>>\n",
            dev_name_);  // TODO(jiesun) :add flexibilities.
    return false;
  }

  if (!AllocateBuffer(req.count))
    return false;

  for (num_buffers_ = 0; num_buffers_ < req.count; ++num_buffers_) {
    v4l2_buffer buf;
    memset(&buf, 0, sizeof(buf));
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    buf.index = num_buffers_;
    if (-1 == DoIoctl(VIDIOC_QUERYBUF, &buf)) {
      printf("<<< Error: VIDIOC_QUERYBUF failed on %s.>>>\n", dev_name_);
      return false;
    }
    v4l2_buffers_[num_buffers_].length = buf.length;
    v4l2_buffers_[num_buffers_].start =
        mmap(NULL,  // Start anywhere.
             buf.length,
             PROT_READ | PROT_WRITE,
             MAP_SHARED,
             fd_, buf.m.offset);
    if (MAP_FAILED == v4l2_buffers_[num_buffers_].start) {
      printf("<<< Error: mmap() failed on %s.>>>\n", dev_name_);
      return false;
    }
  }
  return true;
}

bool V4L2Device::InitUserPtrIO(uint32_t buffer_size) {
  v4l2_requestbuffers req;
  memset(&req, 0, sizeof(req));
  req.count = min_buffers_;
  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  req.memory = V4L2_MEMORY_USERPTR;

  // Align up buffer_size to page size boundary.
  uint32_t page_size = getpagesize();
  buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);
  if (-1 == DoIoctl(VIDIOC_REQBUFS, &req)) {
    if (EINVAL == errno)
      printf("<<< Error: user pointer is not supported on %s.>>>\n", dev_name_);
    else
      printf("<<< Error: VIDIOC_REQBUFS for USERPTR(%d) failed on %s: %s.>>>\n",
          min_buffers_, dev_name_, strerror(errno));
    return false;
  }

  if (!AllocateBuffer(req.count))
    return false;

  for (num_buffers_ = 0; num_buffers_ < req.count; ++num_buffers_) {
    v4l2_buffers_[num_buffers_].length = buffer_size;
    v4l2_buffers_[num_buffers_].start = memalign(page_size, buffer_size);

    if (!v4l2_buffers_[num_buffers_].start) {
      printf("<<< Error: Out of memory.>>>\n");
      return false;
    }
  }
  return true;
}

bool V4L2Device::EnumInput() {
  v4l2_input input;
  int32_t index;
  if (-1 == DoIoctl(VIDIOC_G_INPUT, &index)) {
    printf("<<< Info: VIDIOC_G_INPUT not supported.>>>\n");
    return false;
  }

  for (int32_t i = 0 ; ; ++i) {
    memset(&input, 0, sizeof(input));
    input.index = i;
    if (-1 == DoIoctl(VIDIOC_ENUMINPUT, &input)) {
      if (i == 0) {
        printf("<<< Info: VIDIOC_ENUMINPUT not supported.>>>\n");
        return false;
      } else {
        break;
      }
    }
    printf("Current input: %s %s\n", input.name, i == index ? "*" : "");
  }
  return true;
}

bool V4L2Device::EnumStandard() {
  v4l2_input input;
  v4l2_standard standard;
  memset(&input, 0, sizeof(input));
  if (-1 == DoIoctl(VIDIOC_G_INPUT, &input.index)) {
    printf("<<< Info: VIDIOC_G_INPUT not supported.>>>\n");
    return false;
  }

  if (-1 == DoIoctl(VIDIOC_ENUMINPUT, &input)) {
    printf("<<< Info: VIDIOC_ENUMINPUT not supported.>>>\n");
    return false;
  }

  printf("Current input %s supports:\n", input.name);
  memset(&standard, 0, sizeof(standard));
  standard.index = 0;
  while (0 == DoIoctl(VIDIOC_ENUMSTD, &standard)) {
    if (standard.id & input.std)
      printf("%s\n", standard.name);
    standard.index++;
  }
  // EINVAL indicates the end of the enumeration, which cannot be
  // empty unless this device falls under the USB exception.
  if (errno != EINVAL || standard.index == 0) {
    printf("<<< Info: VIDIOC_ENUMSTD not supported.>>>\n");
    return false;
  }
  return true;
}

bool V4L2Device::EnumControl(bool show_menu) {
  v4l2_queryctrl query_ctrl;
  memset(&query_ctrl, 0, sizeof(query_ctrl));
  // Query V4L2_CID_CAMERA_CLASS_BASE is for V4L2_CID_EXPOSURE_AUTO_PRIORITY.
  std::vector<std::pair<uint32_t, uint32_t>> query_ctrl_sets;
  query_ctrl_sets.push_back(std::make_pair(V4L2_CID_BASE, V4L2_CID_LASTP1));
  query_ctrl_sets.push_back(std::make_pair(V4L2_CID_CAMERA_CLASS_BASE,
                                           V4L2_CID_TILT_SPEED));

  for (int i = 0; i < query_ctrl_sets.size(); i++) {
    for (query_ctrl.id = query_ctrl_sets[i].first;
         query_ctrl.id < query_ctrl_sets[i].second;
         ++query_ctrl.id) {
      if (0 == DoIoctl(VIDIOC_QUERYCTRL, &query_ctrl)) {
        if (query_ctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
            printf("Control %s is disabled\n", query_ctrl.name);
        } else {
            printf("Control %s is enabled(%d-%d:%d)\n",
                   query_ctrl.name, query_ctrl.minimum,
                   query_ctrl.maximum, query_ctrl.default_value);
        }
        if (query_ctrl.type == V4L2_CTRL_TYPE_MENU && show_menu)
          EnumControlMenu(query_ctrl);
      } else if (errno != EINVAL) {
        printf("<<< Info: VIDIOC_query_ctrl not supported.>>>\n");
        return false;
      }
    }
  }

  for (query_ctrl.id = V4L2_CID_PRIVATE_BASE;; query_ctrl.id++) {
    if (0 == DoIoctl(VIDIOC_QUERYCTRL, &query_ctrl)) {
      if (query_ctrl.flags & V4L2_CTRL_FLAG_DISABLED)
        printf("Private Control %s is disabled\n", query_ctrl.name);
      else
        printf("Private Control %s is enabled\n", query_ctrl.name);
      if (query_ctrl.type == V4L2_CTRL_TYPE_MENU && show_menu)
        EnumControlMenu(query_ctrl);
    } else {
      // Assume private control ids are contiguous.
      if (errno == EINVAL)
        break;
      printf("<<< Info: VIDIOC_query_ctrl not supported.>>>\n");
      return false;
    }
  }
  return true;
}

bool V4L2Device::EnumControlMenu(const v4l2_queryctrl& query_ctrl) {
  v4l2_querymenu query_menu;
  memset(&query_menu, 0, sizeof(query_menu));
  printf("\t\tMenu items:\n");
  query_menu.id = query_ctrl.id;
  for (query_menu.index = query_ctrl.minimum;
       query_menu.index <= query_ctrl.maximum;
       ++query_menu.index) {
    if (0 == DoIoctl(VIDIOC_QUERYMENU, &query_menu)) {
      printf("\t\t\t%s\n", query_menu.name);
    } else {
      printf("<<< Info: VIDIOC_QUERYMENU not supported.>>>\n");
      return false;
    }
  }
  return true;
}

bool V4L2Device::EnumFormat(uint32_t* num_formats, bool show_fmt) {
  uint32_t i;
  for (i = 0; ; ++i) {
    v4l2_fmtdesc format_desc;
    memset(&format_desc, 0, sizeof(format_desc));
    format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    format_desc.index = i;
    if (-1 == DoIoctl(VIDIOC_ENUM_FMT, &format_desc)) {
      if (i == 0) {
          printf("<<< Info: VIDIOC_ENUM_FMT not supported.>>>\n");
          return false;
      } else {
          break;
      }
    }
    if (show_fmt)
      printf("<<< Info supported format #%d: %s (%c%c%c%c) >>>\n",
             i+1, format_desc.description,
             (format_desc.pixelformat >> 0) & 0xff,
             (format_desc.pixelformat >> 8) & 0xff,
             (format_desc.pixelformat >> 16) & 0xff,
             (format_desc.pixelformat >> 24) & 0xff);
  }

  if (num_formats)
    *num_formats = i;
  return true;
}

bool V4L2Device::GetPixelFormat(uint32_t index, uint32_t* pixfmt) {
  v4l2_fmtdesc format_desc;
  memset(&format_desc, 0, sizeof(format_desc));
  format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  format_desc.index = index;
  if (-1 == DoIoctl(VIDIOC_ENUM_FMT, &format_desc))
    return false;
  if (pixfmt)
    *pixfmt = format_desc.pixelformat;
  return true;
}

bool V4L2Device::EnumFrameSize(
    uint32_t pixfmt, uint32_t* num_sizes, bool show_frmsize) {
  uint32_t i;
  for (i = 0; ; ++i) {
    v4l2_frmsizeenum frmsize_desc;
    memset(&frmsize_desc, 0, sizeof(frmsize_desc));
    frmsize_desc.pixel_format = pixfmt;
    frmsize_desc.index = i;
    if (-1 == DoIoctl(VIDIOC_ENUM_FRAMESIZES, &frmsize_desc)) {
      if (i == 0) {
        printf("<<< Info: VIDIOC_ENUM_FRAMESIZES not supported.>>>\n");
        return false;
      } else {
        break;
      }
    }
    if (show_frmsize) {
      switch (frmsize_desc.type) {
        case V4L2_FRMSIZE_TYPE_DISCRETE:
          printf("<<< Info supported discrete frame size #%d:"
                 " for pixel format(%c%c%c%c): %dx%d >>>\n", i+1,
                 (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
                 frmsize_desc.discrete.width,
                 frmsize_desc.discrete.height);
          break;
        case V4L2_FRMSIZE_TYPE_CONTINUOUS:
          printf("<<< Info supported discrete frame size #%d:"
                 " for pixel format(%c%c%c%c): "
                 " from %dx%d to %dx%d >>>\n", i+1,
                 (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
                 frmsize_desc.stepwise.min_width,
                 frmsize_desc.stepwise.min_height,
                 frmsize_desc.stepwise.max_width,
                 frmsize_desc.stepwise.max_height);
          break;
        case V4L2_FRMSIZE_TYPE_STEPWISE:
          printf("<<< Info supported discrete frame size #%d:"
                 " for pixel format(%c%c%c%c): "
                 " from %dx%d to %dx%d step(%d,%d) >>>\n", i+1,
                 (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
                 frmsize_desc.stepwise.min_width,
                 frmsize_desc.stepwise.min_height,
                 frmsize_desc.stepwise.max_width,
                 frmsize_desc.stepwise.max_height,
                 frmsize_desc.stepwise.step_width,
                 frmsize_desc.stepwise.step_height);
          break;
      }
    }
  }
  if (num_sizes)
    *num_sizes = i;
  return true;
}

bool V4L2Device::GetFrameSize(
    uint32_t index, uint32_t pixfmt, uint32_t *width, uint32_t *height) {
  v4l2_frmsizeenum frmsize_desc;
  memset(&frmsize_desc, 0, sizeof(frmsize_desc));
  frmsize_desc.pixel_format = pixfmt;
  frmsize_desc.index = index;
  if (-1 == DoIoctl(VIDIOC_ENUM_FRAMESIZES, &frmsize_desc)) {
    printf("<<< Error: VIDIOC_ENUM_FRAMESIZES not supported.>>>\n");
    return false;
  }
  if (frmsize_desc.type != V4L2_FRMSIZE_TYPE_DISCRETE) {
    printf("<<< Error: frame size type %d not supported.>>>\n",
           frmsize_desc.type);
    return false;
  }

  if (width && height) {
    *width = frmsize_desc.discrete.width;
    *height = frmsize_desc.discrete.height;
  }
  return true;
}

bool V4L2Device::EnumFrameInterval(
    uint32_t pixfmt, uint32_t width, uint32_t height, uint32_t* num_intervals,
    bool show_intervals) {
  uint32_t i;
  for (i = 0; ; ++i) {
    v4l2_frmivalenum frm_interval;
    memset(&frm_interval, 0, sizeof(frm_interval));
    frm_interval.pixel_format = pixfmt;
    frm_interval.width = width;
    frm_interval.height = height;
    frm_interval.index = i;
    if (-1 == DoIoctl(VIDIOC_ENUM_FRAMEINTERVALS, &frm_interval)) {
      if (i == 0) {
        printf("<<< Error: VIDIOC_ENUM_FRAMEINTERVALS not supported.>>>\n");
        return false;
      } else {
        break;
      }
    }
    if (show_intervals) {
      switch(frm_interval.type) {
        case V4L2_FRMIVAL_TYPE_DISCRETE:
          printf("<<< Info supported discrete frame interval #%d:"
                 " for pixel format(%c%c%c%c): %dx%d: %d/%d >>>\n", i+1,
                 (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
                 width, height, frm_interval.discrete.numerator,
                 frm_interval.discrete.denominator);
          break;
        case V4L2_FRMIVAL_TYPE_CONTINUOUS:
          printf("<<< Info supported continuous frame interval #%d:"
                 " for pixel format(%c%c%c%c): %dx%d:"
                 " from %d/%d to %d/%d >>>\n", i+1,
                 (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
                 width, height,
                 frm_interval.stepwise.min.numerator,
                 frm_interval.stepwise.min.denominator,
                 frm_interval.stepwise.max.numerator,
                 frm_interval.stepwise.max.denominator);
          break;
        case V4L2_FRMIVAL_TYPE_STEPWISE:
          printf("<<< Info supported stepwise frame interval #%d:"
                 " for pixel format(%c%c%c%c): %dx%d:"
                 " from %d/%d to %d/%d step(%d,%d) >>>\n", i+1,
                 (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
                 width, height,
                 frm_interval.stepwise.min.numerator,
                 frm_interval.stepwise.min.denominator,
                 frm_interval.stepwise.max.numerator,
                 frm_interval.stepwise.max.denominator,
                 frm_interval.stepwise.step.numerator,
                 frm_interval.stepwise.step.denominator);
          break;
        default:
          printf("<<< Error: unsupported frame interval type %d: for index %d"
                 " pixel format(%c%c%c%c): %dx%d >>>\n", frm_interval.type,
                 i+1, (pixfmt >> 0) & 0xff, (pixfmt >> 8) & 0xff,
                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff, width, height);
          return false;
      }
    }
  }
  if (num_intervals)
    *num_intervals = i;
  return true;
}

bool V4L2Device::GetFrameInterval(
    uint32_t index, uint32_t pixfmt, uint32_t width, uint32_t height,
    float* frame_rate) {
  v4l2_frmivalenum frm_interval;
  memset(&frm_interval, 0, sizeof(frm_interval));
  frm_interval.pixel_format = pixfmt;
  frm_interval.width = width;
  frm_interval.height = height;
  frm_interval.index = index;
  if (-1 == DoIoctl(VIDIOC_ENUM_FRAMEINTERVALS, &frm_interval)) {
    printf("<<< Error: VIDIOC_ENUM_FRAMEINTERVALS not supported.>>>\n");
    return false;
  }
  if (frm_interval.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
    printf("<<< Error: frame interval type %d not supported.>>>\n",
           frm_interval.type);
    return false;
  }

  if (frame_rate) {
    *frame_rate = static_cast<float>(frm_interval.discrete.denominator) /
        frm_interval.discrete.numerator;
  }
  return true;
}

bool V4L2Device::QueryControl(uint32_t id, v4l2_queryctrl* ctrl) {
  memset(ctrl, 0, sizeof(*ctrl));
  ctrl->id = id;
  if (-1 == DoIoctl(VIDIOC_QUERYCTRL, ctrl)) {
    if (errno != EINVAL) return false;
    printf("%d is not supported\n", id);
    return false;
  }
  if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) {
    printf("%d is not supported\n", id);
    return false;
  }
  return true;
}

bool V4L2Device::SetControl(uint32_t id, int32_t value) {
  v4l2_control control;
  control.id = id;
  control.value = value;
  if (-1 == DoIoctl(VIDIOC_S_CTRL, &control)) {
    printf("<<< Error: VIDIOC_S_CTRL failed. %d>>>\n", errno);
    return false;
  }
  return true;
}

bool V4L2Device::GetCropCap(v4l2_cropcap* cropcap) {
  if (-1 == DoIoctl(VIDIOC_CROPCAP, cropcap)) {
    printf("<<< Warning: VIDIOC_CROPCAP not supported.>>>\n");
    return false;
  }
  return true;
}

bool V4L2Device::GetCrop(v4l2_crop* crop) {
  if (-1 == DoIoctl(VIDIOC_G_CROP, crop)) {
    printf("<<< Warning: VIDIOC_G_CROP not supported.>>>\n");
    return false;
  }
  printf("crop: %d, %d, %d, %d\n",
         crop->c.left, crop->c.top,
         crop->c.width, crop->c.height);
  return true;
}

bool V4L2Device::SetCrop(v4l2_crop* crop) {
  if (-1 == DoIoctl(VIDIOC_S_CROP, crop)) {
    printf("<<< Warning: VIDIOC_S_CROP not supported.>>>\n");
    return false;
  }
  return true;
}

bool V4L2Device::ProbeCaps(v4l2_capability* cap, bool show_caps) {
  if (-1 == DoIoctl(VIDIOC_QUERYCAP, cap)) {
    printf("<<< Error: VIDIOC_QUERYCAP on %s.>>>\n", dev_name_);
    return false;
  }

  if (show_caps) {
    if (cap->capabilities & V4L2_CAP_VIDEO_CAPTURE)
      printf("<<< Info: %s support video capture interface.>>>\n", dev_name_);
    if (cap->capabilities & V4L2_CAP_VIDEO_OUTPUT)
      printf("<<< Info: %s support video output interface.>>>\n", dev_name_);
    if (cap->capabilities & V4L2_CAP_VIDEO_OVERLAY)
      printf("<<< Info: %s support video overlay interface.>>>\n", dev_name_);
    if (cap->capabilities & V4L2_CAP_AUDIO)
      printf("<<< Info: %s support audio i/o interface.>>>\n", dev_name_);

    if (cap->capabilities & V4L2_CAP_STREAMING)
      printf("<<< Info: %s support streaming i/o interface.>>>\n", dev_name_);
  }

  return true;
}

uint32_t V4L2Device::MapFourCC(const char* fourcc) {
  return v4l2_fourcc(fourcc[0], fourcc[1], fourcc[2], fourcc[3]);
}

bool V4L2Device::GetParam(v4l2_streamparm* param) {
  param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  if (-1 == DoIoctl(VIDIOC_G_PARM, param)) {
    printf("<<< Warning: VIDIOC_G_PARM not supported.>>>\n");
    return false;
  }

  return true;
}

bool V4L2Device::SetParam(v4l2_streamparm* param) {
  if (-1 == DoIoctl(VIDIOC_S_PARM, param)) {
    printf("<<< Warning: VIDIOC_S_PARM not supported.>>>\n");
    return false;
  }
  return true;
}

bool V4L2Device::SetFrameRate(float fps) {
  v4l2_streamparm param;
  if (!GetParam(&param))
    return false;

  const int kFrameRatePrecision = 10000;
  param.parm.capture.timeperframe.numerator = kFrameRatePrecision;
  param.parm.capture.timeperframe.denominator = fps * kFrameRatePrecision;
  return SetParam(&param);
}

float V4L2Device::GetFrameRate() {
  v4l2_streamparm param;
  if (!GetParam(&param))
    return -1;
  return static_cast<float>(param.parm.capture.timeperframe.denominator) /
      param.parm.capture.timeperframe.numerator;
}

bool V4L2Device::GetV4L2Format(v4l2_format* format) {
  memset(format, 0, sizeof(v4l2_format));
  format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  if (-1 == DoIoctl(VIDIOC_G_FMT, format)) {
    printf("<<< Error: VIDIOC_G_FMT on %s.>>>\n", dev_name_);
    return false;
  }
  return true;
}

uint64_t V4L2Device::Now() {
  struct timespec ts;
  int res = clock_gettime(CLOCK_MONOTONIC, &ts);
  CHECK(res == 0);
  return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
}
