diff options
author | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-03-11 13:07:28 +0100 |
---|---|---|
committer | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-03-11 13:07:28 +0100 |
commit | 20b5011195e9b98e0cd6904e7a82d735ee542a52 (patch) | |
tree | cb873b05f2ce555d0b57861ad094f772225d5499 /v4l2-apps/libv4l/libv4l2 | |
parent | 8f3a94f3f8727434e98bd197727e9a8a1a8285c4 (diff) | |
download | mediapointer-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.c | 41 |
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; |