Hi Ville,
Ville Syrj�l� <[EMAIL PROTECTED]> writes:
> This patch adds YUV support to gFillRectangle(). Both packed and planar
> formats are supported. The specified RGB color is converted to YCbCr so
> it doesn't need any API changes. The color conversion formula was taken
> from the v4l2 site. I didn't check the math myself since it seems to work.
> I just needed this to make Clear() work for the CRTC2 layer when in YUV
> mode. Any corrections or other comments?
I've applied your patch to my tree and tried to simplify it a bit.
I'd appreciate if you could try the attached patch and report
back. I'm still not overly happy with the color conversion macros
using floats but we can easily replace them later.
Salut, Sven
? colorhash.diff
? lcd-font.diff
? surface-resize.diff
? yuv_fillrect.patch
? src/after
? src/argb_blend_funcs.diff
? src/before
? src/colorhash.diff
? src/display/idirectfbsurface_util.c
? src/display/idirectfbsurface_util.h
? src/misc/colorhash.c
? src/misc/colorhash.h
? tools/test
? tools/test.c
? tools/test.h
Index: src/gfx/convert.h
===================================================================
RCS file: /cvs/directfb/DirectFB/src/gfx/convert.h,v
retrieving revision 1.14
diff -u -p -b -r1.14 convert.h
--- src/gfx/convert.h 8 Aug 2002 20:02:42 -0000 1.14
+++ src/gfx/convert.h 14 Aug 2002 13:14:38 -0000
@@ -34,6 +34,8 @@
#include "misc/memcpy.h"
+/* pixel packing */
+
#define PIXEL_RGB332(r,g,b) ( (((r)&0xE0) ) | \
(((g)&0xE0) >> 3) | \
(((b)&0xC0) >> 6) )
@@ -59,6 +61,18 @@
((g) << 8) | \
(b) )
+#define PIXEL_YUY2(y,u,v) ( ((v) << 24) | \
+ ((y) << 16) | \
+ ((u) << 8) | \
+ (y) )
+
+#define PIXEL_UYVY(y,u,v) ( ((y) << 24) | \
+ ((v) << 16) | \
+ ((y) << 8) | \
+ (u) )
+
+
+/* packed pixel conversions */
#define RGB15_TO_RGB332(pixel) ( (((pixel) & 0x7000) >> 7) | \
(((pixel) & 0x0380) >> 5) | \
@@ -119,6 +133,19 @@
#define RGB32_TO_RGB24(pixel) ( (pixel) & 0x00FFFFFF )
#define RGB32_TO_ARGB(pixel) ( 0xFF000000 | (pixel) )
+
+
+/* RGB to YUV */
+
+#define Y_FROM_RGB(r,g,b) ( ( 0.2290 * r + 0.5670 * g + 0.1440 * b) * \
+ 219 / 255 + 16 )
+
+#define CB_FROM_RGB(r,g,b) ( (-0.1687 * r - 0.3313 * g + 0.5000 * b) * \
+ 112 / 127 + 128)
+
+#define CR_FROM_RGB(r,g,b) ( ( 0.5000 * r - 0.4187 * g - 0.0813 * b) * \
+ 112 / 127 + 128)
+
static inline DFBSurfacePixelFormat dfb_pixelformat_for_depth( int depth )
Index: src/gfx/generic/generic.c
===================================================================
RCS file: /cvs/directfb/DirectFB/src/gfx/generic/generic.c,v
retrieving revision 1.92
diff -u -p -b -r1.92 generic.c
--- src/gfx/generic/generic.c 13 Aug 2002 11:56:04 -0000 1.92
+++ src/gfx/generic/generic.c 14 Aug 2002 13:14:38 -0000
@@ -89,6 +89,9 @@ void *Aop = NULL;
static void *Bop = NULL;
static __u32 Cop = 0;
+static __u8 CbCop = 0;
+static __u8 CrCop = 0;
+
/*
* color keys
*/
@@ -201,15 +204,15 @@ static GFunc Cop_to_Aop_PFI[DFB_NUM_PIXE
Cop_to_Aop_32,
Cop_to_Aop_32,
Cop_to_Aop_8,
- NULL,
+ Cop_to_Aop_32,
#ifdef SUPPORT_RGB332
Cop_to_Aop_8,
#else
NULL,
#endif
- NULL,
- NULL,
- NULL,
+ Cop_to_Aop_32,
+ Cop_to_Aop_8,
+ Cop_to_Aop_8,
Cop_to_Aop_8
};
@@ -2579,22 +2582,32 @@ int gAquire( CardState *state, DFBAccele
case DSPF_A8:
Cop = color.a;
break;
+ case DSPF_YUY2:
+ Cop = Y_FROM_RGB( color.r, color.g, color.b );
+ CbCop = CB_FROM_RGB( color.r, color.g, color.b );
+ CrCop = CR_FROM_RGB( color.r, color.g, color.b );
+ Cop = PIXEL_YUY2( Cop, CbCop, CrCop );
+ break;
#ifdef SUPPORT_RGB332
case DSPF_RGB332:
Cop = PIXEL_RGB332( color.r, color.g, color.b );
break;
#endif
- case DSPF_YUY2:
case DSPF_UYVY:
+ Cop = Y_FROM_RGB( color.r, color.g, color.b );
+ CbCop = CB_FROM_RGB( color.r, color.g, color.b );
+ CrCop = CR_FROM_RGB( color.r, color.g, color.b );
+ Cop = PIXEL_UYVY( Cop, CbCop, CrCop );
+ break;
case DSPF_I420:
+ Cop = Y_FROM_RGB( color.r, color.g, color.b );
+ CbCop = CB_FROM_RGB( color.r, color.g, color.b );
+ CrCop = CR_FROM_RGB( color.r, color.g, color.b );
+ break;
case DSPF_YV12:
- if (accel != DFXL_BLIT || src_format != dst_format ||
- state->blittingflags != DSBLIT_NOFX)
- {
- ONCE("only copying blits supported for YUV in software");
- pthread_mutex_unlock( &generic_lock );
- return 0;
- }
+ Cop = Y_FROM_RGB( color.r, color.g, color.b );
+ CbCop = CR_FROM_RGB( color.r, color.g, color.b );
+ CrCop = CB_FROM_RGB( color.r, color.g, color.b );
break;
case DSPF_LUT8:
Cop = state->color_index;
@@ -3132,17 +3145,52 @@ static void Bop_prev( int pitch )
void gFillRectangle( DFBRectangle *rect )
{
+ int h;
+
CHECK_PIPELINE();
Dlength = rect->w;
+ if (dst_format == DSPF_YUY2 || dst_format == DSPF_UYVY)
+ Dlength /= 2;
+
Aop_xy( dst_org, rect->x, rect->y, dst_pitch );
- while (rect->h--) {
+ h = rect->h;
+ while (h--) {
RUN_PIPELINE();
Aop_next( dst_pitch );
}
+
+ if (dst_format == DSPF_I420 || dst_format == DSPF_YV12) {
+ rect->x /= 2;
+ rect->y /= 2;
+ rect->w /= 2;
+ rect->h /= 2;
+
+ Dlength = rect->w;
+
+ Cop = CbCop;
+ Aop_xy( dst_org + dst_height * dst_pitch,
+ rect->x, rect->y, dst_pitch/2 );
+ h = rect->h;
+ while (h--) {
+ RUN_PIPELINE();
+
+ Aop_next( dst_pitch/2 );
+ }
+
+ Cop = CrCop;
+ Aop_xy( dst_org + dst_height * dst_pitch + dst_height * dst_pitch/4,
+ rect->x, rect->y, dst_pitch/2 );
+ h = rect->h;
+ while (h--) {
+ RUN_PIPELINE();
+
+ Aop_next( dst_pitch/2 );
+ }
+ }
}
void gDrawLine( DFBRegion *line )