/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*!
 * \file      exynos_v4l2.c
 * \brief     source file for libv4l2
 * \author    Jinsung Yang (jsgood.yang@samsung.com)
 * \author    Sangwoo Park (sw5771.park@samsung.com)
 * \date      2012/01/17
 *
 * <b>Revision History: </b>
 * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n
 *   Initial version
 *
 */

#include <stdio.h>
#include <errno.h>
#include <stdarg.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>

#include "exynos_v4l2.h"

//#define LOG_NDEBUG 0
#define LOG_TAG "libexynosv4l2"
#include <utils/Log.h>
#include "Exynos_log.h"

#define VIDEODEV_MINOR_MAX 63

//#define EXYNOS_V4L2_TRACE 0
#ifdef EXYNOS_V4L2_TRACE
#define Exynos_v4l2_In() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__)
#define Exynos_v4l2_Out() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__)
#else
#define Exynos_v4l2_In() ((void *)0)
#define Exynos_v4l2_Out() ((void *)0)
#endif

static bool __v4l2_check_buf_type(enum v4l2_buf_type type)
{
    bool supported;

    switch (type) {
    case V4L2_BUF_TYPE_VIDEO_CAPTURE:
    case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
    case V4L2_BUF_TYPE_VIDEO_OUTPUT:
    case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
    case V4L2_BUF_TYPE_VIDEO_OVERLAY:
        supported = true;
        break;

    default:
        supported = (type >= V4L2_BUF_TYPE_PRIVATE) ? true : false;
        break;
    }

    return supported;
}

static int __v4l2_open(const char *filename, int oflag, va_list ap)
{
    mode_t mode = 0;
    int fd;

    if (oflag & O_CREAT)
        mode = va_arg(ap, int);

    fd = open(filename, oflag, mode);

    return fd;
}

int exynos_v4l2_open(const char *filename, int oflag, ...)
{
    va_list ap;
    int fd;

    Exynos_v4l2_In();

    va_start(ap, oflag);
    fd = __v4l2_open(filename, oflag, ap);
    va_end(ap);

    Exynos_v4l2_Out();

    return fd;
}

int exynos_v4l2_open_devname(const char *devname, int oflag, ...)
{
    bool found = false;
    int fd = -1;
    struct stat s;
    va_list ap;
    FILE *stream_fd;
    char filename[64], name[64];
    int minor, size, i = 0;

    Exynos_v4l2_In();

    do {
        if (i > VIDEODEV_MINOR_MAX)
            break;

        /* video device node */
        sprintf(filename, "/dev/video%d", i++);

        /* if the node is video device */
        if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) &&
                ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) {
            minor = (int)((unsigned short)(s.st_rdev & 0x3f));
            ALOGD("try node: %s, minor: %d", filename, minor);
            /* open sysfs entry */
            sprintf(filename, "/sys/class/video4linux/video%d/name", minor);
            stream_fd = fopen(filename, "r");
            if (stream_fd == NULL) {
                ALOGE("failed to open sysfs entry for videodev");
                continue;   /* try next */
            }

            /* read sysfs entry for device name */
            size = (int)fgets(name, sizeof(name), stream_fd);
            fclose(stream_fd);

            /* check read size */
            if (size == 0) {
                ALOGE("failed to read sysfs entry for videodev");
            } else {
                /* matched */
                if (strncmp(name, devname, strlen(devname)) == 0) {
                    ALOGI("node found for device %s: /dev/video%d", devname, minor);
                    found = true;
                }
            }
        }
    } while (found == false);

    if (found) {
        sprintf(filename, "/dev/video%d", minor);
        va_start(ap, oflag);
        fd = __v4l2_open(filename, oflag, ap);
        va_end(ap);

        if (fd > 0)
            ALOGI("open video device %s", filename);
        else
            ALOGE("failed to open video device %s", filename);
    } else {
        ALOGE("no video device found");
    }

    Exynos_v4l2_Out();

    return fd;
}

int exynos_v4l2_close(int fd)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0)
        ALOGE("%s: invalid fd: %d", __func__, fd);
    else
        ret = close(fd);

    Exynos_v4l2_Out();

    return ret;
}

bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf)
{
    int ret = -1;
    struct v4l2_input input;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return NULL;
    }

    input.index = index;
    ret = ioctl(fd, VIDIOC_ENUMINPUT, &input);
    if (ret) {
        ALOGE("%s: no matching index founds", __func__);
        return false;
    }

    ALOGI("Name of input channel[%d] is %s", input.index, input.name);

    strcpy(input_name_buf, (const char *)input.name);

    Exynos_v4l2_Out();

    return true;
}

int exynos_v4l2_s_input(int fd, int index)
{
    int ret = -1;
    struct v4l2_input input;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    input.index = index;

    ret = ioctl(fd, VIDIOC_S_INPUT, &input);
    if (ret){
        ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

bool exynos_v4l2_querycap(int fd, unsigned int need_caps)
{
    struct v4l2_capability cap;
    int ret;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return false;
    }

    if (!(need_caps & V4L2_CAP_VIDEO_CAPTURE) &&
            !(need_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) &&
            !(need_caps & V4L2_CAP_VIDEO_OUTPUT) &&
            !(need_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) &&
            !(need_caps & V4L2_CAP_VIDEO_OVERLAY)) {
        ALOGE("%s: unsupported capabilities", __func__);
        return false;
    }

    memset(&cap, 0, sizeof(cap));

    ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d - %s)", errno, strerror(errno));
        return false;
    }

    if ((need_caps & cap.capabilities) != need_caps) {
        ALOGE("%s: unsupported capabilities", __func__);
        return false;
    }

    Exynos_v4l2_Out();

    return true;
}

bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt)
{
    struct v4l2_fmtdesc fmtdesc;
    int found = 0;

    Exynos_v4l2_In();

    fmtdesc.type = type;
    fmtdesc.index = 0;

    while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
        if (fmtdesc.pixelformat == fmt) {
            ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description);
            found = 1;
            break;
        }

        fmtdesc.index++;
    }

    if (!found) {
        ALOGE("%s: unsupported pixel format", __func__);
        return false;
    }

    Exynos_v4l2_Out();

    return true;
}

int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!fmt) {
        ALOGE("%s: fmt is NULL", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(fmt->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_G_FMT, fmt);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_G_FMT (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

static int __v4l2_s_fmt(int fd, unsigned int request, struct v4l2_format *fmt)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!fmt) {
        ALOGE("%s: fmt is NULL", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(fmt->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    } else {
        ret = ioctl(fd, request, fmt);
        if (ret) {
            if (request == VIDIOC_TRY_FMT)
                ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d - %s)", errno, strerror(errno));
            else
                ALOGE("failed to ioctl: VIDIOC_S_FMT (%d - %s)", errno, strerror(errno));

            return ret;
        }
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt)
{
    return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt);
}

int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt)
{
    return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt);
}

int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req)
{
    int ret = -1;
    unsigned int count;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!req) {
        ALOGE("%s: req is NULL", __func__);
        return ret;
    }

    if ((req->memory != V4L2_MEMORY_MMAP) &&
	(req->memory != V4L2_MEMORY_USERPTR) &&
	(req->memory != V4L2_MEMORY_DMABUF)) {
        ALOGE("%s: unsupported memory type", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(req->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    count = req->count;

    ret = ioctl(fd, VIDIOC_REQBUFS, req);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d - %s)", ret, strerror(errno));
        return ret;
    }

    if (count != req->count) {
        ALOGW("number of buffers had been changed: %d => %d", count, req->count);
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!buf) {
        ALOGE("%s: buf is NULL", __func__);
        return ret;
    }

    if ((buf->memory != V4L2_MEMORY_MMAP) &&
	(buf->memory != V4L2_MEMORY_DMABUF)) {
        ALOGE("%s: unsupported memory type", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(buf->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_QUERYBUF, buf);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!buf) {
        ALOGE("%s: buf is NULL", __func__);
        return ret;
    }

    if ((buf->memory != V4L2_MEMORY_MMAP) &&
	(buf->memory != V4L2_MEMORY_USERPTR) &&
	(buf->memory != V4L2_MEMORY_DMABUF)) {
        ALOGE("%s: unsupported memory type", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(buf->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_QBUF, buf);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_QBUF (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!buf) {
        ALOGE("%s: buf is NULL", __func__);
        return ret;
    }

    if ((buf->memory != V4L2_MEMORY_MMAP) &&
	(buf->memory != V4L2_MEMORY_USERPTR) &&
	(buf->memory != V4L2_MEMORY_DMABUF)) {
        ALOGE("%s: unsupported memory type", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(buf->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_DQBUF, buf);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_DQBUF (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (__v4l2_check_buf_type(type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_STREAMON, &type);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_STREAMON (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (__v4l2_check_buf_type(type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!crop) {
        ALOGE("%s: crop is NULL", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(crop->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_CROPCAP, crop);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!crop) {
        ALOGE("%s: crop is NULL", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(crop->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_G_CROP, crop);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_G_CROP (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (!crop) {
        ALOGE("%s: crop is NULL", __func__);
        return ret;
    }

    if (__v4l2_check_buf_type(crop->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_S_CROP, crop);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_S_CROP (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value)
{
    int ret = -1;
    struct v4l2_control ctrl;

    Exynos_v4l2_In();

    ctrl.id = id;

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_G_CTRL (%d - %s)", errno, strerror(errno));
        return ret;
    }

    *value = ctrl.value;

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value)
{
    int ret = -1;
    struct v4l2_control ctrl;

    Exynos_v4l2_In();

    ctrl.id = id;
    ctrl.value = value;

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_S_CTRL (%d)", errno);
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (__v4l2_check_buf_type(streamparm->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_G_PARM, streamparm);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_G_PARM (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (__v4l2_check_buf_type(streamparm->type) == false) {
        ALOGE("%s: unsupported buffer type", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_S_PARM, streamparm);
    if (ret) {
        ALOGE("failed to ioctl: VIDIOC_S_PARM (%d - %s)", errno, strerror(errno));
        return ret;
    }

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (ctrl == NULL) {
        ALOGE("%s: ctrl is NULL", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, ctrl);
    if (ret)
        ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d - %s)", errno, strerror(errno));

    Exynos_v4l2_Out();

    return ret;
}

int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
{
    int ret = -1;

    Exynos_v4l2_In();

    if (fd < 0) {
        ALOGE("%s: invalid fd: %d", __func__, fd);
        return ret;
    }

    if (ctrl == NULL) {
        ALOGE("%s: ctrl is NULL", __func__);
        return ret;
    }

    ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, ctrl);
    if (ret)
        ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d - %s)", errno, strerror(errno));

    Exynos_v4l2_Out();

    return ret;
}
