2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * \brief source file for libv4l2
20 * \author Jinsung Yang (jsgood.yang@samsung.com)
21 * \author Sangwoo Park (sw5771.park@samsung.com)
24 * <b>Revision History: </b>
25 * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
39 #include "exynos_v4l2.h"
41 //#define LOG_NDEBUG 0
42 #define LOG_TAG "libexynosv4l2"
43 #include <utils/Log.h>
44 #include "Exynos_log.h"
46 #define VIDEODEV_MINOR_MAX 63
48 //#define EXYNOS_V4L2_TRACE 0
49 #ifdef EXYNOS_V4L2_TRACE
50 #define Exynos_v4l2_In() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__)
51 #define Exynos_v4l2_Out() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__)
53 #define Exynos_v4l2_In() ((void *)0)
54 #define Exynos_v4l2_Out() ((void *)0)
57 static bool __v4l2_check_buf_type(enum v4l2_buf_type type
)
62 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
63 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
:
64 case V4L2_BUF_TYPE_VIDEO_OUTPUT
:
65 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
66 case V4L2_BUF_TYPE_VIDEO_OVERLAY
:
71 supported
= (type
>= V4L2_BUF_TYPE_PRIVATE
) ? true : false;
78 static int __v4l2_open(const char *filename
, int oflag
, va_list ap
)
84 mode
= va_arg(ap
, int);
86 fd
= open(filename
, oflag
, mode
);
91 int exynos_v4l2_open(const char *filename
, int oflag
, ...)
99 fd
= __v4l2_open(filename
, oflag
, ap
);
107 int exynos_v4l2_open_devname(const char *devname
, int oflag
, ...)
114 char filename
[64], name
[64];
115 int minor
, size
, i
= 0;
120 if (i
> VIDEODEV_MINOR_MAX
)
123 /* video device node */
124 sprintf(filename
, "/dev/video%d", i
++);
126 /* if the node is video device */
127 if ((lstat(filename
, &s
) == 0) && S_ISCHR(s
.st_mode
) &&
128 ((int)((unsigned short)(s
.st_rdev
) >> 8) == 81)) {
129 minor
= (int)((unsigned short)(s
.st_rdev
& 0x3f));
130 ALOGD("try node: %s, minor: %d", filename
, minor
);
131 /* open sysfs entry */
132 sprintf(filename
, "/sys/class/video4linux/video%d/name", minor
);
133 stream_fd
= fopen(filename
, "r");
134 if (stream_fd
== NULL
) {
135 ALOGE("failed to open sysfs entry for videodev");
136 continue; /* try next */
139 /* read sysfs entry for device name */
140 size
= (int)fgets(name
, sizeof(name
), stream_fd
);
143 /* check read size */
145 ALOGE("failed to read sysfs entry for videodev");
148 if (strncmp(name
, devname
, strlen(devname
)) == 0) {
149 ALOGI("node found for device %s: /dev/video%d", devname
, minor
);
154 } while (found
== false);
157 sprintf(filename
, "/dev/video%d", minor
);
159 fd
= __v4l2_open(filename
, oflag
, ap
);
163 ALOGI("open video device %s", filename
);
165 ALOGE("failed to open video device %s", filename
);
167 ALOGE("no video device found");
175 int exynos_v4l2_close(int fd
)
182 ALOGE("%s: invalid fd: %d", __func__
, fd
);
191 bool exynos_v4l2_enuminput(int fd
, int index
, char *input_name_buf
)
194 struct v4l2_input input
;
199 ALOGE("%s: invalid fd: %d", __func__
, fd
);
204 ret
= ioctl(fd
, VIDIOC_ENUMINPUT
, &input
);
206 ALOGE("%s: no matching index founds", __func__
);
210 ALOGI("Name of input channel[%d] is %s", input
.index
, input
.name
);
212 strcpy(input_name_buf
, (const char *)input
.name
);
219 int exynos_v4l2_s_input(int fd
, int index
)
222 struct v4l2_input input
;
227 ALOGE("%s: invalid fd: %d", __func__
, fd
);
233 ret
= ioctl(fd
, VIDIOC_S_INPUT
, &input
);
235 ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d)", ret
);
244 bool exynos_v4l2_querycap(int fd
, unsigned int need_caps
)
246 struct v4l2_capability cap
;
252 ALOGE("%s: invalid fd: %d", __func__
, fd
);
256 if (!(need_caps
& V4L2_CAP_VIDEO_CAPTURE
) &&
257 !(need_caps
& V4L2_CAP_VIDEO_CAPTURE_MPLANE
) &&
258 !(need_caps
& V4L2_CAP_VIDEO_OUTPUT
) &&
259 !(need_caps
& V4L2_CAP_VIDEO_OUTPUT_MPLANE
) &&
260 !(need_caps
& V4L2_CAP_VIDEO_OVERLAY
)) {
261 ALOGE("%s: unsupported capabilities", __func__
);
265 memset(&cap
, 0, sizeof(cap
));
267 ret
= ioctl(fd
, VIDIOC_QUERYCAP
, &cap
);
269 ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d)", ret
);
273 if ((need_caps
& cap
.capabilities
) != need_caps
) {
274 ALOGE("%s: unsupported capabilities", __func__
);
283 bool exynos_v4l2_enum_fmt(int fd
, enum v4l2_buf_type type
, unsigned int fmt
)
285 struct v4l2_fmtdesc fmtdesc
;
293 while (ioctl(fd
, VIDIOC_ENUM_FMT
, &fmtdesc
) == 0) {
294 if (fmtdesc
.pixelformat
== fmt
) {
295 ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt
, fmtdesc
.index
, fmtdesc
.description
);
304 ALOGE("%s: unsupported pixel format", __func__
);
313 int exynos_v4l2_g_fmt(int fd
, struct v4l2_format
*fmt
)
320 ALOGE("%s: invalid fd: %d", __func__
, fd
);
325 ALOGE("%s: fmt is NULL", __func__
);
329 if (__v4l2_check_buf_type(fmt
->type
) == false) {
330 ALOGE("%s: unsupported buffer type", __func__
);
334 ret
= ioctl(fd
, VIDIOC_G_FMT
, fmt
);
336 ALOGE("failed to ioctl: VIDIOC_G_FMT");
345 static int __v4l2_s_fmt(int fd
, unsigned int request
, struct v4l2_format
*fmt
)
352 ALOGE("%s: invalid fd: %d", __func__
, fd
);
357 ALOGE("%s: fmt is NULL", __func__
);
361 if (__v4l2_check_buf_type(fmt
->type
) == false) {
362 ALOGE("%s: unsupported buffer type", __func__
);
365 ret
= ioctl(fd
, request
, fmt
);
367 if (request
== VIDIOC_TRY_FMT
)
368 ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d)", ret
);
370 ALOGE("failed to ioctl: VIDIOC_S_FMT (%d)", ret
);
381 int exynos_v4l2_try_fmt(int fd
, struct v4l2_format
*fmt
)
383 return __v4l2_s_fmt(fd
, VIDIOC_TRY_FMT
, fmt
);
386 int exynos_v4l2_s_fmt(int fd
, struct v4l2_format
*fmt
)
388 return __v4l2_s_fmt(fd
, VIDIOC_S_FMT
, fmt
);
391 int exynos_v4l2_reqbufs(int fd
, struct v4l2_requestbuffers
*req
)
399 ALOGE("%s: invalid fd: %d", __func__
, fd
);
404 ALOGE("%s: req is NULL", __func__
);
408 if ((req
->memory
!= V4L2_MEMORY_MMAP
) && (req
->memory
!= V4L2_MEMORY_USERPTR
)) {
409 ALOGE("%s: unsupported memory type", __func__
);
413 if (__v4l2_check_buf_type(req
->type
) == false) {
414 ALOGE("%s: unsupported buffer type", __func__
);
420 ret
= ioctl(fd
, VIDIOC_REQBUFS
, req
);
422 ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d)", ret
);
426 if (count
!= req
->count
) {
427 ALOGW("number of buffers had been changed: %d => %d", count
, req
->count
);
435 int exynos_v4l2_querybuf(int fd
, struct v4l2_buffer
*buf
)
442 ALOGE("%s: invalid fd: %d", __func__
, fd
);
447 ALOGE("%s: buf is NULL", __func__
);
451 if (buf
->memory
!= V4L2_MEMORY_MMAP
) {
452 ALOGE("%s: unsupported memory type", __func__
);
456 if (__v4l2_check_buf_type(buf
->type
) == false) {
457 ALOGE("%s: unsupported buffer type", __func__
);
461 ret
= ioctl(fd
, VIDIOC_QUERYBUF
, buf
);
463 ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d)", ret
);
472 int exynos_v4l2_qbuf(int fd
, struct v4l2_buffer
*buf
)
479 ALOGE("%s: invalid fd: %d", __func__
, fd
);
484 ALOGE("%s: buf is NULL", __func__
);
488 if ((buf
->memory
!= V4L2_MEMORY_MMAP
) && (buf
->memory
!= V4L2_MEMORY_USERPTR
)) {
489 ALOGE("%s: unsupported memory type", __func__
);
493 if (__v4l2_check_buf_type(buf
->type
) == false) {
494 ALOGE("%s: unsupported buffer type", __func__
);
498 ret
= ioctl(fd
, VIDIOC_QBUF
, buf
);
500 ALOGE("failed to ioctl: VIDIOC_QBUF (%d)", ret
);
509 int exynos_v4l2_dqbuf(int fd
, struct v4l2_buffer
*buf
)
516 ALOGE("%s: invalid fd: %d", __func__
, fd
);
521 ALOGE("%s: buf is NULL", __func__
);
525 if ((buf
->memory
!= V4L2_MEMORY_MMAP
) && (buf
->memory
!= V4L2_MEMORY_USERPTR
)) {
526 ALOGE("%s: unsupported memory type", __func__
);
530 if (__v4l2_check_buf_type(buf
->type
) == false) {
531 ALOGE("%s: unsupported buffer type", __func__
);
535 ret
= ioctl(fd
, VIDIOC_DQBUF
, buf
);
537 ALOGE("failed to ioctl: VIDIOC_DQBUF (%d)", ret
);
546 int exynos_v4l2_streamon(int fd
, enum v4l2_buf_type type
)
553 ALOGE("%s: invalid fd: %d", __func__
, fd
);
557 if (__v4l2_check_buf_type(type
) == false) {
558 ALOGE("%s: unsupported buffer type", __func__
);
562 ret
= ioctl(fd
, VIDIOC_STREAMON
, &type
);
564 ALOGE("failed to ioctl: VIDIOC_STREAMON (%d)", ret
);
573 int exynos_v4l2_streamoff(int fd
, enum v4l2_buf_type type
)
580 ALOGE("%s: invalid fd: %d", __func__
, fd
);
584 if (__v4l2_check_buf_type(type
) == false) {
585 ALOGE("%s: unsupported buffer type", __func__
);
589 ret
= ioctl(fd
, VIDIOC_STREAMOFF
, &type
);
591 ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d)", ret
);
600 int exynos_v4l2_cropcap(int fd
, struct v4l2_cropcap
*crop
)
607 ALOGE("%s: invalid fd: %d", __func__
, fd
);
612 ALOGE("%s: crop is NULL", __func__
);
616 if (__v4l2_check_buf_type(crop
->type
) == false) {
617 ALOGE("%s: unsupported buffer type", __func__
);
621 ret
= ioctl(fd
, VIDIOC_CROPCAP
, crop
);
623 ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d)", ret
);
632 int exynos_v4l2_g_crop(int fd
, struct v4l2_crop
*crop
)
639 ALOGE("%s: invalid fd: %d", __func__
, fd
);
644 ALOGE("%s: crop is NULL", __func__
);
648 if (__v4l2_check_buf_type(crop
->type
) == false) {
649 ALOGE("%s: unsupported buffer type", __func__
);
653 ret
= ioctl(fd
, VIDIOC_G_CROP
, crop
);
655 ALOGE("failed to ioctl: VIDIOC_G_CROP (%d)", ret
);
664 int exynos_v4l2_s_crop(int fd
, struct v4l2_crop
*crop
)
671 ALOGE("%s: invalid fd: %d", __func__
, fd
);
676 ALOGE("%s: crop is NULL", __func__
);
680 if (__v4l2_check_buf_type(crop
->type
) == false) {
681 ALOGE("%s: unsupported buffer type", __func__
);
685 ret
= ioctl(fd
, VIDIOC_S_CROP
, crop
);
687 ALOGE("failed to ioctl: VIDIOC_S_CROP (%d)", ret
);
696 int exynos_v4l2_g_ctrl(int fd
, unsigned int id
, int *value
)
699 struct v4l2_control ctrl
;
706 ALOGE("%s: invalid fd: %d", __func__
, fd
);
710 ret
= ioctl(fd
, VIDIOC_G_CTRL
, &ctrl
);
712 ALOGE("failed to ioctl: VIDIOC_G_CTRL (%d)", ret
);
723 int exynos_v4l2_s_ctrl(int fd
, unsigned int id
, int value
)
726 struct v4l2_control ctrl
;
734 ALOGE("%s: invalid fd: %d", __func__
, fd
);
738 ret
= ioctl(fd
, VIDIOC_S_CTRL
, &ctrl
);
740 ALOGE("failed to ioctl: VIDIOC_S_CTRL (%d)", ret
);
749 int exynos_v4l2_g_parm(int fd
, struct v4l2_streamparm
*streamparm
)
756 ALOGE("%s: invalid fd: %d", __func__
, fd
);
760 if (__v4l2_check_buf_type(streamparm
->type
) == false) {
761 ALOGE("%s: unsupported buffer type", __func__
);
765 ret
= ioctl(fd
, VIDIOC_G_PARM
, streamparm
);
767 ALOGE("failed to ioctl: VIDIOC_G_PARM (%d)", ret
);
776 int exynos_v4l2_s_parm(int fd
, struct v4l2_streamparm
*streamparm
)
783 ALOGE("%s: invalid fd: %d", __func__
, fd
);
787 if (__v4l2_check_buf_type(streamparm
->type
) == false) {
788 ALOGE("%s: unsupported buffer type", __func__
);
792 ret
= ioctl(fd
, VIDIOC_S_PARM
, streamparm
);
794 ALOGE("failed to ioctl: VIDIOC_S_PARM (%d)", ret
);
803 int exynos_v4l2_g_ext_ctrl(int fd
, struct v4l2_ext_controls
*ctrl
)
810 ALOGE("%s: invalid fd: %d", __func__
, fd
);
815 ALOGE("%s: ctrl is NULL", __func__
);
819 ret
= ioctl(fd
, VIDIOC_G_EXT_CTRLS
, ctrl
);
821 ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d)", ret
);
828 int exynos_v4l2_s_ext_ctrl(int fd
, struct v4l2_ext_controls
*ctrl
)
835 ALOGE("%s: invalid fd: %d", __func__
, fd
);
840 ALOGE("%s: ctrl is NULL", __func__
);
844 ret
= ioctl(fd
, VIDIOC_S_EXT_CTRLS
, ctrl
);
846 ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d)", ret
);