Commit f7217115 authored by Sam Hocevar's avatar Sam Hocevar
Browse files

. suite de l'output 8 bits couleur/n&b

 . correction d'un bug dans la g�n�ration de la palette optimale
 . YUV avec dithering mortel qui tue

todo:
 . x11 (�a ne marche qu'en framebuffer pour le moment)
 . mettre la g�n�ration de palette dans video_yuv
 . refaire marcher l'output framebuffer pour bpp!=8
parent 4351c7ef
......@@ -125,7 +125,7 @@ typedef struct vout_thread_s
u32 i_blue_pixel; /* blue */
/* Palette */
u8 lookup[1377]; /* lookup table for 8 bpp palette */
u8 lookup[2176]; /* lookup table for 8 bpp palette */
/* Pictures and rendering properties */
boolean_t b_grayscale; /* color or grayscale display */
......
......@@ -31,8 +31,15 @@
#include "intf_msg.h"
#include "main.h"
#define RGB_MIN -24
#define RGB_MAX 283
//#define RGB_MIN 0
//#define RGB_MAX 255
#define RGB_MIN 0
#define RGB_MAX 255
#define SHIFT 20
#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
/******************************************************************************
* vout_sys_t: video output framebuffer method descriptor
......@@ -224,7 +231,7 @@ static int FBOpenDisplay( vout_thread_t *p_vout )
/* initializes black & white palette */
//FBInitBWPalette( p_vout );
FBInitRGBPalette( p_vout );
FBInitRGBPalette( p_vout );
p_vout->i_bytes_per_pixel = 1;
p_vout->i_bytes_per_line = p_vout->i_width;
......@@ -299,54 +306,91 @@ static void FBCloseDisplay( vout_thread_t *p_vout )
*****************************************************************************/
static void FBInitRGBPalette( vout_thread_t *p_vout )
{
#define SATURATE( x ) \
x = x + ( x >> 3 ) - 16; \
if( x < 0 ) x = 0; \
if( x > 255 ) x = 255;
int y,u,v;
float r,g,b;
int r,g,b;
int uvRed, uvGreen, uvBlue;
unsigned int counter = 0;
unsigned int allocated = 0;
unsigned int lastallocated = 0;
unsigned short red[256], green[256], blue[256], transp[256];
unsigned char extralookup[2176];
struct fb_cmap cmap = { 0, 256, red, green, blue, transp };
for ( y = 0; y <= 256; y += 16 )
for ( u = -256; u <= 256; u += 64 )
for ( v = -256; v <= 256; v += 64 )
{
r = (0.99 * y + 1.0 * u - 0.01 * v);
g = (1.005085 * y - 0.508475 * u - 0.181356 * v);
b = (1.0 * y + 1.0 * v);
if( r > RGB_MIN && g > RGB_MIN && b > RGB_MIN
&& r < RGB_MAX && g < RGB_MAX && b < RGB_MAX )
for ( u = 0; u <= 256; u += 32 )
for ( v = 0; v <= 256; v += 32 )
{
if(allocated == 256) { fprintf(stderr, "sorry, no colors left\n"); exit(1); }
if(r<0) r=0;
if(g<0) g=0;
if(b<0) b=0;
if(r>255) r=255;
if(g>255) g=255;
if(b>255) b=255;
red[allocated] = (int)r << 8;
green[allocated] = (int)g << 8;
blue[allocated] = (int)b << 8;
transp[allocated] = 0;
u += 256;
v += 256;
//printf("%x (%i:%i:%i) %i %i %i\n", (y>>4)*81 + (u>>6)*9 + (v>>6), y>>4, u>>6, v>>6, (int)r, (int)g, (int)b);
//printf("%i %i\n", counter, (y>>4)*81 + (u>>6)*9 + (v>>6) );
u -= 256;
v -= 256;
/* allocate color */
p_vout->lookup[counter] = allocated;
allocated++;
/* set last allocated index */
lastallocated = allocated - 1;
uvRed = (V_RED_COEF*(v-128)) >> SHIFT;
uvGreen = (U_GREEN_COEF*(u-128) + V_GREEN_COEF*(v-128)) >> SHIFT;
uvBlue = (U_BLUE_COEF*(u-128)) >> SHIFT;
r = y + uvRed;
g = y + uvGreen;
b = y + uvBlue;
if( r >= RGB_MIN && g >= RGB_MIN && b >= RGB_MIN
&& r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX )
{
if(allocated == 256) { fprintf(stderr, "sorry, no colors left\n"); exit(1); }
/* saturate the colors */
SATURATE( r );
SATURATE( g );
SATURATE( b );
red[allocated] = r << 8;
green[allocated] = g << 8;
blue[allocated] = b << 8;
transp[allocated] = 0;
/* allocate color */
extralookup[counter] = 1;
p_vout->lookup[counter++] = allocated;
allocated++;
}
else
{
extralookup[counter] = 0;
p_vout->lookup[counter++] = 0;
}
}
else p_vout->lookup[counter] = lastallocated;
counter += 128-81;
}
counter++;
counter = 0;
for ( y = 0; y <= 256; y += 16 )
{
for ( u = 0; u <= 256; u += 32 )
for ( v = 0; v <= 256; v += 32 )
{
int y2, u2, v2;
int dist = 100000000;
if( p_vout->lookup[counter] || y==0)
{
counter++;
continue;
}
for( y2 = y-16; y2 <= y; y2+= 16 )
for( u2 = 0; u2 <= 256; u2 += 32 )
for( v2 = 0; v2 <= 256; v2 += 32 )
{
if( extralookup[((y2>>4)<<7) + (u2>>5)*9 + (v2>>5)])
/* find the nearest color */
if( 128*(y-y2) + (u-u2)*(u-u2) + (v-v2)*(v-v2) < dist )
{
p_vout->lookup[counter] = p_vout->lookup[((y2>>4)<<7) + (u2>>5)*9 + (v2>>5)];
dist = 128*(y-y2) + (u-u2)*(u-u2) + (v-v2)*(v-v2);
}
}
counter++;
}
counter += 128-81;
}
ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap );
......@@ -369,3 +413,4 @@ static void FBInitBWPalette( vout_thread_t *p_vout )
ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap );
}
......@@ -163,10 +163,67 @@ static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data
i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
CONVERT_Y_PIXEL( BPP ) \
/*****************************************************************************
* CONVERT_4YUV_PIXELS, CONVERT_4YUV_PIXELS_SCALE: dither 4 pixels in 8 bpp
*****************************************************************************
* These macros dither 4 pixels in 8 bpp, with or without horiz. scaling
*****************************************************************************/
#define CONVERT_4YUV_PIXELS( CHROMA ) \
*p_pic++ = p_vout->lookup[ \
(((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither20[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither20[i_real_y]) >> 5) ]; \
*p_pic++ = p_vout->lookup[ \
(((*p_y++ + dither11[i_real_y]) >> 4) << 7) \
+ ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \
+ ((*p_v++ + dither21[i_real_y]) >> 5) ]; \
*p_pic++ = p_vout->lookup[ \
(((*p_y++ + dither12[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither22[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither22[i_real_y]) >> 5) ]; \
*p_pic++ = p_vout->lookup[ \
(((*p_y++ + dither13[i_real_y]) >> 4) << 7) \
+ ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \
+ ((*p_v++ + dither23[i_real_y]) >> 5) ]; \
#define CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
*p_pic++ = p_vout->lookup[ \
(((*p_y + dither10[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither20[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither20[i_real_y]) >> 5) ]; \
i_jump_uv = (i_jump_uv + *p_offset) & 0x1; \
p_y += *p_offset; \
p_u += *p_offset & i_jump_uv; \
p_v += *p_offset++ & i_jump_uv; \
*p_pic++ = p_vout->lookup[ \
(((*p_y + dither11[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither21[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither21[i_real_y]) >> 5) ]; \
i_jump_uv = (i_jump_uv + *p_offset) & 0x1; \
p_y += *p_offset; \
p_u += *p_offset & i_jump_uv; \
p_v += *p_offset++ & i_jump_uv; \
*p_pic++ = p_vout->lookup[ \
(((*p_y + dither12[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither22[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither22[i_real_y]) >> 5) ]; \
i_jump_uv = (i_jump_uv + *p_offset) & 0x1; \
p_y += *p_offset; \
p_u += *p_offset & i_jump_uv; \
p_v += *p_offset++ & i_jump_uv; \
*p_pic++ = p_vout->lookup[ \
(((*p_y + dither13[i_real_y]) >> 4) << 7) \
+ ((*p_u + dither23[i_real_y]) >> 5) * 9 \
+ ((*p_v + dither23[i_real_y]) >> 5) ]; \
i_jump_uv = (i_jump_uv + *p_offset) & 0x1; \
p_y += *p_offset; \
p_u += *p_offset & i_jump_uv; \
p_v += *p_offset++ & i_jump_uv; \
/*****************************************************************************
* SCALE_WIDTH: scale a line horizontally
*****************************************************************************
* This macro scale a line using rendering buffer and offset array. It works
* This macro scales a line using rendering buffer and offset array. It works
* for 1, 2 and 4 Bpp.
*****************************************************************************/
#define SCALE_WIDTH \
......@@ -204,11 +261,45 @@ static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data
p_pic += i_pic_width + i_pic_line_width; \
} \
/*****************************************************************************
* SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
*****************************************************************************
* This macro scales a line using an offset array.
*****************************************************************************/
#define SCALE_WIDTH_DITHER( CHROMA ) \
if( b_horizontal_scaling ) \
{ \
/* Horizontal scaling, but we can't use a buffer due to dither */ \
p_offset = p_offset_start; \
i_jump_uv = 0; \
for( i_x = i_pic_width / 16; i_x--; ) \
{ \
CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
} \
} \
else \
{ \
for( i_x = i_width / 16; i_x--; ) \
{ \
CONVERT_4YUV_PIXELS( CHROMA ) \
CONVERT_4YUV_PIXELS( CHROMA ) \
CONVERT_4YUV_PIXELS( CHROMA ) \
CONVERT_4YUV_PIXELS( CHROMA ) \
} \
} \
/* Increment of picture pointer to end of line is still needed */ \
p_pic += i_pic_line_width; \
i_real_y = (i_real_y + 1) & 0x3; \
/*****************************************************************************
* SCALE_HEIGHT: handle vertical scaling
*****************************************************************************
* This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
* 444 for RGB conversion, or 400 for gray convertion. It works for 1, 2, 3
* 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
* and 4 Bpp.
*****************************************************************************/
#define SCALE_HEIGHT( CHROMA, BPP ) \
......@@ -278,6 +369,63 @@ static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data
break; \
} \
/*****************************************************************************
* SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
*****************************************************************************
* This macro handles vertical scaling for a picture. CHROMA may be 420, 422 or
* 444 for RGB conversion, or 400 for gray conversion.
*****************************************************************************/
#define SCALE_HEIGHT_DITHER( CHROMA ) \
\
/* If line is odd, rewind 4:2:0 U and V samples */ \
if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
{ \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
} \
\
/* \
* Handle vertical scaling. The current line can be copied or next one \
* can be ignored. \
*/ \
\
switch( i_vertical_scaling ) \
{ \
case -1: /* vertical scaling factor is < 1 */ \
while( (i_scale_count -= i_pic_height) >= 0 ) \
{ \
/* Height reduction: skip next source line */ \
p_y += i_width; \
i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \
{ \
if( i_y & 0x1 ) \
{ \
p_u += i_chroma_width; \
p_v += i_chroma_width; \
} \
} \
else if( CHROMA == 444 ) \
{ \
p_u += i_width; \
p_v += i_width; \
} \
} \
i_scale_count += i_height; \
break; \
case 1: /* vertical scaling factor is > 1 */ \
while( (i_scale_count -= i_height) > 0 ) \
{ \
SCALE_WIDTH_DITHER( CHROMA ); \
p_y -= i_width; \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
p_pic += i_pic_line_width; \
} \
i_scale_count += i_pic_height; \
break; \
} \
/*****************************************************************************
* vout_InitYUV: allocate and initialize translations tables
*****************************************************************************
......@@ -292,7 +440,8 @@ int vout_InitYUV( vout_thread_t *p_vout )
switch( p_vout->i_bytes_per_pixel )
{
case 1:
tables_size = sizeof( u8 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
/* nothing to allocate - will put the palette here afterwards */
tables_size = 1;
break;
case 2:
tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
......@@ -399,16 +548,6 @@ static void SetYUV( vout_thread_t *p_vout )
switch( p_vout->i_bytes_per_pixel )
{
case 1:
p_vout->yuv.yuv.p_gray8 = (u8 *)p_vout->yuv.p_base + GRAY_MARGIN;
for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
{
p_vout->yuv.yuv.p_gray8[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
p_vout->yuv.yuv.p_gray8[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
}
for( i_index = 0; i_index < 256; i_index++)
{
p_vout->yuv.yuv.p_gray8[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
}
break;
case 2:
p_vout->yuv.yuv.p_gray16 = (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
......@@ -443,28 +582,6 @@ static void SetYUV( vout_thread_t *p_vout )
switch( p_vout->i_bytes_per_pixel )
{
case 1:
p_vout->yuv.yuv.p_rgb8 = (u8 *)p_vout->yuv.p_base;
for( i_index = 0; i_index < RED_MARGIN; i_index++ )
{
p_vout->yuv.yuv.p_rgb8[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
p_vout->yuv.yuv.p_rgb8[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
}
for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
{
p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
}
for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
{
p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
}
for( i_index = 0; i_index < 256; i_index++ )
{
p_vout->yuv.yuv.p_rgb8[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
}
break;
case 2:
p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
......@@ -691,22 +808,14 @@ static void ConvertY4Gray8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y,
* pixels wide blocks */
for( i_x = i_width / 16; i_x--; )
{
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
*p_buffer++ = *p_y++; *p_buffer++ = *p_y++;
}
/* Do horizontal and vertical scaling */
......@@ -759,22 +868,14 @@ static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y
* pixels wide blocks */
for( i_x = i_width / 16; i_x--; )
{
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
}
/* Do horizontal and vertical scaling */
......@@ -837,22 +938,14 @@ static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y
* pixels wide blocks */
for( i_x = i_width / 16; i_x--; )
{
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
*p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
}
/* Do horizontal and vertical scaling */
......@@ -872,25 +965,32 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
int i_vertical_scaling; /* vertical scaling type */
int i_x, i_y; /* horizontal and vertical indexes */
int i_scale_count; /* scale modulo counter */
int i_uval, i_vval; /* U and V samples */
int i_red, i_green, i_blue; /* U and V modified samples */
int i_jump_uv;
int i_real_y;
int i_chroma_width; /* chroma width */
u8 * p_yuv; /* base conversion table */
u8 * p_ybase; /* Y dependant conversion table */
u8 * p_pic_start; /* beginning of the current line for copy */
u8 * p_buffer_start; /* conversion buffer start */
u8 * p_buffer; /* conversion buffer pointer */
u8 * p_foo; /* conversion buffer pointer */
int * p_offset_start; /* offset array start */
int * p_offset; /* offset array pointer */
int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
int dither20[4] = { 0x00, 0x10, 0x04, 0x14 };
int dither21[4] = { 0x18, 0x08, 0x1c, 0x0c };
int dither22[4] = { 0x06, 0x16, 0x02, 0x12 };
int dither23[4] = { 0x1e, 0x0e, 0x1a, 0x0a };
//int dither[4][4] = { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} };
//int dither[4][4] = { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } };
//int dither[4][4] = { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } };
//int dither[4][4] = { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } };
//int dither[4][4] = { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } };
//int dither[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
/*
* Initialize some values - i_pic_line_width will store the line skip
*/
i_pic_line_width -= i_pic_width;
i_chroma_width = i_width / 2;
p_yuv = p_vout->yuv.yuv.p_rgb8;
p_buffer_start = p_vout->yuv.p_buffer;
p_offset_start = p_vout->yuv.p_offset;
SetOffset( i_width, i_height, i_pic_width, i_pic_height,
&b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
......@@ -899,38 +999,12 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
* Perform conversion
*/
i_scale_count = i_pic_height;
i_real_y = 0;
for( i_y = 0; i_y < i_height; i_y++ )
{
/* Mark beginnning of line for possible later line copy, and initialize
* buffer */
p_pic_start = p_pic;
p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
/* Do YUV conversion to buffer - YUV picture is always formed of 16
* pixels wide blocks */
for( i_x = i_width / 16; i_x--; )
{
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
*p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
}
/* Do horizontal and vertical scaling */
SCALE_WIDTH;
SCALE_HEIGHT(420, 1);
SCALE_WIDTH_DITHER( 420 );
SCALE_HEIGHT_DITHER( 420 );
}
}
......
Markdown is supported
0% or .