summaryrefslogtreecommitdiff
path: root/v4l2-apps
diff options
context:
space:
mode:
authorhans@localhost.localdomain <hans@localhost.localdomain>2008-09-15 13:48:21 +0200
committerhans@localhost.localdomain <hans@localhost.localdomain>2008-09-15 13:48:21 +0200
commit37365f711151fceee2bbc87ef7836c5f08b7c1f1 (patch)
tree75939c8fa46e5f8c4e242873521c0852366ce427 /v4l2-apps
parentd00cfd7d61d0a9cf2b38a816bfd5478f3342a0e4 (diff)
downloadmediapointer-dvb-s2-37365f711151fceee2bbc87ef7836c5f08b7c1f1.tar.gz
mediapointer-dvb-s2-37365f711151fceee2bbc87ef7836c5f08b7c1f1.tar.bz2
libv4l: 0.5.0 release
From: Hans de Goede <hdegoede@redhat.com> * Add support for enumerating framesizes and frameintervals of emulated formats when the driver supports it for the real format * Make sure the video device always gets opened RW even if the application asks for RO * Add Genius E-Messenger 112 (093a:2476) to list of cams which have their sensor upside down Priority: normal Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'v4l2-apps')
-rw-r--r--v4l2-apps/lib/libv4l/ChangeLog9
-rw-r--r--v4l2-apps/lib/libv4l/Makefile2
-rw-r--r--v4l2-apps/lib/libv4l/include/libv4lconvert.h10
-rw-r--r--v4l2-apps/lib/libv4l/libv4l1/libv4l1.c15
-rw-r--r--v4l2-apps/lib/libv4l/libv4l1/log.c6
-rw-r--r--v4l2-apps/lib/libv4l/libv4l2/libv4l2.c13
-rw-r--r--v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c15
-rw-r--r--v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h3
-rw-r--r--v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c153
9 files changed, 201 insertions, 25 deletions
diff --git a/v4l2-apps/lib/libv4l/ChangeLog b/v4l2-apps/lib/libv4l/ChangeLog
index 8a7131afb..dd53eced9 100644
--- a/v4l2-apps/lib/libv4l/ChangeLog
+++ b/v4l2-apps/lib/libv4l/ChangeLog
@@ -1,3 +1,12 @@
+libv4l-0.5.0
+------------
+* Add support for enumerating framesizes and frameintervals of emulated
+ formats when the driver supports it for the real format
+* Make sure the video device always gets opened RW even if the application
+ asks for RO
+* Add Genius E-Messenger 112 (093a:2476) to list of cams which have their
+ sensor upside down
+
libv4l-0.4.3
------------
* Add suport for YUYV and YVYU packed pixel formats (Jean-Francois Moine)
diff --git a/v4l2-apps/lib/libv4l/Makefile b/v4l2-apps/lib/libv4l/Makefile
index 2fa7ca51f..4c99c3167 100644
--- a/v4l2-apps/lib/libv4l/Makefile
+++ b/v4l2-apps/lib/libv4l/Makefile
@@ -1,5 +1,5 @@
LIB_RELEASE=0
-V4L2_LIB_VERSION=$(LIB_RELEASE).4.3
+V4L2_LIB_VERSION=$(LIB_RELEASE).5.0
all clean install:
$(MAKE) -C libv4lconvert V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@
diff --git a/v4l2-apps/lib/libv4l/include/libv4lconvert.h b/v4l2-apps/lib/libv4l/include/libv4lconvert.h
index 87e41ceaa..626c43473 100644
--- a/v4l2-apps/lib/libv4l/include/libv4lconvert.h
+++ b/v4l2-apps/lib/libv4l/include/libv4lconvert.h
@@ -71,6 +71,16 @@ LIBV4L_PUBLIC int v4lconvert_convert(struct v4lconvert_data *data,
/* get a string describing the last error*/
LIBV4L_PUBLIC const char *v4lconvert_get_error_message(struct v4lconvert_data *data);
+/* Just like VIDIOC_ENUM_FRAMESIZE, except that the framesizes of emulated
+ formats can be enumerated as well. */
+LIBV4L_PUBLIC int v4lconvert_enum_framesizes(struct v4lconvert_data *data,
+ struct v4l2_frmsizeenum *frmsize);
+
+/* Just like VIDIOC_ENUM_FRAMEINTERVALS, except that the intervals of emulated
+ formats can be enumerated as well. */
+LIBV4L_PUBLIC int v4lconvert_enum_frameintervals(struct v4lconvert_data *data,
+ struct v4l2_frmivalenum *frmival);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c
index 39f2d29e0..797c8768a 100644
--- a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c
+++ b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c
@@ -259,6 +259,15 @@ int v4l1_open (const char *file, int oflag, ...)
struct v4l2_format fmt2;
struct v4l2_input input2;
struct v4l2_standard standard2;
+ int v4l_device = 0;
+
+ /* check if we're opening a video4linux2 device */
+ if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) {
+ /* Some apps open the device read only, but we need rw rights as the
+ buffers *MUST* be mapped rw */
+ oflag = (oflag & ~O_ACCMODE) | O_RDWR;
+ v4l_device = 1;
+ }
/* original open code */
if (oflag & O_CREAT)
@@ -276,11 +285,7 @@ int v4l1_open (const char *file, int oflag, ...)
fd = syscall(SYS_open, file, oflag);
/* end of original open code */
- if (fd == -1)
- return fd;
-
- /* check if we're opening a video4linux2 device */
- if (strncmp(file, "/dev/video", 10) && strncmp(file, "/dev/v4l/", 9))
+ if (fd == -1 || !v4l_device)
return fd;
/* check that this is an v4l2 device, no need to emulate v4l1 on
diff --git a/v4l2-apps/lib/libv4l/libv4l1/log.c b/v4l2-apps/lib/libv4l/libv4l1/log.c
index 74ce0f20b..9ff0cea46 100644
--- a/v4l2-apps/lib/libv4l/libv4l1/log.c
+++ b/v4l2-apps/lib/libv4l/libv4l1/log.c
@@ -66,6 +66,7 @@ static const char *v4l1_ioctls[] = {
void v4l1_log_ioctl(unsigned long int request, void *arg, int result)
{
const char *ioctl_str = "unknown";
+ char buf[40];
if (!v4l1_log_file)
return;
@@ -77,6 +78,11 @@ void v4l1_log_ioctl(unsigned long int request, void *arg, int result)
if (_IOC_TYPE(request) == 'v' && _IOC_NR(request) < ARRAY_SIZE(v4l1_ioctls))
ioctl_str = v4l1_ioctls[_IOC_NR(request)];
+ else {
+ snprintf(buf, sizeof(buf), "unknown request: %c %d\n",
+ (int)_IOC_TYPE(request), (int)_IOC_NR(request));
+ ioctl_str = buf;
+ }
fprintf(v4l1_log_file, "request == %s\n", ioctl_str);
diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c
index 937c06cce..b4a10afac 100644
--- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c
+++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c
@@ -649,6 +649,11 @@ int v4l2_ioctl (int fd, unsigned long int request, ...)
(devices[index].flags & V4L2_ENABLE_ENUM_FMT_EMULATION))
is_capture_request = 1;
break;
+ case VIDIOC_ENUM_FRAMESIZES:
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ if (devices[index].flags & V4L2_ENABLE_ENUM_FMT_EMULATION)
+ is_capture_request = 1;
+ break;
case VIDIOC_TRY_FMT:
if (((struct v4l2_format *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
is_capture_request = 1;
@@ -714,6 +719,14 @@ int v4l2_ioctl (int fd, unsigned long int request, ...)
result = v4lconvert_enum_fmt(devices[index].convert, arg);
break;
+ case VIDIOC_ENUM_FRAMESIZES:
+ result = v4lconvert_enum_framesizes(devices[index].convert, arg);
+ break;
+
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ result = v4lconvert_enum_frameintervals(devices[index].convert, arg);
+ break;
+
case VIDIOC_TRY_FMT:
result = v4lconvert_try_format(devices[index].convert, arg, NULL);
break;
diff --git a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c
index e8756f338..307a03ce5 100644
--- a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c
+++ b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c
@@ -53,6 +53,15 @@ LIBV4L_PUBLIC int open (const char *file, int oflag, ...)
{
int fd;
struct v4l2_capability cap;
+ int v4l_device = 0;
+
+ /* check if we're opening a video4linux2 device */
+ if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) {
+ /* Some apps open the device read only, but we need rw rights as the
+ buffers *MUST* be mapped rw */
+ oflag = (oflag & ~O_ACCMODE) | O_RDWR;
+ v4l_device = 1;
+ }
/* original open code */
if (oflag & O_CREAT)
@@ -70,11 +79,7 @@ LIBV4L_PUBLIC int open (const char *file, int oflag, ...)
fd = syscall(SYS_open, file, oflag);
/* end of original open code */
- if (fd == -1)
- return fd;
-
- /* check if we're opening a video4linux2 device */
- if (strncmp(file, "/dev/video", 10) && strncmp(file, "/dev/v4l/", 9))
+ if (fd == -1 || !v4l_device)
return fd;
/* check that this is an v4l2 device, libv4l2 only supports v4l2 devices */
diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h
index a2086e6fd..0c4eff6ce 100644
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h
@@ -64,6 +64,7 @@
#endif
#define V4LCONVERT_ERROR_MSG_SIZE 256
+#define V4LCONVERT_MAX_FRAMESIZES 16
#define V4LCONVERT_ERR(...) \
snprintf(data->error_msg, V4LCONVERT_ERROR_MSG_SIZE, \
@@ -82,6 +83,8 @@ struct v4lconvert_data {
unsigned int no_formats;
char error_msg[V4LCONVERT_ERROR_MSG_SIZE];
struct jdec_private *jdec;
+ struct v4l2_frmsizeenum framesizes[V4LCONVERT_MAX_FRAMESIZES];
+ unsigned int no_framesizes;
};
struct v4lconvert_flags_info {
diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c
index cbd4ca5a8..93bc67c7e 100644
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c
@@ -34,6 +34,9 @@
{ V4L2_PIX_FMT_BGR24, 0 }, \
{ V4L2_PIX_FMT_YUV420, 0 }
+static void v4lconvert_get_framesizes(struct v4lconvert_data *data,
+ unsigned int pixelformat);
+
/* Note uncompressed formats must go first so that they are prefered by
v4lconvert_try_format for low resolutions */
static const struct v4lconvert_pixfmt supported_src_pixfmts[] = {
@@ -61,10 +64,11 @@ static const struct v4lconvert_pixfmt supported_dst_pixfmts[] = {
/* List of cams which need special flags */
static const struct v4lconvert_flags_info v4lconvert_flags[] = {
- { "USB Camera (0471:0325)", V4LCONVERT_UPSIDE_DOWN }, /* SPC200NC */
- { "USB Camera (0471:0326)", V4LCONVERT_UPSIDE_DOWN }, /* SPC300NC */
{ "SPC 200NC ", V4LCONVERT_UPSIDE_DOWN },
{ "SPC 300NC ", V4LCONVERT_UPSIDE_DOWN },
+ { "USB Camera (0471:0325)", V4LCONVERT_UPSIDE_DOWN }, /* SPC200NC */
+ { "USB Camera (0471:0326)", V4LCONVERT_UPSIDE_DOWN }, /* SPC300NC */
+ { "USB Camera (093a:2476)", V4LCONVERT_UPSIDE_DOWN }, /* Genius E-M 112 */
};
struct v4lconvert_data *v4lconvert_create(int fd)
@@ -93,6 +97,8 @@ struct v4lconvert_data *v4lconvert_create(int fd)
data->supported_src_formats |= 1 << j;
break;
}
+
+ v4lconvert_get_framesizes(data, fmt.pixelformat);
}
data->no_formats = i;
@@ -119,6 +125,17 @@ void v4lconvert_destroy(struct v4lconvert_data *data)
free(data);
}
+static int v4lconvert_supported_dst_format(unsigned int pixelformat)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
+ if (supported_dst_pixfmts[i].fmt == pixelformat)
+ break;
+
+ return i != ARRAY_SIZE(supported_dst_pixfmts);
+}
+
/* See libv4lconvert.h for description of in / out parameters */
int v4lconvert_enum_fmt(struct v4lconvert_data *data, struct v4l2_fmtdesc *fmt)
{
@@ -163,12 +180,8 @@ int v4lconvert_try_format(struct v4lconvert_data *data,
unsigned int desired_pixfmt = dest_fmt->fmt.pix.pixelformat;
struct v4l2_format try_fmt, closest_fmt = { .type = 0 };
- for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
- if (supported_dst_pixfmts[i].fmt == desired_pixfmt)
- break;
-
/* Can we do conversion to the requested format & type? */
- if (i == ARRAY_SIZE(supported_dst_pixfmts) ||
+ if (!v4lconvert_supported_dst_format(desired_pixfmt) ||
dest_fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
int ret = syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, dest_fmt);
if (src_fmt)
@@ -243,8 +256,6 @@ int v4lconvert_needs_conversion(struct v4lconvert_data *data,
const struct v4l2_format *src_fmt, /* in */
const struct v4l2_format *dest_fmt) /* in */
{
- int i;
-
if(memcmp(src_fmt, dest_fmt, sizeof(*src_fmt)))
return 1; /* Formats differ */
@@ -252,11 +263,7 @@ int v4lconvert_needs_conversion(struct v4lconvert_data *data,
return 0; /* Formats identical and we don't need flip */
/* Formats are identical, but we need flip, do we support the dest_fmt? */
- for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++)
- if (supported_dst_pixfmts[i].fmt == dest_fmt->fmt.pix.pixelformat)
- break;
-
- if (i == ARRAY_SIZE(supported_dst_pixfmts))
+ if (!v4lconvert_supported_dst_format(dest_fmt->fmt.pix.pixelformat))
return 0; /* Needs flip but we cannot do it :( */
else
return 1; /* Needs flip and thus conversion */
@@ -610,3 +617,121 @@ const char *v4lconvert_get_error_message(struct v4lconvert_data *data)
{
return data->error_msg;
}
+
+static void v4lconvert_get_framesizes(struct v4lconvert_data *data,
+ unsigned int pixelformat)
+{
+ int i, j, match;
+ struct v4l2_frmsizeenum frmsize = { .pixel_format = pixelformat };
+
+ for (i = 0; ; i++) {
+ frmsize.index = i;
+ if (syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize))
+ break;
+
+ /* We got a framesize, check we don't have the same one already */
+ match = 0;
+ for (j = 0; j < data->no_framesizes && !match; j++) {
+ if (frmsize.type != data->framesizes[j].type)
+ continue;
+
+ switch(frmsize.type) {
+ case V4L2_FRMSIZE_TYPE_DISCRETE:
+ if(!memcmp(&frmsize.discrete, &data->framesizes[j].discrete,
+ sizeof(frmsize.discrete)))
+ match = 1;
+ break;
+ case V4L2_FRMSIZE_TYPE_CONTINUOUS:
+ case V4L2_FRMSIZE_TYPE_STEPWISE:
+ if(!memcmp(&frmsize.stepwise, &data->framesizes[j].stepwise,
+ sizeof(frmsize.stepwise)))
+ match = 1;
+ break;
+ }
+ }
+ /* Add this framesize if it is not already in our list */
+ if (!match) {
+ if (data->no_framesizes == V4LCONVERT_MAX_FRAMESIZES) {
+ fprintf(stderr,
+ "libv4lconvert: warning more framesizes then I can handle!\n");
+ return;
+ }
+ data->framesizes[data->no_framesizes].type = frmsize.type;
+ switch(frmsize.type) {
+ case V4L2_FRMSIZE_TYPE_DISCRETE:
+ data->framesizes[data->no_framesizes].discrete = frmsize.discrete;
+ break;
+ case V4L2_FRMSIZE_TYPE_CONTINUOUS:
+ case V4L2_FRMSIZE_TYPE_STEPWISE:
+ data->framesizes[data->no_framesizes].stepwise = frmsize.stepwise;
+ break;
+ }
+ data->no_framesizes++;
+ }
+ }
+}
+
+int v4lconvert_enum_framesizes(struct v4lconvert_data *data,
+ struct v4l2_frmsizeenum *frmsize)
+{
+ if (!v4lconvert_supported_dst_format(frmsize->pixel_format))
+ return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMESIZES, frmsize);
+
+ if (frmsize->index >= data->no_framesizes) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ frmsize->type = data->framesizes[frmsize->index].type;
+ switch(frmsize->type) {
+ case V4L2_FRMSIZE_TYPE_DISCRETE:
+ frmsize->discrete = data->framesizes[frmsize->index].discrete;
+ break;
+ case V4L2_FRMSIZE_TYPE_CONTINUOUS:
+ case V4L2_FRMSIZE_TYPE_STEPWISE:
+ frmsize->stepwise = data->framesizes[frmsize->index].stepwise;
+ break;
+ }
+
+ return 0;
+}
+
+int v4lconvert_enum_frameintervals(struct v4lconvert_data *data,
+ struct v4l2_frmivalenum *frmival)
+{
+ int res;
+ struct v4l2_format src_fmt, dest_fmt;
+
+ if (!v4lconvert_supported_dst_format(frmival->pixel_format))
+ return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival);
+
+ /* Check which format we will be using to convert to frmival->pixel_format */
+ memset(&dest_fmt, 0, sizeof(dest_fmt));
+ dest_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dest_fmt.fmt.pix.pixelformat = frmival->pixel_format;
+ dest_fmt.fmt.pix.width = frmival->width;
+ dest_fmt.fmt.pix.height = frmival->height;
+ if ((res = v4lconvert_try_format(data, &dest_fmt, &src_fmt)))
+ return res;
+
+ /* Check the requested format is supported exactly as requested */
+ if (dest_fmt.fmt.pix.pixelformat != frmival->pixel_format ||
+ dest_fmt.fmt.pix.width != frmival->width ||
+ dest_fmt.fmt.pix.height != frmival->height) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Enumerate the frameintervals of the source format we will be using */
+ frmival->pixel_format = src_fmt.fmt.pix.pixelformat;
+ frmival->width = src_fmt.fmt.pix.width;
+ frmival->height = src_fmt.fmt.pix.height;
+ res = syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival);
+
+ /* Restore the requested format in the frmival struct */
+ frmival->pixel_format = dest_fmt.fmt.pix.pixelformat;
+ frmival->width = dest_fmt.fmt.pix.width;
+ frmival->height = dest_fmt.fmt.pix.height;
+
+ return res;
+}