diff options
author | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-06-16 23:51:10 +0200 |
---|---|---|
committer | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-06-16 23:51:10 +0200 |
commit | e4998840d5667668db3e89356e0a681f70149bd3 (patch) | |
tree | 0b90eb760c6e175395f1b9f5aaf55d1ff7bec141 /v4l2-apps | |
parent | a48e6ba1941c59fc3fee73372eec6d3931000982 (diff) | |
download | mediapointer-dvb-s2-e4998840d5667668db3e89356e0a681f70149bd3.tar.gz mediapointer-dvb-s2-e4998840d5667668db3e89356e0a681f70149bd3.tar.bz2 |
libv4l: Fix a bug in the always report widths which are a multiple of 8 code
From: Hans de Goede <hdegoede@redhat.com>
Fix a bug in the always report widths which are a multiple of 8 code added
in 0.5.97
Priority: normal
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'v4l2-apps')
-rw-r--r-- | v4l2-apps/libv4l/ChangeLog | 2 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 54 |
2 files changed, 35 insertions, 21 deletions
diff --git a/v4l2-apps/libv4l/ChangeLog b/v4l2-apps/libv4l/ChangeLog index 4cc6ae4f6..e69a8c8f4 100644 --- a/v4l2-apps/libv4l/ChangeLog +++ b/v4l2-apps/libv4l/ChangeLog @@ -6,6 +6,8 @@ libv4l-0.6.0 an external helper as I've failed to contact Mark W. McClelland to get permission to relicense the code. If you know a working email address for Mark W. McClelland, please let me know. +* Fix a bug in the always report widths which are a multiple of 8 code added + in 0.5.97 libv4l-0.5.99 ------------- diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c index 998bc154d..1389c58bc 100644 --- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c +++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c @@ -359,7 +359,7 @@ int v4lconvert_try_format(struct v4lconvert_data *data, int i, result; unsigned int desired_width = dest_fmt->fmt.pix.width; unsigned int desired_height = dest_fmt->fmt.pix.height; - struct v4l2_format try_src, try_dest; + struct v4l2_format try_src, try_dest, try2_src, try2_dest; if (dest_fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && v4lconvert_supported_dst_fmt_only(data) && @@ -378,6 +378,29 @@ int v4lconvert_try_format(struct v4lconvert_data *data, return result; } + /* In case of a non exact resolution match, try again with a slightly larger + resolution as some weird devices are not able to crop of the number of + extra (border) pixels most sensors have compared to standard resolutions, + which we will then just crop of in software */ + if (try_dest.fmt.pix.width != desired_width || + try_dest.fmt.pix.height != desired_height) { + try2_dest = *dest_fmt; + try2_dest.fmt.pix.width = desired_width + 7; + try2_dest.fmt.pix.height = desired_height + 1; + result = v4lconvert_do_try_format(data, &try2_dest, &try2_src); + if (result == 0 && + try2_dest.fmt.pix.width >= desired_width && + try2_dest.fmt.pix.width <= desired_width + 7 && + try2_dest.fmt.pix.height >= desired_height && + try2_dest.fmt.pix.height <= desired_height + 1) { + /* Success! */ + try2_dest.fmt.pix.width = desired_width; + try2_dest.fmt.pix.height = desired_height; + try_dest = try2_dest; + try_src = try2_src; + } + } + /* In case of a non exact resolution match, see if this is a well known resolution some apps are hardcoded too and try to give the app what it asked for by cropping a slightly larger resolution or adding a small @@ -387,7 +410,7 @@ int v4lconvert_try_format(struct v4lconvert_data *data, for (i = 0; i < ARRAY_SIZE(v4lconvert_crop_res); i++) { if (v4lconvert_crop_res[i][0] == desired_width && v4lconvert_crop_res[i][1] == desired_height) { - struct v4l2_format try2_src, try2_dest = *dest_fmt; + try2_dest = *dest_fmt; /* Note these are chosen so that cropping to vga res just works for vv6410 sensor cams, which have 356x292 and 180x148 */ @@ -423,20 +446,13 @@ int v4lconvert_try_format(struct v4lconvert_data *data, /* Some applications / libs (*cough* gstreamer *cough*) will not work correctly with planar YUV formats when the width is not a multiple of 8 - or the height is not a multiple of 2 */ - if (try_dest.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420 || - try_dest.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) { - try_dest.fmt.pix.width &= ~7; - try_dest.fmt.pix.height &= ~1; - } - - /* Likewise the width needs to be a multiple of 4 for RGB formats - (although I've never seen a device with a width not a multiple of 4) */ - if (try_dest.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24 || - try_dest.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) - try_dest.fmt.pix.width &= ~3; + or the height is not a multiple of 2. With RGB formats these apps require + the width to be a multiple of 4. We apply the same rounding to all + formats to not end up with 2 close but different resolutions. */ + try_dest.fmt.pix.width &= ~7; + try_dest.fmt.pix.height &= ~1; - /* Are we converting? */ + /* Are we converting / cropping ? */ if(try_src.fmt.pix.width != try_dest.fmt.pix.width || try_src.fmt.pix.height != try_dest.fmt.pix.height || try_src.fmt.pix.pixelformat != try_dest.fmt.pix.pixelformat) @@ -1147,12 +1163,8 @@ int v4lconvert_enum_framesizes(struct v4lconvert_data *data, case V4L2_FRMSIZE_TYPE_DISCRETE: frmsize->discrete = data->framesizes[frmsize->index].discrete; /* Apply the same rounding algorithm as v4lconvert_try_format */ - if (frmsize->pixel_format == V4L2_PIX_FMT_YUV420 || - frmsize->pixel_format == V4L2_PIX_FMT_YVU420) { - frmsize->discrete.width &= ~7; - frmsize->discrete.height &= ~1; - } else - frmsize->discrete.width &= ~3; + frmsize->discrete.width &= ~7; + frmsize->discrete.height &= ~1; break; case V4L2_FRMSIZE_TYPE_CONTINUOUS: case V4L2_FRMSIZE_TYPE_STEPWISE: |