summaryrefslogtreecommitdiff
path: root/v4l2-apps/libv4l
diff options
context:
space:
mode:
authorhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-05-19 14:25:22 +0200
committerhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-05-19 14:25:22 +0200
commita077e421fe63a7102f6bbaa7057df7690e239cf6 (patch)
tree2826d2c39abf876dd7462a91a26b0a40873fb396 /v4l2-apps/libv4l
parente760f2575db92f9bdfe64e24d817409d4e7518d8 (diff)
downloadmediapointer-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/ChangeLog1
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/flip.c129
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h2
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c2
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: