/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/video_capture/linux/video_capture_v4l2.h"

#include <fcntl.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <unistd.h>

#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <new>

#include "api/sequence_checker.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "media/base/video_common.h"
#include "modules/video_capture/video_capture_defines.h"
#include "modules/video_capture/video_capture_impl.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/synchronization/mutex.h"
#include "system_wrappers/include/clock.h"

// These defines are here to support building on kernel 3.16 which some
// downstream projects, e.g. Firefox, use.
// TODO(apehrson): Remove them and their undefs when no longer needed.
#ifndef V4L2_PIX_FMT_ABGR32
#define ABGR32_OVERRIDE 1
#define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4')
#endif

#ifndef V4L2_PIX_FMT_ARGB32
#define ARGB32_OVERRIDE 1
#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4')
#endif

#ifndef V4L2_PIX_FMT_RGBA32
#define RGBA32_OVERRIDE 1
#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4')
#endif

namespace webrtc {
namespace videocapturemodule {
VideoCaptureModuleV4L2::VideoCaptureModuleV4L2(Clock* clock)
    : VideoCaptureImpl(clock),
      _deviceId(-1),
      _deviceFd(-1),
      _buffersAllocatedByDevice(-1),
      _captureStarted(false),
      _pool(nullptr) {}

int32_t VideoCaptureModuleV4L2::Init(const char* deviceUniqueIdUTF8) {
  RTC_DCHECK_RUN_ON(&api_checker_);

  int len = strlen((const char*)deviceUniqueIdUTF8);
  _deviceUniqueId = new (std::nothrow) char[len + 1];
  if (_deviceUniqueId) {
    memcpy(_deviceUniqueId, deviceUniqueIdUTF8, len + 1);
  }

  int fd;
  char device[32];
  bool found = false;

  /* detect /dev/video [0-63] entries */
  int n;
  for (n = 0; n < 64; n++) {
    snprintf(device, sizeof(device), "/dev/video%d", n);
    if ((fd = open(device, O_RDONLY)) != -1) {
      // query device capabilities
      struct v4l2_capability cap;
      if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == 0) {
        if (cap.bus_info[0] != 0) {
          if (strncmp((const char*)cap.bus_info,
                      (const char*)deviceUniqueIdUTF8,
                      strlen((const char*)deviceUniqueIdUTF8)) ==
              0) {  // match with device id
            close(fd);
            found = true;
            break;  // fd matches with device unique id supplied
          }
        }
      }
      close(fd);  // close since this is not the matching device
    }
  }
  if (!found) {
    RTC_LOG(LS_INFO) << "no matching device found";
    return -1;
  }
  _deviceId = n;  // store the device id
  return 0;
}

VideoCaptureModuleV4L2::~VideoCaptureModuleV4L2() {
  RTC_DCHECK_RUN_ON(&api_checker_);

  StopCapture();

  RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
  if (_deviceFd != -1)
    close(_deviceFd);
}

int32_t VideoCaptureModuleV4L2::StartCapture(
    const VideoCaptureCapability& capability) {
  RTC_DCHECK_RUN_ON(&api_checker_);

  if (_captureStarted) {
    if (capability == _requestedCapability) {
      return 0;
    } else {
      StopCapture();
    }
  }

  // We don't want members above to be guarded by capture_checker_ as
  // it's meant to be for members that are accessed on the API thread
  // only when we are not capturing. The code above can be called many
  // times while sharing instance of VideoCaptureV4L2 between websites
  // and therefore it would not follow the requirements of this checker.
  {
    RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);

    // Set a baseline of configured parameters. It is updated here during
    // configuration, then read from the capture thread.
    configured_capability_ = capability;

    MutexLock lock(&capture_lock_);
    // first open /dev/video device
    char device[20];
    snprintf(device, sizeof(device), "/dev/video%d", _deviceId);

    if ((_deviceFd = open(device, O_RDWR | O_NONBLOCK, 0)) < 0) {
      RTC_LOG(LS_INFO) << "error in opening " << device
                       << " errono = " << errno;
      return -1;
    }

    // Supported video formats in preferred order.
    // If the requested resolution is larger than VGA, we prefer MJPEG. Go for
    // I420 otherwise.
    unsigned int hdFmts[] = {
        V4L2_PIX_FMT_MJPEG,  V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YVU420,
        V4L2_PIX_FMT_YUYV,   V4L2_PIX_FMT_UYVY,   V4L2_PIX_FMT_NV12,
        V4L2_PIX_FMT_ABGR32, V4L2_PIX_FMT_ARGB32, V4L2_PIX_FMT_RGBA32,
        V4L2_PIX_FMT_BGR32,  V4L2_PIX_FMT_RGB32,  V4L2_PIX_FMT_BGR24,
        V4L2_PIX_FMT_RGB24,  V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_JPEG,
    };
    unsigned int sdFmts[] = {
        V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_YUYV,
        V4L2_PIX_FMT_UYVY,   V4L2_PIX_FMT_NV12,   V4L2_PIX_FMT_ABGR32,
        V4L2_PIX_FMT_ARGB32, V4L2_PIX_FMT_RGBA32, V4L2_PIX_FMT_BGR32,
        V4L2_PIX_FMT_RGB32,  V4L2_PIX_FMT_BGR24,  V4L2_PIX_FMT_RGB24,
        V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_MJPEG,  V4L2_PIX_FMT_JPEG,
    };
    const bool isHd = capability.width > 640 || capability.height > 480;
    unsigned int* fmts = isHd ? hdFmts : sdFmts;
    static_assert(sizeof(hdFmts) == sizeof(sdFmts));
    constexpr int nFormats = sizeof(hdFmts) / sizeof(unsigned int);

    // Enumerate image formats.
    struct v4l2_fmtdesc fmt;
    int fmtsIdx = nFormats;
    memset(&fmt, 0, sizeof(fmt));
    fmt.index = 0;
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    RTC_LOG(LS_INFO) << "Video Capture enumerats supported image formats:";
    while (ioctl(_deviceFd, VIDIOC_ENUM_FMT, &fmt) == 0) {
      RTC_LOG(LS_INFO) << "  { pixelformat = " << GetFourccName(fmt.pixelformat)
                       << ", description = '" << fmt.description << "' }";
      // Match the preferred order.
      for (int i = 0; i < nFormats; i++) {
        if (fmt.pixelformat == fmts[i] && i < fmtsIdx)
          fmtsIdx = i;
      }
      // Keep enumerating.
      fmt.index++;
    }

    if (fmtsIdx == nFormats) {
      RTC_LOG(LS_INFO) << "no supporting video formats found";
      return -1;
    } else {
      RTC_LOG(LS_INFO) << "We prefer format " << GetFourccName(fmts[fmtsIdx]);
    }

    struct v4l2_format video_fmt;
    memset(&video_fmt, 0, sizeof(struct v4l2_format));
    video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    video_fmt.fmt.pix.sizeimage = 0;
    video_fmt.fmt.pix.width = capability.width;
    video_fmt.fmt.pix.height = capability.height;
    video_fmt.fmt.pix.pixelformat = fmts[fmtsIdx];

    if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
      configured_capability_.videoType = VideoType::kYUY2;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
      configured_capability_.videoType = VideoType::kI420;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420)
      configured_capability_.videoType = VideoType::kYV12;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
      configured_capability_.videoType = VideoType::kUYVY;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
      configured_capability_.videoType = VideoType::kNV12;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
      configured_capability_.videoType = VideoType::kRGB24;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
      configured_capability_.videoType = VideoType::kBGR24;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
      configured_capability_.videoType = VideoType::kRGB565;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ABGR32 ||
             video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
      configured_capability_.videoType = VideoType::kARGB;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ARGB32 ||
             video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
      configured_capability_.videoType = VideoType::kBGRA;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGBA32)
      configured_capability_.videoType = VideoType::kABGR;
    else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG ||
             video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
      configured_capability_.videoType = VideoType::kMJPEG;
    else
      RTC_DCHECK_NOTREACHED();

    // set format and frame size now
    if (ioctl(_deviceFd, VIDIOC_S_FMT, &video_fmt) < 0) {
      RTC_LOG(LS_INFO) << "error in VIDIOC_S_FMT, errno = " << errno;
      return -1;
    }

    // initialize current width and height
    configured_capability_.width = video_fmt.fmt.pix.width;
    configured_capability_.height = video_fmt.fmt.pix.height;

    // Trying to set frame rate, before check driver capability.
    bool driver_framerate_support = true;
    struct v4l2_streamparm streamparms;
    memset(&streamparms, 0, sizeof(streamparms));
    streamparms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (ioctl(_deviceFd, VIDIOC_G_PARM, &streamparms) < 0) {
      RTC_LOG(LS_INFO) << "error in VIDIOC_G_PARM errno = " << errno;
      driver_framerate_support = false;
      // continue
    } else {
      // check the capability flag is set to V4L2_CAP_TIMEPERFRAME.
      if (streamparms.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
        // driver supports the feature. Set required framerate.
        memset(&streamparms, 0, sizeof(streamparms));
        streamparms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        streamparms.parm.capture.timeperframe.numerator = 1;
        streamparms.parm.capture.timeperframe.denominator = capability.maxFPS;
        if (ioctl(_deviceFd, VIDIOC_S_PARM, &streamparms) < 0) {
          RTC_LOG(LS_INFO) << "Failed to set the framerate. errno=" << errno;
          driver_framerate_support = false;
        }
      }
    }
    // If driver doesn't support framerate control, need to hardcode.
    // Hardcoding the value based on the frame size.
    if (!driver_framerate_support) {
      if (configured_capability_.width >= 800 &&
          configured_capability_.videoType != VideoType::kMJPEG) {
        configured_capability_.maxFPS = 15;
      } else {
        configured_capability_.maxFPS = 30;
      }
    }

    if (!AllocateVideoBuffers()) {
      RTC_LOG(LS_INFO) << "failed to allocate video capture buffers";
      return -1;
    }

    // Needed to start UVC camera - from the uvcview application
    enum v4l2_buf_type type;
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (ioctl(_deviceFd, VIDIOC_STREAMON, &type) == -1) {
      RTC_LOG(LS_INFO) << "Failed to turn on stream";
      return -1;
    }

    _requestedCapability = capability;
    _captureStarted = true;
    _streaming = true;
    quit_ = false;
  }
  // Outside of `RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);`

  // start capture thread;
  RTC_DCHECK(_captureThread.empty());
  _captureThread = PlatformThread::SpawnJoinable(
      [this] {
        while (CaptureProcess()) {
        }
      },
      "CaptureThread", ThreadAttributes().SetPriority(ThreadPriority::kHigh));

  return 0;
}

int32_t VideoCaptureModuleV4L2::StopCapture() {
  RTC_DCHECK_RUN_ON(&api_checker_);

  if (!_captureThread.empty()) {
    {
      MutexLock lock(&capture_lock_);
      quit_ = true;
    }
    // Make sure the capture thread stops using the mutex.
    _captureThread.Finalize();
  }

  _captureStarted = false;

  RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
  MutexLock lock(&capture_lock_);
  if (_streaming) {
    _streaming = false;

    DeAllocateVideoBuffers();
    close(_deviceFd);
    _deviceFd = -1;

    _requestedCapability = configured_capability_ = VideoCaptureCapability();
  }

  return 0;
}

// critical section protected by the caller

bool VideoCaptureModuleV4L2::AllocateVideoBuffers() {
  RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
  struct v4l2_requestbuffers rbuffer;
  memset(&rbuffer, 0, sizeof(v4l2_requestbuffers));

  rbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  rbuffer.memory = V4L2_MEMORY_MMAP;
  rbuffer.count = kNoOfV4L2Bufffers;

  if (ioctl(_deviceFd, VIDIOC_REQBUFS, &rbuffer) < 0) {
    RTC_LOG(LS_INFO) << "Could not get buffers from device. errno = " << errno;
    return false;
  }

  if (rbuffer.count > kNoOfV4L2Bufffers)
    rbuffer.count = kNoOfV4L2Bufffers;

  _buffersAllocatedByDevice = rbuffer.count;

  // Map the buffers
  _pool = new Buffer[rbuffer.count];

  for (unsigned int i = 0; i < rbuffer.count; i++) {
    struct v4l2_buffer buffer;
    memset(&buffer, 0, sizeof(v4l2_buffer));
    buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buffer.memory = V4L2_MEMORY_MMAP;
    buffer.index = i;

    if (ioctl(_deviceFd, VIDIOC_QUERYBUF, &buffer) < 0) {
      return false;
    }

    _pool[i].start = mmap(nullptr, buffer.length, PROT_READ | PROT_WRITE,
                          MAP_SHARED, _deviceFd, buffer.m.offset);

    if (MAP_FAILED == _pool[i].start) {
      for (unsigned int j = 0; j < i; j++)
        munmap(_pool[j].start, _pool[j].length);
      return false;
    }

    _pool[i].length = buffer.length;

    if (ioctl(_deviceFd, VIDIOC_QBUF, &buffer) < 0) {
      return false;
    }
  }
  return true;
}

bool VideoCaptureModuleV4L2::DeAllocateVideoBuffers() {
  RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
  // unmap buffers
  for (int i = 0; i < _buffersAllocatedByDevice; i++)
    munmap(_pool[i].start, _pool[i].length);

  delete[] _pool;

  // turn off stream
  enum v4l2_buf_type type;
  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  if (ioctl(_deviceFd, VIDIOC_STREAMOFF, &type) < 0) {
    RTC_LOG(LS_INFO) << "VIDIOC_STREAMOFF error. errno: " << errno;
  }

  return true;
}

bool VideoCaptureModuleV4L2::CaptureStarted() {
  RTC_DCHECK_RUN_ON(&api_checker_);
  return _captureStarted;
}

bool VideoCaptureModuleV4L2::CaptureProcess() {
  RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);

  int retVal = 0;
  fd_set rSet;
  struct timeval timeout;

  FD_ZERO(&rSet);
  FD_SET(_deviceFd, &rSet);
  timeout.tv_sec = 1;
  timeout.tv_usec = 0;

  // _deviceFd written only in StartCapture, when this thread isn't running.
  retVal = select(_deviceFd + 1, &rSet, nullptr, nullptr, &timeout);

  {
    MutexLock lock(&capture_lock_);

    if (quit_) {
      return false;
    }

    if (retVal < 0 && errno != EINTR) {  // continue if interrupted
      // select failed
      return false;
    } else if (retVal == 0) {
      // select timed out
      return true;
    } else if (!FD_ISSET(_deviceFd, &rSet)) {
      // not event on camera handle
      return true;
    }

    if (_streaming) {
      struct v4l2_buffer buf;
      memset(&buf, 0, sizeof(struct v4l2_buffer));
      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.memory = V4L2_MEMORY_MMAP;
      // dequeue a buffer - repeat until dequeued properly!
      while (ioctl(_deviceFd, VIDIOC_DQBUF, &buf) < 0) {
        if (errno != EINTR) {
          RTC_LOG(LS_INFO) << "could not sync on a buffer on device "
                           << strerror(errno);
          return true;
        }
      }

      // convert to to I420 if needed
      IncomingFrame(reinterpret_cast<uint8_t*>(_pool[buf.index].start),
                    buf.bytesused, configured_capability_);
      // enqueue the buffer again
      if (ioctl(_deviceFd, VIDIOC_QBUF, &buf) == -1) {
        RTC_LOG(LS_INFO) << "Failed to enqueue capture buffer";
      }
    }
  }
  usleep(0);
  return true;
}

int32_t VideoCaptureModuleV4L2::CaptureSettings(
    VideoCaptureCapability& settings) {
  RTC_DCHECK_RUN_ON(&api_checker_);
  settings = _requestedCapability;

  return 0;
}
}  // namespace videocapturemodule
}  // namespace webrtc

#ifdef ABGR32_OVERRIDE
#undef ABGR32_OVERRIDE
#undef V4L2_PIX_FMT_ABGR32
#endif

#ifdef ARGB32_OVERRIDE
#undef ARGB32_OVERRIDE
#undef V4L2_PIX_FMT_ARGB32
#endif

#ifdef RGBA32_OVERRIDE
#undef RGBA32_OVERRIDE
#undef V4L2_PIX_FMT_RGBA32
#endif
