From 18d8f58054d630d7f1c80f5586aaa7331d4f46e7 Mon Sep 17 00:00:00 2001 From: "hans@rhel5-devel.localdomain" Date: Tue, 14 Apr 2009 23:11:39 +0200 Subject: libv4l: crop widths to the nearest multiple of 8 when converting to YUV420 From: Hans de Goede Some applications / libs (*cough* gstreamer *cough*) will not work correctly with planar YUV formats when the width is not a multiple of 8, so crop widths which are not a multiple of 8 to the nearest multiple of 8 when converting to planar YUV Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/libv4l/ChangeLog | 4 ++++ v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/v4l2-apps/libv4l/ChangeLog b/v4l2-apps/libv4l/ChangeLog index b1f4c3a22..e60ccdbb2 100644 --- a/v4l2-apps/libv4l/ChangeLog +++ b/v4l2-apps/libv4l/ChangeLog @@ -16,6 +16,10 @@ libv4l-0.5.97 can then change the settings using a v4l2 control panel like v4l2ucp * Only report / allow supported destination formats in enum_fmt / try_fmt / g_fmt / s_fmt when processing, rotating or flipping. +* Some applications / libs (*cough* gstreamer *cough*) will not work + correctly with planar YUV formats when the width is not a multiple of 8, + so crop widths which are not a multiple of 8 to the nearest multiple of 8 + when converting to planar YUV * Add dependency generation to libv4l by: Gilles Gigan * Add support to use orientation from VIDIOC_ENUMINPUT by: Adam Baker diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c index 2e029a81c..39e9d8669 100644 --- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c +++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c @@ -398,6 +398,21 @@ 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; + /* Are we converting? */ if(try_src.fmt.pix.width != try_dest.fmt.pix.width || try_src.fmt.pix.height != try_dest.fmt.pix.height || @@ -1083,6 +1098,13 @@ int v4lconvert_enum_framesizes(struct v4lconvert_data *data, switch(frmsize->type) { 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; break; case V4L2_FRMSIZE_TYPE_CONTINUOUS: case V4L2_FRMSIZE_TYPE_STEPWISE: -- cgit v1.2.3