summaryrefslogtreecommitdiff
path: root/v4l2-apps/libv4l/libv4l2
diff options
context:
space:
mode:
authorhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-03-11 13:07:28 +0100
committerhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-03-11 13:07:28 +0100
commit20b5011195e9b98e0cd6904e7a82d735ee542a52 (patch)
treecb873b05f2ce555d0b57861ad094f772225d5499 /v4l2-apps/libv4l/libv4l2
parent8f3a94f3f8727434e98bd197727e9a8a1a8285c4 (diff)
downloadmediapointer-dvb-s2-20b5011195e9b98e0cd6904e7a82d735ee542a52.tar.gz
mediapointer-dvb-s2-20b5011195e9b98e0cd6904e7a82d735ee542a52.tar.bz2
libv4l: Make S_FMT handling more robust
From: Hans de Goede <hdegoede@redhat.com> Some drivers (pwc) do not properly reflect what one really gets after a s_fmt in their try_fmt answer. So update dest format (which we report as result from s_fmt / g_fmt to the app) with all info from the src format not changed by conversion. Priority: normal Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'v4l2-apps/libv4l/libv4l2')
-rw-r--r--v4l2-apps/libv4l/libv4l2/libv4l2.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/v4l2-apps/libv4l/libv4l2/libv4l2.c b/v4l2-apps/libv4l/libv4l2/libv4l2.c
index 0a05623cb..dd422ea34 100644
--- a/v4l2-apps/libv4l/libv4l2/libv4l2.c
+++ b/v4l2-apps/libv4l/libv4l2/libv4l2.c
@@ -620,6 +620,36 @@ static int v4l2_check_buffer_change_ok(int index)
return 0;
}
+static int v4l2_pix_fmt_identical(struct v4l2_format *a, struct v4l2_format *b)
+{
+ if (a->fmt.pix.width == b->fmt.pix.width &&
+ a->fmt.pix.height == b->fmt.pix.height &&
+ a->fmt.pix.pixelformat == b->fmt.pix.pixelformat &&
+ a->fmt.pix.field == b->fmt.pix.field)
+ return 1;
+
+ return 0;
+}
+
+static void v4l2_set_src_and_dest_format(int index,
+ struct v4l2_format *src_fmt, struct v4l2_format *dest_fmt)
+{
+ /* Sigh some drivers (pwc) do not properly reflect what one really gets
+ after a s_fmt in their try_fmt answer. So update dest format (which we
+ report as result from s_fmt / g_fmt to the app) with all info from the src
+ format not changed by conversion */
+ dest_fmt->fmt.pix.field = src_fmt->fmt.pix.field;
+ dest_fmt->fmt.pix.colorspace = src_fmt->fmt.pix.colorspace;
+ /* When we're not converting use bytesperline and imagesize from src_fmt */
+ if (v4l2_pix_fmt_identical(src_fmt, dest_fmt)) {
+ dest_fmt->fmt.pix.bytesperline = src_fmt->fmt.pix.bytesperline;
+ dest_fmt->fmt.pix.sizeimage = src_fmt->fmt.pix.sizeimage;
+ }
+
+ devices[index].src_fmt = *src_fmt;
+ devices[index].dest_fmt = *dest_fmt;
+}
+
int v4l2_ioctl (int fd, unsigned long int request, ...)
{
void *arg;
@@ -735,7 +765,8 @@ int v4l2_ioctl (int fd, unsigned long int request, ...)
{
struct v4l2_format src_fmt, *dest_fmt = arg;
- if (!memcmp(&devices[index].dest_fmt, dest_fmt, sizeof(*dest_fmt))) {
+ if (v4l2_pix_fmt_identical(&devices[index].dest_fmt, dest_fmt)) {
+ *dest_fmt = devices[index].dest_fmt;
result = 0;
break;
}
@@ -775,8 +806,9 @@ int v4l2_ioctl (int fd, unsigned long int request, ...)
/* Maybe after try format has adjusted width/height etc, to whats
available nothing has changed (on the cam side) ? */
- if (!memcmp(&devices[index].src_fmt, &src_fmt, sizeof(src_fmt))) {
- devices[index].dest_fmt = *dest_fmt;
+ if (v4l2_pix_fmt_identical(&devices[index].src_fmt, &src_fmt)) {
+ v4l2_set_src_and_dest_format(index, &devices[index].src_fmt,
+ dest_fmt);
result = 0;
break;
}
@@ -794,8 +826,7 @@ int v4l2_ioctl (int fd, unsigned long int request, ...)
break;
}
- devices[index].src_fmt = src_fmt;
- devices[index].dest_fmt = *dest_fmt;
+ v4l2_set_src_and_dest_format(index, &src_fmt, dest_fmt);
}
break;