2 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
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
36 #include <sys/types.h>
37 #include <sys/ioctl.h>
40 #include "exynos_v4l2.h"
42 //#define LOG_NDEBUG 0
43 #define LOG_TAG "libexynosv4l2"
44 #ifndef TIZEN_FEATURE_E3250 /* build env */
45 #include <utils/Log.h>
47 #include "Exynos_OSAL_Log.h"
50 #define VIDEODEV_MAX 255
52 static bool __v4l2_check_buf_type(enum v4l2_buf_type type)
57 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
58 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
59 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
60 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
61 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
66 supported = (type >= V4L2_BUF_TYPE_PRIVATE) ? true : false;
73 static int __v4l2_open(const char *filename, int oflag, va_list ap)
79 mode = va_arg(ap, int);
81 fd = open(filename, oflag, mode);
86 int exynos_v4l2_open(const char *filename, int oflag, ...)
92 fd = __v4l2_open(filename, oflag, ap);
98 int exynos_v4l2_open_devname(const char *devname, int oflag, ...)
105 char filename[64], name[64];
109 if (i > VIDEODEV_MAX)
112 /* video device node */
113 snprintf(filename, sizeof(filename), "/dev/video%d", i);
115 /* if the node is video device */
116 if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) &&
117 ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) {
118 ALOGD("try node: %s", filename);
119 /* open sysfs entry */
120 snprintf(filename, sizeof(filename), "/sys/class/video4linux/video%d/name", i);
121 if (S_ISLNK(s.st_mode)) {
122 ALOGE("symbolic link detected");
125 stream_fd = fopen(filename, "r");
126 if (stream_fd == NULL) {
127 ALOGE("failed to open sysfs entry for videodev");
129 continue; /* try next */
132 /* read sysfs entry for device name */
133 size = (int)fgets(name, sizeof(name), stream_fd);
136 /* check read size */
138 ALOGE("failed to read sysfs entry for videodev");
141 if (strncmp(name, devname, strlen(devname)) == 0) {
142 ALOGI("node found for device %s: /dev/video%d", devname, i);
149 } while (found == false);
152 snprintf(filename, sizeof(filename), "/dev/video%d", i);
154 fd = __v4l2_open(filename, oflag, ap);
158 ALOGI("open video device %s", filename);
160 ALOGE("failed to open video device %s", filename);
162 ALOGE("no video device found");
168 int exynos_v4l2_close(int fd)
173 ALOGE("%s: invalid fd: %d", __func__, fd);
180 bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf)
183 struct v4l2_input input;
186 ALOGE("%s: invalid fd: %d", __func__, fd);
191 ret = ioctl(fd, VIDIOC_ENUMINPUT, &input, 32);
193 ALOGE("%s: no matching index founds", __func__);
197 ALOGI("Name of input channel[%d] is %s", input.index, input.name);
199 strncpy(input_name_buf, (const char *)input.name, 32);
204 int exynos_v4l2_s_input(int fd, int index)
207 struct v4l2_input input;
210 ALOGE("%s: invalid fd: %d", __func__, fd);
216 ret = ioctl(fd, VIDIOC_S_INPUT, &input);
218 ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d - %s)", errno, strerror(errno));
225 bool exynos_v4l2_querycap(int fd, unsigned int need_caps)
227 struct v4l2_capability cap;
231 ALOGE("%s: invalid fd: %d", __func__, fd);
235 if (!(need_caps & V4L2_CAP_VIDEO_CAPTURE) &&
236 !(need_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) &&
237 !(need_caps & V4L2_CAP_VIDEO_OUTPUT) &&
238 !(need_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) &&
239 !(need_caps & V4L2_CAP_VIDEO_OVERLAY)) {
240 ALOGE("%s: unsupported capabilities", __func__);
244 memset(&cap, 0, sizeof(cap));
246 ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
248 ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d - %s)", errno, strerror(errno));
252 if ((need_caps & cap.capabilities) != need_caps) {
253 ALOGE("%s: unsupported capabilities", __func__);
260 bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt)
262 struct v4l2_fmtdesc fmtdesc;
268 while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
269 if (fmtdesc.pixelformat == fmt) {
270 ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description);
279 ALOGE("%s: unsupported pixel format", __func__);
286 int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt)
291 ALOGE("%s: invalid fd: %d", __func__, fd);
296 ALOGE("%s: fmt is NULL", __func__);
300 if (__v4l2_check_buf_type(fmt->type) == false) {
301 ALOGE("%s: unsupported buffer type", __func__);
305 ret = ioctl(fd, VIDIOC_G_FMT, fmt);
307 ALOGE("failed to ioctl: VIDIOC_G_FMT (%d - %s)", errno, strerror(errno));
314 static int __v4l2_s_fmt(int fd, unsigned int request, struct v4l2_format *fmt)
319 ALOGE("%s: invalid fd: %d", __func__, fd);
324 ALOGE("%s: fmt is NULL", __func__);
328 if (__v4l2_check_buf_type(fmt->type) == false) {
329 ALOGE("%s: unsupported buffer type", __func__);
332 ret = ioctl(fd, request, fmt);
334 if (request == VIDIOC_TRY_FMT)
335 ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d - %s)", errno, strerror(errno));
337 ALOGE("failed to ioctl: VIDIOC_S_FMT (%d - %s)", errno, strerror(errno));
346 int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt)
348 return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt);
351 int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt)
353 return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt);
356 int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req)
362 ALOGE("%s: invalid fd: %d", __func__, fd);
367 ALOGE("%s: req is NULL", __func__);
371 if ((req->memory != V4L2_MEMORY_MMAP) &&
372 (req->memory != V4L2_MEMORY_USERPTR) &&
373 (req->memory != V4L2_MEMORY_DMABUF)) {
374 ALOGE("%s: unsupported memory type", __func__);
378 if (__v4l2_check_buf_type(req->type) == false) {
379 ALOGE("%s: unsupported buffer type", __func__);
385 ret = ioctl(fd, VIDIOC_REQBUFS, req);
387 ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d - %s)", ret, strerror(errno));
391 if (count != req->count) {
392 ALOGW("number of buffers had been changed: %d => %d", count, req->count);
398 int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf)
403 ALOGE("%s: invalid fd: %d", __func__, fd);
408 ALOGE("%s: buf is NULL", __func__);
412 if ((buf->memory != V4L2_MEMORY_MMAP) &&
413 (buf->memory != V4L2_MEMORY_DMABUF)) {
414 ALOGE("%s: unsupported memory type", __func__);
418 if (__v4l2_check_buf_type(buf->type) == false) {
419 ALOGE("%s: unsupported buffer type", __func__);
423 ret = ioctl(fd, VIDIOC_QUERYBUF, buf);
425 ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d - %s)", errno, strerror(errno));
432 #ifdef TIZEN_FEATURE_E3250 /*dmabuf */
434 #ifndef VIDIOC_EXPBUF
435 struct v4l2_exportbuffer {
442 #define VIDIOC_EXPBUF _IOWR('V', 16, struct v4l2_exportbuffer)
445 int exynos_v4l2_expbuf(int fd, int *buf_fd, __u32 mem_offset)
448 struct v4l2_exportbuffer expbuf;
451 ALOGE("%s: invalid fd: %d", __func__, fd);
452 ALOGE("%s: invalid fd: %d", __func__, fd);
456 expbuf.flags = O_CLOEXEC;
457 //expbuf.mem_offset = mem_offset;
458 ALOGE("%s: fd:%d mem_offset:%d", __func__, fd, mem_offset);
460 ret = ioctl(fd, VIDIOC_EXPBUF, &expbuf);
462 ALOGE("failed to ioctl: VIDIOC_EXPBUF (%d - %s)", errno, strerror(errno));
465 ALOGE("%s: got fd: %d", __func__, expbuf.fd);
472 int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf)
477 ALOGE("%s: invalid fd: %d", __func__, fd);
482 ALOGE("%s: buf is NULL", __func__);
486 if ((buf->memory != V4L2_MEMORY_MMAP) &&
487 (buf->memory != V4L2_MEMORY_USERPTR) &&
488 (buf->memory != V4L2_MEMORY_DMABUF)) {
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 - %s)", errno, strerror(errno));
507 int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf)
512 ALOGE("%s: invalid fd: %d", __func__, fd);
517 ALOGE("%s: buf is NULL", __func__);
521 if ((buf->memory != V4L2_MEMORY_MMAP) &&
522 (buf->memory != V4L2_MEMORY_USERPTR) &&
523 (buf->memory != V4L2_MEMORY_DMABUF)) {
524 ALOGE("%s: unsupported memory type", __func__);
528 if (__v4l2_check_buf_type(buf->type) == false) {
529 ALOGE("%s: unsupported buffer type", __func__);
533 ret = ioctl(fd, VIDIOC_DQBUF, buf);
538 int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type)
543 ALOGE("%s: invalid fd: %d", __func__, fd);
547 if (__v4l2_check_buf_type(type) == false) {
548 ALOGE("%s: unsupported buffer type", __func__);
552 ret = ioctl(fd, VIDIOC_STREAMON, &type);
554 ALOGE("failed to ioctl: VIDIOC_STREAMON (%d - %s)", errno, strerror(errno));
561 int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type)
566 ALOGE("%s: invalid fd: %d", __func__, fd);
570 if (__v4l2_check_buf_type(type) == false) {
571 ALOGE("%s: unsupported buffer type", __func__);
575 ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
577 ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d - %s)", errno, strerror(errno));
584 int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop)
589 ALOGE("%s: invalid fd: %d", __func__, fd);
594 ALOGE("%s: crop is NULL", __func__);
598 if (__v4l2_check_buf_type(crop->type) == false) {
599 ALOGE("%s: unsupported buffer type", __func__);
603 ret = ioctl(fd, VIDIOC_CROPCAP, crop);
605 ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d - %s)", errno, strerror(errno));
612 int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop)
617 ALOGE("%s: invalid fd: %d", __func__, fd);
622 ALOGE("%s: crop is NULL", __func__);
626 if (__v4l2_check_buf_type(crop->type) == false) {
627 ALOGE("%s: unsupported buffer type", __func__);
631 ret = ioctl(fd, VIDIOC_G_CROP, crop);
633 ALOGE("failed to ioctl: VIDIOC_G_CROP (%d - %s)", errno, strerror(errno));
640 int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop)
645 ALOGE("%s: invalid fd: %d", __func__, fd);
650 ALOGE("%s: crop is NULL", __func__);
654 if (__v4l2_check_buf_type(crop->type) == false) {
655 ALOGE("%s: unsupported buffer type", __func__);
659 ret = ioctl(fd, VIDIOC_S_CROP, crop);
661 ALOGE("failed to ioctl: VIDIOC_S_CROP (%d - %s)", errno, strerror(errno));
668 int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value)
671 struct v4l2_control ctrl;
676 ALOGE("%s: invalid fd: %d", __func__, fd);
680 ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl);
682 ALOGE("failed to ioctl: VIDIOC_G_CTRL id: %x (%d - %s)", id, errno, strerror(errno));
691 int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value)
694 struct v4l2_control ctrl;
700 ALOGE("%s: invalid fd: %d", __func__, fd);
704 ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
706 ALOGE("failed to ioctl: VIDIOC_S_CTRL id: %x (errno: %d)", id, errno);
713 int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm)
718 ALOGE("%s: invalid fd: %d", __func__, fd);
722 if (__v4l2_check_buf_type(streamparm->type) == false) {
723 ALOGE("%s: unsupported buffer type", __func__);
727 ret = ioctl(fd, VIDIOC_G_PARM, streamparm);
729 ALOGE("failed to ioctl: VIDIOC_G_PARM (%d - %s)", errno, strerror(errno));
736 int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm)
741 ALOGE("%s: invalid fd: %d", __func__, fd);
745 if (__v4l2_check_buf_type(streamparm->type) == false) {
746 ALOGE("%s: unsupported buffer type", __func__);
750 ret = ioctl(fd, VIDIOC_S_PARM, streamparm);
752 ALOGE("failed to ioctl: VIDIOC_S_PARM (%d - %s)", errno, strerror(errno));
759 int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
764 ALOGE("%s: invalid fd: %d", __func__, fd);
769 ALOGE("%s: ctrl is NULL", __func__);
773 ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, ctrl);
775 ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d - %s)", errno, strerror(errno));
780 int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
785 ALOGE("%s: invalid fd: %d", __func__, fd);
790 ALOGE("%s: ctrl is NULL", __func__);
794 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, ctrl);
796 ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d - %s)", errno, strerror(errno));