// 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 "hal/usb/v4l2_test/media_v4l2_device.h"

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

#include <cassert>
#include <ctime>
#include <string>
#include <utility>

#include "cros-camera/common.h"

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

  if (!S_ISCHR(st.st_mode)) {
    if (show_err) {
      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) {
    if (show_err) {
      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_) {
    if (show_err) {
      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)) {
    if (show_err) {
      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;
    do {
      ret = ReadOneFrame(&buf_index, &data_size);
    } while (ret == 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(henryhsu): 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 =
          reinterpret_cast<uintptr_t>(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) {
    auto ShowCaps = [&](uint32_t caps) {
      if (caps & V4L2_CAP_VIDEO_CAPTURE)
        printf("<<< Info: %s support video capture interface.>>>\n", dev_name_);
      if (caps & V4L2_CAP_VIDEO_OUTPUT)
        printf("<<< Info: %s support video output interface.>>>\n", dev_name_);
      if (caps & V4L2_CAP_VIDEO_OVERLAY)
        printf("<<< Info: %s support video overlay interface.>>>\n", dev_name_);
      if (caps & V4L2_CAP_AUDIO)
        printf("<<< Info: %s support audio i/o interface.>>>\n", dev_name_);
      if (caps & V4L2_CAP_STREAMING)
        printf("<<< Info: %s support streaming i/o interface.>>>\n", dev_name_);
    };
    ShowCaps(cap->capabilities);
    if (cap->capabilities & V4L2_CAP_DEVICE_CAPS) {
      printf(
          "<<< Info: %s support per device capabilities. Dump it as well.>>>\n",
          dev_name_);
      ShowCaps(cap->device_caps);
    }
  }

  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_EQ(res, 0);
  return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
}
