evas - fix yuv support to no longer ignore 709 colorspace params

if yuou use 709 instead of 601 yuv (ycbcr) evas will just be wrong and
use 601. this fixes that and implements 709. it also fixes a scaling
bug for yuv in the gl engine. no one noticed but me, so i won't call
this a bug fix, and it can go into the next efl release - no need to
backport unless it actually bothers peolpe (which it seemingly doesn't)
This commit is contained in:
Carsten Haitzler 2015-05-27 20:17:20 +09:00
parent 80000e993e
commit cc49c1702b
13 changed files with 1585 additions and 102 deletions

View File

@ -1697,7 +1697,7 @@ _evas_image_pixels_import(Eo *eo_obj, Evas_Image_Data *o, Evas_Pixel_Import_Sour
o->engine_data = ENFN->image_data_get(ENDT, o->engine_data, 1, &image_pixels,&o->load_error);
if (image_pixels)
evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows, (DATA8 *) image_pixels, o->cur->image.w, o->cur->image.h);
evas_common_convert_yuv_422p_601_rgba((DATA8 **) pixels->rows, (DATA8 *) image_pixels, o->cur->image.w, o->cur->image.h);
if (o->engine_data)
o->engine_data = ENFN->image_data_put(ENDT, o->engine_data, image_pixels);
if (o->engine_data)

View File

@ -131,7 +131,7 @@ evas_common_convert_yuv_422P_601_to(void *data, int w, int h, Evas_Colorspace cs
dst = malloc(sizeof (unsigned int) * w * h);
if (!dst) return NULL;
evas_common_convert_yuv_420p_601_rgba(data, dst, w, h);
evas_common_convert_yuv_422p_601_rgba(data, dst, w, h);
return dst;
}
default:

View File

@ -16,12 +16,17 @@
#endif
static void _evas_yuv_init (void);
// Broken atm - the sse and mmx get math.. wrong :(
//static void _evas_yv12_709torgb_sse(unsigned char **yuv, unsigned char *rgb, int w, int h);
static void _evas_yv12torgb_sse (unsigned char **yuv, unsigned char *rgb, int w, int h);
// Broken atm - the sse and mmx get math.. wrong :(
//static void _evas_yv12_709torgb_mmx(unsigned char **yuv, unsigned char *rgb, int w, int h);
static void _evas_yv12torgb_mmx (unsigned char **yuv, unsigned char *rgb, int w, int h);
#ifdef BUILD_ALTIVEC
static void _evas_yv12torgb_altivec(unsigned char **yuv, unsigned char *rgb, int w, int h);
static void _evas_yv12torgb_diz (unsigned char **yuv, unsigned char *rgb, int w, int h);
#endif
static void _evas_yv12_709torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h);
static void _evas_yv12torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
static void _evas_yuy2torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
static void _evas_nv12torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
@ -31,10 +36,17 @@ static void _evas_nv12tiledtorgb_raster(unsigned char **yuv, unsigned char *rgb,
#define CBU 132251
#define CGU 25624
#define CGV 53280
#define YMUL 76283
#define OFF 32768
#define BITRES 16
#define CRV709 117504
#define CBU709 138607
#define CGU709 13959
#define CGV709 34996
/* calculation float resolution in bits */
/* ie RES = 6 is 10.6 fixed point */
/* RES = 8 is 8.8 fixed point */
@ -56,6 +68,11 @@ __attribute__ ((aligned (8))) const volatile unsigned short _const_32 [4] = F
__attribute__ ((aligned (8))) const volatile unsigned short _const_16 [4] = FOUR(16);
__attribute__ ((aligned (8))) const volatile unsigned short _const_ff [4] = FOUR(-1);
__attribute__ ((aligned (8))) const volatile unsigned short _const_crvcrv709[4] = FOUR(RZ(CRV709));
__attribute__ ((aligned (8))) const volatile unsigned short _const_cbucbu709[4] = FOUR(RZ(CBU709));
__attribute__ ((aligned (8))) const volatile unsigned short _const_cgucgu709[4] = FOUR(RZ(CGU709));
__attribute__ ((aligned (8))) const volatile unsigned short _const_cgvcgv709[4] = FOUR(RZ(CGV709));
#define CONST_CRVCRV *_const_crvcrv
#define CONST_CBUCBU *_const_cbucbu
#define CONST_CGUCGU *_const_cgucgu
@ -66,12 +83,22 @@ __attribute__ ((aligned (8))) const volatile unsigned short _const_ff [4] = F
#define CONST_16 *_const_16
#define CONST_FF *_const_ff
#define CONST_CRVCRV709 *_const_crvcrv709
#define CONST_CBUCBU709 *_const_cbucbu709
#define CONST_CGUCGU709 *_const_cgucgu709
#define CONST_CGVCGV709 *_const_cgvcgv709
/* for C non aligned cleanup */
const int _crv = RZ(CRV); /* 1.596 */
const int _cbu = RZ(CBU); /* 2.018 */
const int _cgu = RZ(CGU); /* 0.391 */
const int _cgv = RZ(CGV); /* 0.813 */
const int _crv709 = RZ(CRV709); /* 1.793 */
const int _cbu709 = RZ(CBU709); /* 2.115 */
const int _cgu709 = RZ(CGU709); /* 0.213 */
const int _cgv709 = RZ(CGV709); /* 0.534 */
#endif
#ifdef BUILD_ALTIVEC
@ -113,6 +140,11 @@ static short _v813[256];
static short _v391[256];
static short _v2018[256];
static short _v1793[256];
static short _v534[256];
static short _v213[256];
static short _v2115[256];
static unsigned char _clip_lut[1024];
#define LUT_CLIP(i) ((_clip_lut+384)[(i)])
@ -121,8 +153,26 @@ static unsigned char _clip_lut[1024];
static int initted = 0;
void
evas_common_convert_yuv_420p_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
evas_common_convert_yuv_422p_709_rgba(DATA8 **src, DATA8 *dst, int w, int h)
{
if (!initted) _evas_yuv_init();
initted = 1;
/* Broken atm - the sse and mmx get math.. wrong :(
if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2))
_evas_yv12_709torgb_sse(src, dst, w, h);
else if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
_evas_yv12_709torgb_mmx(src, dst, w, h);
else
*/
_evas_yv12_709torgb_raster(src, dst, w, h);
}
void
evas_common_convert_yuv_422p_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
{
if (!initted) _evas_yuv_init();
initted = 1;
if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2))
_evas_yv12torgb_sse(src, dst, w, h);
else if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
@ -132,12 +182,7 @@ evas_common_convert_yuv_420p_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
_evas_yv12torgb_altivec(src, dst, w, h);
#endif
else
{
if (!initted) _evas_yuv_init();
initted = 1;
/* FIXME: diz may be faster sometimes */
_evas_yv12torgb_raster(src, dst, w, h);
}
_evas_yv12torgb_raster(src, dst, w, h);
}
/* Thanks to Diz for this code. i've munged it a little and turned it into */
@ -157,6 +202,169 @@ evas_common_convert_yuv_420p_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
/* this code should be faster. In the end it's all just an mmx version of */
/* the reference implimentation done with fixed point math */
/*
static void
_evas_yv12_709torgb_sse(unsigned char **yuv, unsigned char *rgb, int w, int h)
{
#ifdef BUILD_MMX
int xx, yy;
register unsigned char *yp1, *up, *vp;
unsigned char *dp1;
dp1 = rgb;
for (yy = 0; yy < h; yy++)
{
yp1 = yuv[yy];
up = yuv[h + (yy / 2)];
vp = yuv[h + (h / 2) + (yy / 2)];
for (xx = 0; xx < (w - 807); xx += 8)
{
movd_m2r(*up, mm3);
movd_m2r(*vp, mm2);
movq_m2r(*yp1, mm0);
pxor_r2r(mm7, mm7);
punpcklbw_r2r(mm7, mm2);
punpcklbw_r2r(mm7, mm3);
movq_r2r(mm0, mm1);
psrlw_i2r(8, mm0);
psllw_i2r(8, mm1);
psrlw_i2r(8, mm1);
movq_m2r(CONST_16, mm4);
psubsw_r2r(mm4, mm0);
psubsw_r2r(mm4, mm1);
movq_m2r(CONST_128, mm5);
psubsw_r2r(mm5, mm2);
psubsw_r2r(mm5, mm3);
movq_m2r(CONST_YMUL, mm4);
pmullw_r2r(mm4, mm0);
pmullw_r2r(mm4, mm1);
movq_m2r(CONST_CRVCRV709, mm7);
pmullw_r2r(mm3, mm7);
movq_m2r(CONST_CBUCBU709, mm6);
pmullw_r2r(mm2, mm6);
movq_m2r(CONST_CGUCGU709, mm5);
pmullw_r2r(mm2, mm5);
movq_m2r(CONST_CGVCGV709, mm4);
pmullw_r2r(mm3, mm4);
movq_r2r(mm0, mm2);
paddsw_r2r(mm7, mm2);
paddsw_r2r(mm1, mm7);
psraw_i2r(RES, mm2);
psraw_i2r(RES, mm7);
packuswb_r2r(mm7, mm2);
pxor_r2r(mm7, mm7);
movq_r2r(mm2, mm3);
punpckhbw_r2r(mm7, mm2);
punpcklbw_r2r(mm3, mm7);
por_r2r(mm7, mm2);
movq_r2r(mm0, mm3);
psubsw_r2r(mm5, mm3);
psubsw_r2r(mm4, mm3);
paddsw_m2r(CONST_32, mm3);
movq_r2r(mm1, mm7);
psubsw_r2r(mm5, mm7);
psubsw_r2r(mm4, mm7);
paddsw_m2r(CONST_32, mm7);
psraw_i2r(RES, mm3);
psraw_i2r(RES, mm7);
packuswb_r2r(mm7, mm3);
pxor_r2r(mm7, mm7);
movq_r2r(mm3, mm4);
punpckhbw_r2r(mm7, mm3);
punpcklbw_r2r(mm4, mm7);
por_r2r(mm7, mm3);
movq_m2r(CONST_32, mm4);
paddsw_r2r(mm6, mm0);
paddsw_r2r(mm6, mm1);
paddsw_r2r(mm4, mm0);
paddsw_r2r(mm4, mm1);
psraw_i2r(RES, mm0);
psraw_i2r(RES, mm1);
packuswb_r2r(mm1, mm0);
pxor_r2r(mm7, mm7);
movq_r2r(mm0, mm5);
punpckhbw_r2r(mm7, mm0);
punpcklbw_r2r(mm5, mm7);
por_r2r(mm7, mm0);
movq_m2r(CONST_FF, mm1);
movq_r2r(mm0, mm5);
movq_r2r(mm3, mm6);
movq_r2r(mm2, mm7);
punpckhbw_r2r(mm3, mm2);
punpcklbw_r2r(mm6, mm7);
punpckhbw_r2r(mm1, mm0);
punpcklbw_r2r(mm1, mm5);
movq_r2r(mm7, mm1);
punpckhwd_r2r(mm5, mm7);
punpcklwd_r2r(mm5, mm1);
movq_r2r(mm2, mm4);
punpckhwd_r2r(mm0, mm2);
punpcklwd_r2r(mm0, mm4);
movntq_r2m(mm1, *(dp1));
movntq_r2m(mm7, *(dp1 + 8));
movntq_r2m(mm4, *(dp1 + 16));
movntq_r2m(mm2, *(dp1 + 24));
yp1 += 8;
up += 4;
vp += 4;
dp1 += 8 * 4;
}
if (xx < w)
{
int y, u, v, r, g, b;
for (; xx < w; xx += 2)
{
u = (*up++) - 128;
v = (*vp++) - 128;
y = RZ(YMUL) * ((*yp1++) - 16);
r = LUT_CLIP((y + (_crv709 * v)) >> RES);
g = LUT_CLIP((y - (_cgu709 * u) - (_cgv709 * v) + RZ(OFF)) >> RES);
b = LUT_CLIP((y + (_cbu709 * u) + RZ(OFF)) >> RES);
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(r,g,b);
dp1 += 4;
y = RZ(YMUL) * ((*yp1++) - 16);
r = LUT_CLIP((y + (_crv709 * v)) >> RES);
g = LUT_CLIP((y - (_cgu709 * u) - (_cgv709 * v) + RZ(OFF)) >> RES);
b = LUT_CLIP((y + (_cbu709 * u) + RZ(OFF)) >> RES);
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(r,g,b);
dp1 += 4;
}
}
}
emms();
#else
_evas_yv12_709torgb_mmx(yuv, rgb, w, h);
#endif
}
*/
static void
_evas_yv12torgb_sse(unsigned char **yuv, unsigned char *rgb, int w, int h)
{
@ -320,6 +528,168 @@ _evas_yv12torgb_sse(unsigned char **yuv, unsigned char *rgb, int w, int h)
#endif
}
/*
static void
_evas_yv12_709torgb_mmx(unsigned char **yuv, unsigned char *rgb, int w, int h)
{
#ifdef BUILD_MMX
int xx, yy;
register unsigned char *yp1, *up, *vp;
unsigned char *dp1;
dp1 = rgb;
for (yy = 0; yy < h; yy++)
{
yp1 = yuv[yy];
up = yuv[h + (yy / 2)];
vp = yuv[h + (h / 2) + (yy / 2)];
for (xx = 0; xx < (w - 7); xx += 8)
{
movd_m2r(*up, mm3);
movd_m2r(*vp, mm2);
movq_m2r(*yp1, mm0);
pxor_r2r(mm7, mm7);
punpcklbw_r2r(mm7, mm2);
punpcklbw_r2r(mm7, mm3);
movq_r2r(mm0, mm1);
psrlw_i2r(8, mm0);
psllw_i2r(8, mm1);
psrlw_i2r(8, mm1);
movq_m2r(CONST_16, mm4);
psubsw_r2r(mm4, mm0);
psubsw_r2r(mm4, mm1);
movq_m2r(CONST_128, mm5);
psubsw_r2r(mm5, mm2);
psubsw_r2r(mm5, mm3);
movq_m2r(CONST_YMUL, mm4);
pmullw_r2r(mm4, mm0);
pmullw_r2r(mm4, mm1);
movq_m2r(CONST_CRVCRV709, mm7);
pmullw_r2r(mm3, mm7);
movq_m2r(CONST_CBUCBU709, mm6);
pmullw_r2r(mm2, mm6);
movq_m2r(CONST_CGUCGU709, mm5);
pmullw_r2r(mm2, mm5);
movq_m2r(CONST_CGVCGV709, mm4);
pmullw_r2r(mm3, mm4);
movq_r2r(mm0, mm2);
paddsw_r2r(mm7, mm2);
paddsw_r2r(mm1, mm7);
psraw_i2r(RES, mm2);
psraw_i2r(RES, mm7);
packuswb_r2r(mm7, mm2);
pxor_r2r(mm7, mm7);
movq_r2r(mm2, mm3);
punpckhbw_r2r(mm7, mm2);
punpcklbw_r2r(mm3, mm7);
por_r2r(mm7, mm2);
movq_r2r(mm0, mm3);
psubsw_r2r(mm5, mm3);
psubsw_r2r(mm4, mm3);
paddsw_m2r(CONST_32, mm3);
movq_r2r(mm1, mm7);
psubsw_r2r(mm5, mm7);
psubsw_r2r(mm4, mm7);
paddsw_m2r(CONST_32, mm7);
psraw_i2r(RES, mm3);
psraw_i2r(RES, mm7);
packuswb_r2r(mm7, mm3);
pxor_r2r(mm7, mm7);
movq_r2r(mm3, mm4);
punpckhbw_r2r(mm7, mm3);
punpcklbw_r2r(mm4, mm7);
por_r2r(mm7, mm3);
movq_m2r(CONST_32, mm4);
paddsw_r2r(mm6, mm0);
paddsw_r2r(mm6, mm1);
paddsw_r2r(mm4, mm0);
paddsw_r2r(mm4, mm1);
psraw_i2r(RES, mm0);
psraw_i2r(RES, mm1);
packuswb_r2r(mm1, mm0);
pxor_r2r(mm7, mm7);
movq_r2r(mm0, mm5);
punpckhbw_r2r(mm7, mm0);
punpcklbw_r2r(mm5, mm7);
por_r2r(mm7, mm0);
movq_m2r(CONST_FF, mm1);
movq_r2r(mm0, mm5);
movq_r2r(mm3, mm6);
movq_r2r(mm2, mm7);
punpckhbw_r2r(mm3, mm2);
punpcklbw_r2r(mm6, mm7);
punpckhbw_r2r(mm1, mm0);
punpcklbw_r2r(mm1, mm5);
movq_r2r(mm7, mm1);
punpckhwd_r2r(mm5, mm7);
punpcklwd_r2r(mm5, mm1);
movq_r2r(mm2, mm4);
punpckhwd_r2r(mm0, mm2);
punpcklwd_r2r(mm0, mm4);
movq_r2m(mm1, *(dp1));
movq_r2m(mm7, *(dp1 + 8));
movq_r2m(mm4, *(dp1 + 16));
movq_r2m(mm2, *(dp1 + 24));
yp1 += 8;
up += 4;
vp += 4;
dp1 += 8 * 4;
}
if (xx < w)
{
int y, u, v, r, g, b;
for (; xx < w; xx += 2)
{
u = (*up++) - 128;
v = (*vp++) - 128;
y = RZ(YMUL) * ((*yp1++) - 16);
r = LUT_CLIP((y + (_crv709 * v)) >> RES);
g = LUT_CLIP((y - (_cgu709 * u) - (_cgv709 * v) + RZ(OFF)) >> RES);
b = LUT_CLIP((y + (_cbu709 * u) + RZ(OFF)) >> RES);
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(r,g,b);
dp1 += 4;
y = RZ(YMUL) * ((*yp1++) - 16);
r = LUT_CLIP((y + (_crv709 * v)) >> RES);
g = LUT_CLIP((y - (_cgu709 * u) - (_cgv709 * v) + RZ(OFF)) >> RES);
b = LUT_CLIP((y + (_cbu709 * u) + RZ(OFF)) >> RES);
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(r,g,b);
dp1 += 4;
}
}
}
emms();
#else
_evas_yv12torgb_raster(yuv, rgb, w, h);
#endif
}
*/
static void
_evas_yv12torgb_mmx(unsigned char **yuv, unsigned char *rgb, int w, int h)
{
@ -715,6 +1085,12 @@ _evas_yuv_init(void)
_v391[i] = (int)(((float)(i - 128)) * 0.391);
_v2018[i] = (int)(((float)(i - 128)) * 2.018);
//////////////////////////////////////////////////////////////////////////
_v1793[i] = (int)(((float)(i - 128)) * 1.793);
_v534[i] = (int)(((float)(i - 128)) * 0.534);
_v213[i] = (int)(((float)(i - 128)) * 0.213);
_v2115[i] = (int)(((float)(i - 128)) * 2.115);
}
for (i = -384; i < 640; i++)
@ -800,6 +1176,70 @@ _evas_yv12torgb_diz(unsigned char **yuv, unsigned char *rgb, int w, int h)
}
#endif
static void
_evas_yv12_709torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
{
int xx, yy;
int y, u, v;
unsigned char *yp1, *yp2, *up, *vp;
unsigned char *dp1, *dp2;
/* destination pointers */
dp1 = rgb;
dp2 = rgb + (w * 4);
for (yy = 0; yy < h; yy += 2)
{
/* plane pointers */
yp1 = yuv[yy];
yp2 = yuv[yy + 1];
up = yuv[h + (yy / 2)];
vp = yuv[h + (h / 2) + (yy / 2)];
for (xx = 0; xx < w; xx += 2)
{
int vmu;
/* collect u & v for 2x2 pixel block */
u = *up++;
v = *vp++;
/* save lookups */
vmu = _v534[v] + _v213[u];
u = _v2115[u];
v = _v1793[v];
/* do the top 2 pixels of the 2x2 block which shared u & v */
/* yuv to rgb */
y = _v1164[*yp1++];
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
dp1 += 4;
/* yuv to rgb */
y = _v1164[*yp1++];
*((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
dp1 += 4;
/* do the bottom 2 pixels */
/* yuv to rgb */
y = _v1164[*yp2++];
*((DATA32 *) dp2) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
dp2 += 4;
/* yuv to rgb */
y = _v1164[*yp2++];
*((DATA32 *) dp2) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
dp2 += 4;
}
/* jump down one line since we are doing 2 at once */
dp1 += (w * 4);
dp2 += (w * 4);
}
}
static void
_evas_yv12torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
{

View File

@ -1,7 +1,9 @@
#ifndef _EVAS_CONVERT_YUV_H
#define _EVAS_CONVERT_YUV_H
EAPI void evas_common_convert_yuv_420p_601_rgba (DATA8 **src, DATA8 *dst, int w, int h);
EAPI void evas_common_convert_yuv_422p_709_rgba (DATA8 **src, DATA8 *dst, int w, int h);
EAPI void evas_common_convert_yuv_422p_601_rgba (DATA8 **src, DATA8 *dst, int w, int h);
EAPI void evas_common_convert_yuv_422_601_rgba (DATA8 **src, DATA8 *dst, int w, int h);
EAPI void evas_common_convert_yuv_420_601_rgba (DATA8 **src, DATA8 *dst, int w, int h);
EAPI void evas_common_convert_yuv_420T_601_rgba (DATA8 **src, DATA8 *dst, int w, int h);

View File

@ -794,13 +794,13 @@ evas_common_image_colorspace_normalize(RGBA_Image *im)
case EVAS_COLORSPACE_ARGB8888:
case EVAS_COLORSPACE_GRY8:
case EVAS_COLORSPACE_AGRY88:
if (im->image.data != im->cs.data)
{
if (im->image.data != im->cs.data)
{
#ifdef EVAS_CSERVE2
// if (((Image_Entry *)im)->data1) evas_cserve2_image_free(&im->cache_entry);
if (((Image_Entry *)im)->data1) ERR("Shouldn't reach this point since we are using cache2.");
#endif
if (!im->image.no_free)
if (!im->image.no_free)
{
_evas_common_rgba_image_surface_munmap(im->image.data,
im->cache_entry.allocated.w,
@ -808,19 +808,19 @@ evas_common_image_colorspace_normalize(RGBA_Image *im)
im->cache_entry.space);
#ifdef SURFDBG
surfs = eina_list_remove(surfs, im);
#endif
#endif
((Image_Entry *)im)->allocated.w = 0;
((Image_Entry *)im)->allocated.h = 0;
}
im->image.data = im->cs.data;
im->cs.no_free = im->image.no_free;
}
break;
im->image.data = im->cs.data;
im->cs.no_free = im->image.no_free;
}
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
evas_common_convert_yuv_420p_601_rgba(im->cs.data, (DATA8*) im->image.data,
im->cache_entry.w, im->cache_entry.h);
break;
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
evas_common_convert_yuv_422p_601_rgba(im->cs.data, (DATA8*) im->image.data,
im->cache_entry.w, im->cache_entry.h);
break;
case EVAS_COLORSPACE_YCBCR422601_PL:
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
evas_common_convert_yuv_422_601_rgba(im->cs.data, (DATA8*) im->image.data,
@ -836,13 +836,18 @@ evas_common_image_colorspace_normalize(RGBA_Image *im)
evas_common_convert_yuv_420T_601_rgba(im->cs.data, (DATA8*) im->image.data,
im->cache_entry.w, im->cache_entry.h);
break;
case EMILE_COLORSPACE_YCBCR422P709_PL:
if ((im->image.data) && (*((unsigned char **)im->cs.data)))
evas_common_convert_yuv_422p_709_rgba(im->cs.data, (DATA8*) im->image.data,
im->cache_entry.w, im->cache_entry.h);
break;
default:
break;
break;
}
im->cs.dirty = 0;
#ifdef SURFDBG
surf_debug();
#endif
#endif
}
EAPI void

View File

@ -465,6 +465,9 @@ enum _Shader_Type {
SHD_YUV,
SHD_YUY2,
SHD_NV12,
SHD_YUV_709,
SHD_YUY2_709,
SHD_NV12_709,
SHD_LINE,
SHD_RGB_A_PAIR,
SHD_TEX_EXTERNAL,
@ -792,6 +795,13 @@ void evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_yuv_709_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,

View File

@ -1548,11 +1548,13 @@ evas_gl_common_shader_select(Evas_Engine_GL_Context *gc,
{
if (tex->pt->dyn.img)
{
printf("a... %i\n", (int)tex->alpha);
afill = !tex->alpha;
bgra = 1;
}
else if (tex->im && tex->im->native.target == GL_TEXTURE_EXTERNAL_OES)
{
printf("b... %i\n", (int)tex->alpha);
type = SHD_TEX_EXTERNAL;
afill = !tex->alpha;
}
@ -1571,6 +1573,9 @@ evas_gl_common_shader_select(Evas_Engine_GL_Context *gc,
SHADER_YUV_NOMUL, SHADER_YUV, SHADER_YUV_MASK_NOMUL, SHADER_YUV_MASK,
SHADER_YUY2_NOMUL, SHADER_YUY2, SHADER_YUY2_MASK_NOMUL, SHADER_YUY2_MASK,
SHADER_NV12_NOMUL, SHADER_NV12, SHADER_NV12_MASK_NOMUL, SHADER_NV12_MASK,
SHADER_YUV_709_NOMUL, SHADER_YUV_709, SHADER_YUV_709_MASK_NOMUL, SHADER_YUV_709_MASK,
SHADER_YUY2_709_NOMUL, SHADER_YUY2_709, SHADER_YUY2_709_MASK_NOMUL, SHADER_YUY2_709_MASK,
SHADER_NV12_709_NOMUL, SHADER_NV12_709, SHADER_NV12_709_MASK_NOMUL, SHADER_NV12_709_MASK,
// RGB+A could support extra sampling
SHADER_RGB_A_PAIR_NOMUL, SHADER_RGB_A_PAIR, SHADER_RGB_A_PAIR_MASK_NOMUL, SHADER_RGB_A_PAIR_MASK,
// TEX_EXTERNAL could support extra sampling
@ -1584,8 +1589,11 @@ evas_gl_common_shader_select(Evas_Engine_GL_Context *gc,
case SHD_YUV: k = 0; break;
case SHD_YUY2: k = 4; break;
case SHD_NV12: k = 8; break;
case SHD_RGB_A_PAIR: k = 12; break;
case SHD_TEX_EXTERNAL: k = 16; break;
case SHD_YUV_709: k = 12; break;
case SHD_YUY2_709: k = 16; break;
case SHD_NV12_709: k = 20; break;
case SHD_RGB_A_PAIR: k = 24; break;
case SHD_TEX_EXTERNAL: k = 28; break;
default:
CRI("Unknown shader type requested!");
return SHADER_RECT;
@ -2343,10 +2351,89 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
tx2 = (sx + sw) / (double)tex->pt->w;
ty2 = (sy + sh) / (double)tex->pt->h;
t2x1 = ((sx) / 2) / (double)tex->ptu->w;
t2y1 = ((sy) / 2) / (double)tex->ptu->h;
t2x2 = ((sx + sw) / 2) / (double)tex->ptu->w;
t2y2 = ((sy + sh) / 2) / (double)tex->ptu->h;
t2x1 = ((sx) / 2.0) / (double)tex->ptu->w;
t2y1 = ((sy) / 2.0) / (double)tex->ptu->h;
t2x2 = ((sx + sw) / 2.0) / (double)tex->ptu->w;
t2y2 = ((sy + sh) / 2.0) / (double)tex->ptu->h;
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV2(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_6_TEXUV3(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
if (!nomul)
PUSH_6_COLORS(pn, r, g, b, a);
}
void
evas_gl_common_context_yuv_709_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth)
{
GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
Eina_Bool blend = 0;
Evas_GL_Shader shader;
GLuint prog;
int pn = 0, nomul = 0;
if ((a < 255) || (!!mtex))
blend = 1;
shader = evas_gl_common_shader_select(gc, SHD_YUV_709, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, 0, mtex,
NULL, &nomul);
prog = gc->shared->shader[shader].prog;
pn = _evas_gl_common_context_push(SHD_YUV_709,
gc, tex, mtex,
prog,
x, y, w, h,
blend,
smooth,
0, 0, 0, 0, 0,
mask_smooth);
gc->pipe[pn].region.type = SHD_YUV_709;
gc->pipe[pn].shader.id = shader;
gc->pipe[pn].shader.cur_tex = tex->pt->texture;
gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
gc->pipe[pn].shader.cur_texm = mtex ? mtex->pt->texture : 0;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
gc->pipe[pn].shader.mask_smooth = mask_smooth;
gc->pipe[pn].shader.clip = 0;
gc->pipe[pn].shader.cx = 0;
gc->pipe[pn].shader.cy = 0;
gc->pipe[pn].shader.cw = 0;
gc->pipe[pn].shader.ch = 0;
gc->pipe[pn].array.line = 0;
gc->pipe[pn].array.use_vertex = 1;
gc->pipe[pn].array.use_color = !nomul;
gc->pipe[pn].array.use_texuv = 1;
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 1;
gc->pipe[pn].array.use_mask = !!mtex;
gc->pipe[pn].array.use_texsam = 0;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
tx1 = (sx) / (double)tex->pt->w;
ty1 = (sy) / (double)tex->pt->h;
tx2 = (sx + sw) / (double)tex->pt->w;
ty2 = (sy + sh) / (double)tex->pt->h;
t2x1 = ((sx) / 2.0) / (double)tex->ptu->w;
t2y1 = ((sy) / 2.0) / (double)tex->ptu->h;
t2x2 = ((sx + sw) / 2.0) / (double)tex->ptu->w;
t2y2 = ((sy + sh) / 2.0) / (double)tex->ptu->h;
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
@ -2643,10 +2730,13 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
switch (cspace)
{
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
type = SHD_YUV;
utexture = EINA_TRUE;
break;
case EVAS_COLORSPACE_YCBCR422P709_PL:
type = SHD_YUV_709;
utexture = EINA_TRUE;
break;
case EVAS_COLORSPACE_YCBCR422601_PL:
type = SHD_YUY2;
uvtexture = EINA_TRUE;

View File

@ -791,7 +791,7 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
free(im->im->image.data);
im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32));
if (im->im->image.data)
evas_common_convert_yuv_420p_601_rgba(im->cs.data,
evas_common_convert_yuv_422p_601_rgba(im->cs.data,
(void *)im->im->image.data,
im->im->cache_entry.w, im->im->cache_entry.h);
}
@ -992,7 +992,8 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int r, int g, int b, int a,
Evas_GL_Image *mask,
Eina_Bool smooth,
Eina_Bool yuv, Eina_Bool yuy2, Eina_Bool nv12,
Eina_Bool yuv, Eina_Bool yuv_709,
Eina_Bool yuy2, Eina_Bool nv12,
Eina_Bool rgb_a_pair)
{
int mx = 0, my = 0, mw = 0, mh = 0;
@ -1033,6 +1034,14 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (yuv_709)
evas_gl_common_context_yuv_709_push(gc,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (yuy2)
evas_gl_common_context_yuy2_push(gc,
im->tex,
@ -1081,6 +1090,14 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (yuv_709)
evas_gl_common_context_yuv_709_push(gc,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (yuy2)
evas_gl_common_context_yuy2_push(gc,
im->tex,
@ -1124,6 +1141,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
int c, cx, cy, cw, ch;
int i;
Eina_Bool yuv = EINA_FALSE;
Eina_Bool yuv_709 = EINA_FALSE;
Eina_Bool yuy2 = EINA_FALSE;
Eina_Bool nv12 = EINA_FALSE;
Eina_Bool rgb_a_pair = EINA_FALSE;
@ -1156,9 +1174,11 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
switch (im->cs.space)
{
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
yuv = EINA_TRUE;
break;
case EVAS_COLORSPACE_YCBCR422P709_PL:
yuv_709 = EINA_TRUE;
break;
case EVAS_COLORSPACE_YCBCR422601_PL:
yuy2 = EINA_TRUE;
break;
@ -1189,7 +1209,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
r, g, b, a,
mask,
smooth,
yuv, yuy2, nv12, rgb_a_pair);
yuv, yuv_709, yuy2, nv12, rgb_a_pair);
}
else
{
@ -1200,7 +1220,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
r, g, b, a,
mask,
smooth,
yuv, yuy2, nv12, rgb_a_pair);
yuv, yuv_709, yuy2, nv12, rgb_a_pair);
}
return;
}
@ -1227,7 +1247,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
r, g, b, a,
mask,
smooth,
yuv, yuy2, nv12, rgb_a_pair);
yuv, yuv_709, yuy2, nv12, rgb_a_pair);
}
evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);
/* restore clip info */

View File

@ -1684,7 +1684,7 @@ evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigne
tex = evas_gl_common_texture_alloc(gc, w, h, EINA_FALSE);
if (!tex) return NULL;
tex->ptu = _pool_tex_new(gc, w / 2 + 1, h / 2 + 1, lum_ifmt, lum_fmt);
tex->ptu = _pool_tex_new(gc, (w + 1) / 2, (h + 1) / 2, lum_ifmt, lum_fmt);
if (!tex->ptu)
{
evas_gl_common_texture_light_free(tex);

View File

@ -76,6 +76,18 @@ typedef enum {
SHADER_NV12_NOMUL,
SHADER_NV12_MASK,
SHADER_NV12_MASK_NOMUL,
SHADER_YUV_709,
SHADER_YUV_709_NOMUL,
SHADER_YUV_709_MASK,
SHADER_YUV_709_MASK_NOMUL,
SHADER_YUY2_709,
SHADER_YUY2_709_NOMUL,
SHADER_YUY2_709_MASK,
SHADER_YUY2_709_MASK_NOMUL,
SHADER_NV12_709,
SHADER_NV12_709_NOMUL,
SHADER_NV12_709_MASK,
SHADER_NV12_709_MASK_NOMUL,
SHADER_LAST
} Evas_GL_Shader;
@ -163,6 +175,40 @@ static struct {
{ SHADER_NV12_MASK_NOMUL, "tex" },
{ SHADER_NV12_MASK_NOMUL, "texuv" },
{ SHADER_NV12_MASK_NOMUL, "texm" },
{ SHADER_YUV_709, "tex" },
{ SHADER_YUV_709, "texu" },
{ SHADER_YUV_709, "texv" },
{ SHADER_YUV_709_NOMUL, "tex" },
{ SHADER_YUV_709_NOMUL, "texu" },
{ SHADER_YUV_709_NOMUL, "texv" },
{ SHADER_YUV_709_MASK, "tex" },
{ SHADER_YUV_709_MASK, "texu" },
{ SHADER_YUV_709_MASK, "texv" },
{ SHADER_YUV_709_MASK, "texm" },
{ SHADER_YUV_709_MASK_NOMUL, "tex" },
{ SHADER_YUV_709_MASK_NOMUL, "texu" },
{ SHADER_YUV_709_MASK_NOMUL, "texv" },
{ SHADER_YUV_709_MASK_NOMUL, "texm" },
{ SHADER_YUY2_709, "tex" },
{ SHADER_YUY2_709, "texuv" },
{ SHADER_YUY2_709_NOMUL, "tex" },
{ SHADER_YUY2_709_NOMUL, "texuv" },
{ SHADER_YUY2_709_MASK, "tex" },
{ SHADER_YUY2_709_MASK, "texuv" },
{ SHADER_YUY2_709_MASK, "texm" },
{ SHADER_YUY2_709_MASK_NOMUL, "tex" },
{ SHADER_YUY2_709_MASK_NOMUL, "texuv" },
{ SHADER_YUY2_709_MASK_NOMUL, "texm" },
{ SHADER_NV12_709, "tex" },
{ SHADER_NV12_709, "texuv" },
{ SHADER_NV12_709_NOMUL, "tex" },
{ SHADER_NV12_709_NOMUL, "texuv" },
{ SHADER_NV12_709_MASK, "tex" },
{ SHADER_NV12_709_MASK, "texuv" },
{ SHADER_NV12_709_MASK, "texm" },
{ SHADER_NV12_709_MASK_NOMUL, "tex" },
{ SHADER_NV12_709_MASK_NOMUL, "texuv" },
{ SHADER_NV12_709_MASK_NOMUL, "texm" },
{ SHADER_LAST, NULL }
};

File diff suppressed because it is too large Load Diff

View File

@ -69,32 +69,35 @@ void main()
{
vec4 c;
#if defined(SHD_YUV)
float r, g, b, y, u, v;
#if defined(SHD_YUV) || defined(SHD_NV12) || defined(SHD_YUY2)
float r, g, b, y, u, v, vmu;
# if defined(SHD_YUV)
y = texture2D(tex, tex_c).r;
u = texture2D(texu, tex_c2).r;
v = texture2D(texv, tex_c3).r;
y = (y - 0.0625) * 1.164;
u = u - 0.5;
v = v - 0.5;
r = y + (1.402 * v);
g = y - (0.34414 * u) - (0.71414 * v);
b = y + (1.772 * u);
c = vec4(r, g, b, 1.0);
#elif defined(SHD_NV12) || defined(SHD_YUY2)
float y, u, v, vmu, r, g, b;
# elif defined(SHD_NV12) || defined(SHD_YUY2)
y = texture2D(tex, tex_c).g;
u = texture2D(texuv, tex_c2).g;
v = texture2D(texuv, tex_c2).a;
# endif
// center u and v around 0 for uv and y (with 128/255 for u + v, 16/255 for y)
u = u - 0.5;
v = v - 0.5;
vmu = v * 0.813 + u * 0.391;
u = u * 2.018;
v = v * 1.596;
# ifdef SHD_NV12
# if defined (SHD_YUV_709)
// 709 yuv colorspace for hd content
y = (y - 0.062) * 1.164;
vmu = (v * 0.534) + (u * 0.213);
v = v * 1.793;
u = u * 2.115;
# else
// 601 colorspace constants (older yuv content)
y = (y - 0.062) * 1.164;
vmu = (v * 0.813) + (u * 0.391);
v = v * 1.596;
u = u * 2.018;
# endif
// common yuv
r = y + v;
g = y - vmu;
b = y + u;

View File

@ -111,3 +111,18 @@ nv12_nomul:tex,nv12,nomul
nv12_mask:tex,nv12,mask
nv12_mask_nomul:tex,nv12,mask,nomul
yuv_709:tex,yuv,yuv_709
yuv_709_nomul:tex,yuv,yuv_709,nomul
yuv_709_mask:tex,yuv,yuv_709,mask
yuv_709_mask_nomul:tex,yuv,yuv_709,mask,nomul
yuy2_709:tex,yuy2,yuv_709
yuy2_709_nomul:tex,yuy2,yuv_709,nomul
yuy2_709_mask:tex,yuy2,yuv_709,mask
yuy2_709_mask_nomul:tex,yuy2,yuv_709,mask,nomul
nv12_709:tex,nv12,yuv_709
nv12_709_nomul:tex,nv12,yuv_709,nomul
nv12_709_mask:tex,nv12,yuv_709,mask
nv12_709_mask_nomul:tex,nv12,yuv_709,mask,nomul