diff options
author | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-05-19 14:25:22 +0200 |
---|---|---|
committer | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-05-19 14:25:22 +0200 |
commit | a077e421fe63a7102f6bbaa7057df7690e239cf6 (patch) | |
tree | 2826d2c39abf876dd7462a91a26b0a40873fb396 /v4l2-apps/libv4l | |
parent | e760f2575db92f9bdfe64e24d817409d4e7518d8 (diff) | |
download | mediapointer-dvb-s2-a077e421fe63a7102f6bbaa7057df7690e239cf6.tar.gz mediapointer-dvb-s2-a077e421fe63a7102f6bbaa7057df7690e239cf6.tar.bz2 |
libv4l: support separate vfliping and hfliping
From: Hans de Goede <hdegoede@redhat.com>
Before this patch libv4l only support 180 degree rotation, which is
hflip and vflip combined, this patch adds support for separate
hflipping and vflipping.
Priority: normal
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'v4l2-apps/libv4l')
-rw-r--r-- | v4l2-apps/libv4l/ChangeLog | 1 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/flip.c | 129 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h | 2 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 2 |
4 files changed, 128 insertions, 6 deletions
diff --git a/v4l2-apps/libv4l/ChangeLog b/v4l2-apps/libv4l/ChangeLog index 82402f1bf..aa0a3ea3c 100644 --- a/v4l2-apps/libv4l/ChangeLog +++ b/v4l2-apps/libv4l/ChangeLog @@ -8,6 +8,7 @@ libv4l-0.5.98 * Support V4L2_CTRL_FLAG_NEXT_CTRL for fake controls by Adam Baker * Add ability to determine upside down cams based on DMI info * Fix a bug in v4lconvert_uyvy_to_yuv420() +* Add support for separate vflipping and hflipping libv4l-0.5.97 ------------- diff --git a/v4l2-apps/libv4l/libv4lconvert/flip.c b/v4l2-apps/libv4l/libv4lconvert/flip.c index cc9526493..5d881844a 100644 --- a/v4l2-apps/libv4l/libv4lconvert/flip.c +++ b/v4l2-apps/libv4l/libv4lconvert/flip.c @@ -23,6 +23,97 @@ #include <string.h> #include "libv4lconvert-priv.h" +static void v4lconvert_vflip_rgbbgr24(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int y; + + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline; + for (y = 0; y < fmt->fmt.pix.height; y++) { + src -= fmt->fmt.pix.bytesperline; + memcpy(dest, src, fmt->fmt.pix.width * 3); + dest += fmt->fmt.pix.width * 3; + } +} + +static void v4lconvert_vflip_yuv420(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int y; + + /* First flip the Y plane */ + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline; + for (y = 0; y < fmt->fmt.pix.height; y++) { + src -= fmt->fmt.pix.bytesperline; + memcpy(dest, src, fmt->fmt.pix.width); + dest += fmt->fmt.pix.width; + } + + /* Now flip the U plane */ + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline * 5 / 4; + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src -= fmt->fmt.pix.bytesperline / 2; + memcpy(dest, src, fmt->fmt.pix.width / 2); + dest += fmt->fmt.pix.width / 2; + } + + /* Last flip the V plane */ + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline / 2; + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src -= fmt->fmt.pix.bytesperline / 2; + memcpy(dest, src, fmt->fmt.pix.width / 2); + dest += fmt->fmt.pix.width / 2; + } +} + +static void v4lconvert_hflip_rgbbgr24(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int x, y; + + for (y = 0; y < fmt->fmt.pix.height; y++) { + src += fmt->fmt.pix.width * 3; + for (x = 0; x < fmt->fmt.pix.width; x++) { + src -= 3; + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest += 3; + } + src += fmt->fmt.pix.bytesperline; + } +} + +static void v4lconvert_hflip_yuv420(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int x, y; + + /* First flip the Y plane */ + for (y = 0; y < fmt->fmt.pix.height; y++) { + src += fmt->fmt.pix.width; + for (x = 0; x < fmt->fmt.pix.width; x++) + *dest++ = *--src; + src += fmt->fmt.pix.bytesperline; + } + + /* Now flip the U plane */ + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src += fmt->fmt.pix.width / 2; + for (x = 0; x < fmt->fmt.pix.width / 2; x++) + *dest++ = *--src; + src += fmt->fmt.pix.bytesperline / 2; + } + + /* Last flip the V plane */ + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src += fmt->fmt.pix.width / 2; + for (x = 0; x < fmt->fmt.pix.width / 2; x++) + *dest++ = *--src; + src += fmt->fmt.pix.bytesperline / 2; + } +} + static void v4lconvert_rotate180_rgbbgr24(const unsigned char *src, unsigned char *dst, int width, int height) { @@ -133,9 +224,35 @@ void v4lconvert_rotate90(unsigned char *src, unsigned char *dest, void v4lconvert_flip(unsigned char *src, unsigned char *dest, struct v4l2_format *fmt, int flags) { - /* FIXME implement separate vflipping and hflipping, for now we always - rotate 180 when vflip is selected! */ - if (flags & V4LCONTROL_VFLIPPED) { + switch (flags & (V4LCONTROL_VFLIPPED|V4LCONTROL_HFLIPPED)) { + + case V4LCONTROL_VFLIPPED: + switch (fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + v4lconvert_vflip_rgbbgr24(src, dest, fmt); + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + v4lconvert_vflip_yuv420(src, dest, fmt); + break; + } + break; + + case V4LCONTROL_HFLIPPED: + switch (fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + v4lconvert_hflip_rgbbgr24(src, dest, fmt); + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + v4lconvert_hflip_yuv420(src, dest, fmt); + break; + } + break; + + case (V4LCONTROL_VFLIPPED|V4LCONTROL_HFLIPPED): switch (fmt->fmt.pix.pixelformat) { case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_BGR24: @@ -148,7 +265,9 @@ void v4lconvert_flip(unsigned char *src, unsigned char *dest, fmt->fmt.pix.height); break; } + break; } - else /* FIXME and do nothing when only HFLIP is selected */ - memcpy(dest, src, fmt->fmt.pix.sizeimage); + + /* Our newly written data has no padding */ + v4lconvert_fixup_fmt(fmt); } diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h index 4a333d9a9..2d34bd6a4 100644 --- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h +++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h @@ -127,6 +127,8 @@ struct v4lconvert_pixfmt { int flags; }; +void v4lconvert_fixup_fmt(struct v4l2_format *fmt); + void v4lconvert_rgb24_to_yuv420(const unsigned char *src, unsigned char *dest, const struct v4l2_format *src_fmt, int bgr, int yvu); diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c index 39e9d8669..a175973ef 100644 --- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c +++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c @@ -321,7 +321,7 @@ static int v4lconvert_do_try_format(struct v4lconvert_data *data, return 0; } -static void v4lconvert_fixup_fmt(struct v4l2_format *fmt) +void v4lconvert_fixup_fmt(struct v4l2_format *fmt) { switch (fmt->fmt.pix.pixelformat) { case V4L2_PIX_FMT_RGB24: |