Commit 2faf5103 authored by Vincent Seguin's avatar Vincent Seguin

Nettoyage, ajout du gamma, pr�paration de la yuv walken.

parent a6bc5de8
......@@ -22,7 +22,7 @@ VIDEO=X11
# Target architecture and optimization
#ARCH=
ARCH=MMX
#ARCH=MMX
#ARCH=PPC
# Decoder choice - ?? old decoder will be removed soon
......@@ -64,6 +64,7 @@ endif
# Libraries
#
LIB += -lpthread
LIB += -lm
ifeq ($(VIDEO),X11)
LIB += -L/usr/X11R6/lib
......@@ -211,7 +212,7 @@ misc_obj = misc/mtime.o \
ifeq ($(ARCH),MMX)
ASM_OBJ = video_decoder_ref/idctmmx.o \
video_output/yuv_mmx.o
video_output/video_yuv_mmx.o
endif
C_OBJ = $(interface_obj) \
......
......@@ -119,6 +119,11 @@
/* Base delay in micro second for interface sleeps */
#define INTF_IDLE_SLEEP 100000
/* Factor for changing gamma, and minimum and maximum values */
#define INTF_GAMMA_FACTOR 1.1
#define INTF_GAMMA_MIN 0.1
#define INTF_GAMMA_MAX 10
/*
* X11 settings
*/
......@@ -241,6 +246,9 @@
#define VOUT_GRAYSCALE_VAR "vlc_grayscale"
#define VOUT_GRAYSCALE_DEFAULT 0
/* Default gamma */
#define VOUT_GAMMA 1.
/*
* Time settings
*/
......
......@@ -57,7 +57,7 @@ typedef struct
* (the pointer) should NEVER be modified. In YUV format, the p_y, p_u and
* p_v data pointers refers to different areas of p_data, and should not
* be freed */
byte_t * p_data; /* picture data */
void * p_data; /* picture data */
yuv_data_t * p_y; /* pointer to beginning of Y image in p_data */
yuv_data_t * p_u; /* pointer to beginning of U image in p_data */
yuv_data_t * p_v; /* pointer to beginning of V image in p_data */
......
......@@ -34,9 +34,11 @@ typedef struct vout_thread_s
int i_bytes_per_pixel; /* real screen depth */
float f_x_ratio; /* horizontal display ratio */
float f_y_ratio; /* vertical display ratio */
float f_gamma; /* gamma */
/* New size for resizeable windows - they may be ignored or handled by
* vout_SysManage */
/* Changed properties values - some of them are treated directly by the
* thread, the over may be ignored or handled by vout_SysManage */
boolean_t b_gamma_change; /* gamma change indicator */
int i_new_width; /* new width */
int i_new_height; /* new height */
......@@ -59,15 +61,16 @@ typedef struct vout_thread_s
/* Video heap */
picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */
/* YUV translation tables, for 15,16 and 24/32 bpp displays. 16 bits and 32
* bits pointers points on the same data.
* CAUTION: these tables are translated: their origin is -384 */
u16 * pi_trans16_red;
u16 * pi_trans16_green;
u16 * pi_trans16_blue;
u32 * pi_trans32_red;
u32 * pi_trans32_green;
u32 * pi_trans32_blue;
/* YUV translation tables - they have to be casted to the appropriate width
* on use. All tables are allocated in the same memory block, based at
* p_trans_base, and shifted depending of the output thread configuration */
byte_t * p_trans_base; /* base for all translation tables */
void * p_trans_red;
void * p_trans_green;
void * p_trans_blue;
void * p_trans_gray;
/* YUV translation tables, for optimized C YUV transform ?? */
} vout_thread_t;
/*******************************************************************************
......
......@@ -16,7 +16,7 @@ void vout_SysEnd ( p_vout_thread_t p_vout );
void vout_SysDestroy ( p_vout_thread_t p_vout );
int vout_SysManage ( p_vout_thread_t p_vout );
void vout_SysDisplay ( p_vout_thread_t p_vout );
byte_t * vout_SysGetPicture ( p_vout_thread_t p_vout );
void * vout_SysGetPicture ( p_vout_thread_t p_vout );
void vout_SysPrint ( p_vout_thread_t p_vout, int i_x, int i_y,
int i_halign, int i_valign,
unsigned char *psz_text );
......
......@@ -166,7 +166,7 @@ void vout_SysDisplay( vout_thread_t *p_vout )
*******************************************************************************
* This function returns the address of the current display buffer.
*******************************************************************************/
byte_t * vout_SysGetPicture( vout_thread_t *p_vout )
void * vout_SysGetPicture( vout_thread_t *p_vout )
{
return( p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->write );
}
......
......@@ -10,7 +10,8 @@
/*******************************************************************************
* Preamble
*******************************************************************************/
#include <errno.h>
#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
......@@ -43,14 +44,29 @@
* not change much for two different loops. This macro allows to change slightly
* the content of the loop without having to copy and paste code. It is used in
* RenderYUVPicture function. */
#define YUV_GRAYSCALE( TRANS_RED, TRANS_GREEN, TRANS_BLUE, P_PIC ) \
#define YUV_GRAYSCALE( TRANS_GRAY, P_PIC ) \
/* Main loop */ \
for (i_pic_y=0; i_pic_y < p_pic->i_height ; i_pic_y++) \
{ \
for (i_pic_x=0; i_pic_x< p_pic->i_width; i_pic_x++) \
for (i_pic_x=0; i_pic_x< p_pic->i_width; i_pic_x+=16) \
{ \
i_y = *p_y++; \
*P_PIC++ = TRANS_RED[i_y] | TRANS_GREEN[i_y] | TRANS_BLUE[i_y]; \
/* Convert 16 pixels (width is always multiple of 16 */ \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
*P_PIC++ = TRANS_GRAY[ *p_y++ ]; \
} \
/* Skip until beginning of next line */ \
P_PIC += i_eol_offset; \
......@@ -66,7 +82,7 @@ for (i_pic_y=0; i_pic_y < p_pic->i_height ; i_pic_y++) \
/* Main loop */ \
for (i_pic_y=0; i_pic_y < p_pic->i_height ; i_pic_y++) \
{ \
for (i_pic_x=0; i_pic_x< p_pic->i_width; i_pic_x+=2) \
for (i_pic_x=0; i_pic_x< p_pic->i_width; i_pic_x+=2 ) \
{ \
/* First sample (complete) */ \
i_y = 76309 * *p_y++ - 1188177; \
......@@ -123,7 +139,7 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
* i_width, i_height: frames dimensions (pixels)
* i_ypitch, i_vpitch: Y and V lines sizes (bytes)
* i_aspect: vertical aspect factor
* pi_pic: RGB frame
* p_pic: RGB frame
* i_dci_offset: ?? x offset for left image border
* i_offset_to_line_0: ?? x offset for left image border
* i_pitch: RGB line size (bytes)
......@@ -131,7 +147,7 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
void vout_YUV420_16_MMX( u8* p_y, u8* p_u, u8 *p_v,
unsigned int i_width, unsigned int i_height,
unsigned int i_ypitch, unsigned int i_vpitch,
unsigned int i_aspect, u8 *pi_pic,
unsigned int i_aspect, u8 *p_pic,
u32 i_dci_offset, u32 i_offset_to_line_0,
int CCOPitch, int i_colortype );
#endif
......@@ -143,6 +159,7 @@ static int InitThread ( vout_thread_t *p_vout );
static void RunThread ( vout_thread_t *p_vout );
static void ErrorThread ( vout_thread_t *p_vout );
static void EndThread ( vout_thread_t *p_vout );
static void BuildTables ( vout_thread_t *p_vout );
static void RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderYUVGrayPicture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderYUV16Picture ( vout_thread_t *p_vout, picture_t *p_pic );
......@@ -192,6 +209,7 @@ vout_thread_t * vout_CreateThread (
p_vout->i_bytes_per_pixel = 2;
p_vout->f_x_ratio = 1;
p_vout->f_y_ratio = 1;
p_vout->f_gamma = VOUT_GAMMA;
intf_DbgMsg("wished configuration: %dx%d,%d (%d bytes/pixel, %d bytes/line), ratio %.2f:%.2f, gray=%d\n",
p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
......@@ -224,6 +242,9 @@ vout_thread_t * vout_CreateThread (
p_vout->c_idle_loops = 0;
p_vout->c_fps_samples = 0;
#endif
p_vout->b_gamma_change = 0;
p_vout->i_new_width = p_vout->i_width;
p_vout->i_new_height = p_vout->i_height;
/* Create thread and set locks */
vlc_mutex_init( &p_vout->lock );
......@@ -516,7 +537,6 @@ void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
static int InitThread( vout_thread_t *p_vout )
{
int i_index; /* generic index */
int i_pixel_size; /* pixel size, in bytes, for translations tables */
/* Update status */
*p_vout->pi_status = THREAD_START;
......@@ -536,94 +556,19 @@ static int InitThread( vout_thread_t *p_vout )
}
/* Allocate translation tables */
switch( p_vout->i_bytes_per_pixel )
p_vout->p_trans_base = malloc( 4 * 1024 * p_vout->i_bytes_per_pixel );
if( p_vout->p_trans_base == NULL )
{
case 2: /* 15 or 16 bpp, use 16 bits translations tables */
i_pixel_size = sizeof( u16 );
break;
case 3: /* 24 or 32 bpp, use 32 bits translations tables */
case 4:
#ifndef DEBUG
default:
#endif
i_pixel_size = sizeof( u32 );
break;
#ifdef DEBUG
default:
intf_DbgMsg("error: invalid bytes_per_pixel %d\n", p_vout->i_bytes_per_pixel );
i_pixel_size = sizeof( u32 );
break;
#endif
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
return( 1 );
}
p_vout->pi_trans32_red = (u32 *)p_vout->pi_trans16_red =
(u16 *)malloc( 1024 * i_pixel_size );
p_vout->pi_trans32_green = (u32 *)p_vout->pi_trans16_green =
(u16 *)malloc( 1024 * i_pixel_size );
p_vout->pi_trans32_blue = (u32 *)p_vout->pi_trans16_blue =
(u16 *)malloc( 1024 * i_pixel_size );
if( (p_vout->pi_trans16_red == NULL) ||
(p_vout->pi_trans16_green == NULL ) ||
(p_vout->pi_trans16_blue == NULL ) )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
*p_vout->pi_status = THREAD_ERROR;
if( p_vout->pi_trans16_red != NULL )
{
free( p_vout->pi_trans16_red );
}
if( p_vout->pi_trans16_green != NULL )
{
free( p_vout->pi_trans16_green );
}
if( p_vout->pi_trans16_blue != NULL )
{
free( p_vout->pi_trans16_blue );
}
return( 1 );
}
p_vout->p_trans_red = p_vout->p_trans_base + 384 *p_vout->i_bytes_per_pixel;
p_vout->p_trans_green = p_vout->p_trans_base + ( 1024 + 384)*p_vout->i_bytes_per_pixel;
p_vout->p_trans_blue = p_vout->p_trans_base + (2*1024 + 384)*p_vout->i_bytes_per_pixel;
p_vout->p_trans_gray = p_vout->p_trans_base + (3*1024 + 384)*p_vout->i_bytes_per_pixel;
/* Translate translation tables */
p_vout->pi_trans16_red += 384;
p_vout->pi_trans16_green += 384;
p_vout->pi_trans16_blue += 384;
p_vout->pi_trans32_red += 384;
p_vout->pi_trans32_green += 384;
p_vout->pi_trans32_blue += 384;
/* Build translation tables */
switch( p_vout->i_screen_depth )
{
case 15:
for( i_index = -384; i_index < 640; i_index++)
{
p_vout->pi_trans16_red[i_index] = (CLIP_BYTE( i_index ) & 0xf8)<<7;
p_vout->pi_trans16_green[i_index] = (CLIP_BYTE( i_index ) & 0xf8)<<2;
p_vout->pi_trans16_blue[i_index] = CLIP_BYTE( i_index ) >> 3;
}
break;
case 16:
for( i_index = -384; i_index < 640; i_index++)
{
p_vout->pi_trans16_red[i_index] = (CLIP_BYTE( i_index ) & 0xf8)<<8;
p_vout->pi_trans16_green[i_index] = (CLIP_BYTE( i_index ) & 0xfc)<<3;
p_vout->pi_trans16_blue[i_index] = CLIP_BYTE( i_index ) >> 3;
}
break;
case 24:
case 32:
for( i_index = -384; i_index < 640; i_index++)
{
p_vout->pi_trans32_red[i_index] = CLIP_BYTE( i_index ) <<16;
p_vout->pi_trans32_green[i_index] = CLIP_BYTE( i_index ) <<8;
p_vout->pi_trans32_blue[i_index] = CLIP_BYTE( i_index ) ;
}
break;
#ifdef DEBUG
default:
intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
break;
#endif
}
BuildTables( p_vout );
/* Mark thread as running and return */
p_vout->b_active = 1;
......@@ -725,6 +670,15 @@ static void RunThread( vout_thread_t *p_vout)
}
}
/*
* Rebuild tables if gamma has changed
*/
if( p_vout->b_gamma_change )
{
p_vout->b_gamma_change = 0;
BuildTables( p_vout );
}
/*
* Check events, sleep and display picture
*/
......@@ -844,10 +798,8 @@ static void EndThread( vout_thread_t *p_vout )
}
}
/* Destroy translation tables - remeber these tables are translated */
free( p_vout->pi_trans16_red - 384 );
free( p_vout->pi_trans16_green - 384 );
free( p_vout->pi_trans16_blue - 384 );
/* Destroy translation tables */
free( p_vout->p_trans_base );
/* Destroy thread structures allocated by InitThread */
vout_SysEnd( p_vout );
......@@ -858,6 +810,72 @@ static void EndThread( vout_thread_t *p_vout )
*pi_status = THREAD_OVER;
}
/*******************************************************************************
* BuildTables: build YUV translation tables
*******************************************************************************
* This function will build translations tables according to pixel width and
* gamma.
*******************************************************************************/
static void BuildTables( vout_thread_t *p_vout )
{
u16 * p_trans16_red = (u16 *) p_vout->p_trans_red;
u16 * p_trans16_green = (u16 *) p_vout->p_trans_green;
u16 * p_trans16_blue = (u16 *) p_vout->p_trans_blue;
u16 * p_trans16_gray = (u16 *) p_vout->p_trans_gray;
u32 * p_trans32_red = (u32 *) p_vout->p_trans_red;
u32 * p_trans32_green = (u32 *) p_vout->p_trans_green;
u32 * p_trans32_blue = (u32 *) p_vout->p_trans_blue;
u32 * p_trans32_gray = (u32 *) p_vout->p_trans_gray;
u8 i_gamma[256]; /* gamma table */
int i_index; /* index in tables */
/* Build gamma table */
for( i_index = 0; i_index < 256; i_index++ )
{
i_gamma[i_index] = 255. * pow( (double)i_index / 255., p_vout->f_gamma );
}
/* Build red, green, blue and gray tables */
switch( p_vout->i_screen_depth )
{
case 15:
for( i_index = -384; i_index < 640; i_index++)
{
p_trans16_red[i_index] = (i_gamma[CLIP_BYTE( i_index )] & 0xf8)<<7;
p_trans16_green[i_index] = (i_gamma[CLIP_BYTE( i_index )] & 0xf8)<<2;
p_trans16_blue[i_index] = i_gamma[CLIP_BYTE( i_index )] >> 3;
p_trans16_gray[i_index] = p_trans16_red[i_index] |
p_trans16_green[i_index] | p_trans16_blue[i_index];
}
break;
case 16:
for( i_index = -384; i_index < 640; i_index++)
{
p_trans16_red[i_index] = (i_gamma[CLIP_BYTE( i_index )] & 0xf8)<<8;
p_trans16_green[i_index] = (i_gamma[CLIP_BYTE( i_index )] & 0xfc)<<3;
p_trans16_blue[i_index] = i_gamma[CLIP_BYTE( i_index )] >> 3;
p_trans16_gray[i_index] = p_trans16_red[i_index] |
p_trans16_green[i_index] | p_trans16_blue[i_index];
}
break;
case 32:
for( i_index = -384; i_index < 640; i_index++)
{
p_trans32_red[i_index] = i_gamma[CLIP_BYTE( i_index )] <<16;
p_trans32_green[i_index] = i_gamma[CLIP_BYTE( i_index )] <<8;
p_trans32_blue[i_index] = i_gamma[CLIP_BYTE( i_index )] ;
p_trans32_gray[i_index] = p_trans32_red[i_index] |
p_trans32_green[i_index] | p_trans32_blue[i_index];
}
break;
#ifdef DEBUG
default:
intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
break;
#endif
}
}
/*******************************************************************************
* RenderPicture: render a picture
*******************************************************************************
......@@ -890,7 +908,7 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
RenderYUV16Picture( p_vout, p_pic );
}
else /* color 24 or 32 bpp */
else if( p_vout->i_bytes_per_pixel == 4 ) /* color 32 bpp */
{
RenderYUV32Picture( p_vout, p_pic );
}
......@@ -909,7 +927,7 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
}
/*******************************************************************************
* RenderYUVGrayPicture: render a 15, 16, 24 or 32 bpp YUV picture in grayscale
* RenderYUVGrayPicture: render YUV picture in grayscale
*******************************************************************************
* Performs the YUV convertion. The picture sent to this function should only
* have YUV_420, YUV_422 or YUV_444 types.
......@@ -920,15 +938,10 @@ static void RenderYUVGrayPicture( vout_thread_t *p_vout, picture_t *p_pic )
int i_width, i_height; /* picture size */
int i_eol_offset; /* pixels from end of line to next line */
yuv_data_t *p_y; /* Y data base adress */
yuv_data_t i_y; /* Y sample */
u16 * pi_pic16; /* destination picture, 15 or 16 bpp */
u32 * pi_pic32; /* destination picture, 24 or 32 bpp */
u16 * pi_trans16_red; /* red transformation table */
u16 * pi_trans16_green; /* green transformation table */
u16 * pi_trans16_blue; /* blue transformation table */
u32 * pi_trans32_red; /* red transformation table */
u32 * pi_trans32_green; /* green transformation table */
u32 * pi_trans32_blue; /* blue transformation table */
u16 * p_pic16; /* destination picture, 15 or 16 bpp */
u32 * p_pic32; /* destination picture, 32 bpp */
u16 * p_trans16_gray; /* transformation table, 15 or 16 bpp */
u32 * p_trans32_gray; /* transformation table, 32 bpp */
/* Set the base pointers and transformation parameters */
p_y = p_pic->p_y;
......@@ -942,23 +955,14 @@ static void RenderYUVGrayPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
case 15:
case 16:
pi_trans16_red = p_vout->pi_trans16_red;
pi_trans16_green = p_vout->pi_trans16_green;
pi_trans16_blue = p_vout->pi_trans16_blue;
pi_pic16 = (u16 *) vout_SysGetPicture( p_vout );
YUV_GRAYSCALE( pi_trans16_red, pi_trans16_green, pi_trans16_blue,
pi_pic16 );
p_trans16_gray = (u16 *) p_vout->p_trans_gray;
p_pic16 = (u16 *) vout_SysGetPicture( p_vout );
YUV_GRAYSCALE( p_trans16_gray, p_pic16 );
break;
case 24:
case 32:
pi_trans32_red = p_vout->pi_trans32_red;
pi_trans32_green = p_vout->pi_trans32_green;
pi_trans32_blue = p_vout->pi_trans32_blue;
pi_pic32 = (u32 *) vout_SysGetPicture( p_vout );
YUV_GRAYSCALE( pi_trans32_red, pi_trans32_green, pi_trans32_blue,
pi_pic32 );
p_trans32_gray = (u32 *) p_vout->p_trans_gray;
p_pic32 = (u32 *) vout_SysGetPicture( p_vout );
YUV_GRAYSCALE( p_trans32_gray, p_pic32 );
break;
#ifdef DEBUG
default:
......@@ -986,10 +990,10 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
yuv_data_t *p_y; /* Y data base adress */
yuv_data_t *p_u; /* U data base adress */
yuv_data_t *p_v; /* V data base adress */
u16 * pi_pic; /* base adress for destination picture */
u16 * pi_trans_red; /* red transformation table */
u16 * pi_trans_green; /* green transformation table */
u16 * pi_trans_blue; /* blue transformation table */
u16 * p_data; /* base adress for destination picture */
u16 * p_trans_red; /* red transformation table */
u16 * p_trans_green; /* green transformation table */
u16 * p_trans_blue; /* blue transformation table */
/* Choose transformation matrix coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][0];
......@@ -997,10 +1001,11 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
i_cgu = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][3];
/* Choose the conversions tables */
pi_trans_red = p_vout->pi_trans16_red;
pi_trans_green = p_vout->pi_trans16_green;
pi_trans_blue = p_vout->pi_trans16_blue;
/* Choose the conversions tables and picture address */
p_trans_red = (u16 *) p_vout->p_trans_red;
p_trans_green = (u16 *) p_vout->p_trans_green;
p_trans_blue = (u16 *) p_vout->p_trans_blue;
p_data = (u16 *) vout_SysGetPicture( p_vout );
/* Set the base pointers and transformation parameters */
p_y = p_pic->p_y;
......@@ -1011,9 +1016,6 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
i_chroma_width = i_width / 2;
i_eol_offset = p_vout->i_bytes_per_line / 2 - i_width;
/* Get base adress for destination image */
pi_pic = (u16 *)vout_SysGetPicture( p_vout );
/* Do YUV transformation - the loops are repeated for optimization */
switch( p_pic->i_type )
{
......@@ -1022,36 +1024,36 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
vout_YUV420_16_MMX( p_y, p_u, p_v,
i_width, i_height,
i_width, i_chroma_width,
0, (u8 *) pi_pic,
0, p_data,
0, 0, p_vout->i_bytes_per_line,
p_vout->i_screen_depth == 15 );
#else
YUV_TRANSFORM( 420,
pi_trans_red,
pi_trans_green,
pi_trans_blue,
pi_pic );
p_trans_red,
p_trans_green,
p_trans_blue,
p_data );
#endif
break;
case YUV_422_PICTURE: /* 15 or 16 bpp 422 transformation */
YUV_TRANSFORM( 422,
pi_trans_red,
pi_trans_green,
pi_trans_blue,
pi_pic );
p_trans_red,
p_trans_green,
p_trans_blue,
p_data );
break;
case YUV_444_PICTURE: /* 15 or 16 bpp 444 transformation */
YUV_TRANSFORM( 444,
pi_trans_red,
pi_trans_green,
pi_trans_blue,
pi_pic );
p_trans_red,
p_trans_green,
p_trans_blue,
p_data );
break;
}
}
/*******************************************************************************
* RenderYUV32Picture: render a 24 or 32 bpp YUV picture
* RenderYUV32Picture: render a 32 bpp YUV picture
*******************************************************************************
* Performs the YUV convertion. The picture sent to this function should only
* have YUV_420, YUV_422 or YUV_444 types.
......@@ -1067,10 +1069,10 @@ static void RenderYUV32Picture( vout_thread_t *p_vout, picture_t *p_pic )
yuv_data_t *p_y; /* Y data base adress */
yuv_data_t *p_u; /* U data base adress */
yuv_data_t *p_v; /* V data base adress */
u32 * pi_pic; /* base adress for destination picture */
u32 * pi_trans_red; /* red transformation table */
u32 * pi_trans_green; /* green transformation table */
u32 * pi_trans_blue; /* blue transformation table */
u32 * p_data; /* base adress for destination picture */
u32 * p_trans_red; /* red transformation table */
u32 * p_trans_green; /* green transformation table */
u32 * p_trans_blue; /* blue transformation table */
/* Choose transformation matrix coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][0];
......@@ -1078,10 +1080,11 @@ static void RenderYUV32Picture( vout_thread_t *p_vout, picture_t *p_pic )
i_cgu = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][3];
/* Choose the conversions tables */
pi_trans_red = p_vout->pi_trans32_red;
pi_trans_green = p_vout->pi_trans32_green;
pi_trans_blue = p_vout->pi_trans32_blue;
/* Choose the conversions tables and picture address */
p_trans_red = (u32 *) p_vout->p_trans_red;
p_trans_green = (u32 *) p_vout->p_trans_green;
p_trans_blue = (u32 *) p_vout->p_trans_blue;
p_data = (u32 *) vout_SysGetPicture( p_vout );
/* Set the base pointers and transformation parameters */
p_y = p_pic->p_y;
......@@ -1092,32 +1095,29 @@ static void RenderYUV32Picture( vout_thread_t *p_vout, picture_t *p_pic )
i_chroma_width = i_width / 2;
i_eol_offset = p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - i_width;
/* Get base adress for destination image */
pi_pic = (u32 *)vout_SysGetPicture( p_vout );
/* Do YUV transformation - the loops are repeated for optimization */
switch( p_pic->i_type )
{
case YUV_420_PICTURE: /* 24 or 32 bpp 420 transformation */
case YUV_420_PICTURE: /* 32 bpp 420 transformation */
YUV_TRANSFORM( 420,
pi_trans_red,
pi_trans_green,
pi_trans_blue,
pi_pic );
p_trans_red,
p_trans_green,
p_trans_blue,
p_data );
break;
case YUV_422_PICTURE: /* 24 or 32 bpp 422 transformation */
case YUV_422_PICTURE: /* 32 bpp 422 transformation */
YUV_TRANSFORM( 422,
pi_trans_red,
pi_trans_green,
pi_trans_blue,
pi_pic );
p_trans_red,
p_trans_green,
p_trans_blue,
p_data );
break;
case YUV_444_PICTURE: /* 24 or 32 bpp 444 transformation */
case YUV_444_PICTURE: /* 32 bpp 444 transformation */
YUV_TRANSFORM( 444,
pi_trans_red,
pi_trans_green,
pi_trans_blue,
pi_pic );
p_trans_red,
p_trans_green,
p_trans_blue,
p_data );
break;
}
}
......@@ -1147,8 +1147,8 @@ static void RenderInfo( vout_thread_t *p_vout )
}
/* Print statistics in upper left corner */
sprintf( psz_buffer, "%ld frames (%.1f %% idle)", p_vout->c_fps_samples,
p_vout->c_loops ?
sprintf( psz_buffer, "gamma=%.2f %ld frames (%.1f %% idle)",
p_vout->f_gamma, p_vout->c_fps_samples, p_vout->c_loops ?
(double ) p_vout->c_idle_loops * 100 / p_vout->c_loops : 100. );
vout_SysPrint( p_vout, 0, 0, -1, -1, psz_buffer );
#endif
......
......@@ -275,7 +275,7 @@ void vout_SysDisplay( vout_thread_t *p_vout )
*******************************************************************************
* This function returns the address of the current display buffer.
*******************************************************************************/
byte_t * vout_SysGetPicture( vout_thread_t *p_vout )
void * vout_SysGetPicture( vout_thread_t *p_vout )
{
return( p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->data );
}
......@@ -407,10 +407,6 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root
return( 1 );
}
/* Store additionnal vout informations */
p_vout->i_new_width = p_vout->i_width;
p_vout->i_new_height = p_vout->i_height;
/* Get font information */
if( X11GetFont( p_vout ) )
{
......
/*******************************************************************************
* video_yuv_c.c: YUV transformation, optimized
* (c)1999 VideoLAN
*******************************************************************************
* Provides optimized functions to perform the YUV conversion.
*******************************************************************************/
#include <stdlib.h> /* malloc */
#include "convert.h"
static int binaryLog (int i)
{
int log;
log = 0;
if (i & 0xffff0000) log = 16;
if (i & 0xff00ff00) log += 8;
if (i & 0xf0f0f0f0) log += 4;
if (i & 0xcccccccc) log += 2;
if (i & 0xaaaaaaaa) log++;
if (i != (1 << log))
return -1;
return log;
}
static int colorMaskToShift (int * right, int * left, int mask)
{
int low;
int high;
low = mask & (- mask); /* lower bit of the mask */
high = mask + low; /* higher bit of the mask */
low = binaryLog (low);
high = binaryLog (high);
if ((low == -1) || (high == -1))
return 1;
*left = low;
*right = (8 - high + low);
return 0;
}
/*
* YUV to RGB routines.
*
* these routines calculate r, g and b values from each pixel's y, u and v.
* these r, g an b values are then passed thru a table lookup to take the
* gamma curve into account and find the corresponding pixel value.
*
* the table must store more than 3*256 values because of the possibility
* of overflow in the yuv->rgb calculation. actually the calculated r,g,b
* values are in the following intervals :
* -176 to 255+176 for red
* -133 to 255+133 for green
* -222 to 255+222 for blue
*
* If the input y,u,v values are right, the r,g,b results are not expected
* to move out of the 0 to 255 interval but who knows what will happen in
* real use...
*
* the red, green and blue conversion tables are stored in a single 1935-entry
* array. The respective positions of each component in the array have been
* calculated to minimize the cache interactions of the 3 tables.
*/
static int rgbTable16 (short table [1935],
int redMask, int greenMask, int blueMask,
unsigned char gamma[256])
{
int redRight;
int redLeft;
int greenRight;
int greenLeft;
int blueRight;
int blueLeft;
short * redTable;
short * greenTable;
short * blueTable;
int i;
int y;
if (colorMaskToShift (&redRight, &redLeft, redMask) ||
colorMaskToShift (&greenRight, &greenLeft, greenMask) ||
colorMaskToShift (&blueRight, &blueLeft, blueMask))
return 1;
/*
* green blue red +- 2 just to be sure
* green = 0-525 [151-370]
* blue = 594-1297 [834-1053] <834-29>
* red = 1323-1934 [1517-1736] <493-712>
*/
redTable = table + 1501;
greenTable = table + 135;
blueTable = table + 818;
for (i = 0; i < 178; i++) {
redTable[i-178] = 0;
redTable[i+256] = redMask;
}
for (i = 0; i < 135; i++) {
greenTable[i-135] = 0;
greenTable[i+256] = greenMask;
}
for (i = 0; i < 224; i++) {
blueTable[i-224] = 0;
blueTable[i+256] = blueMask;
}
for (i = 0; i < 256; i++) {
y = gamma[i];
redTable[i] = ((y >> redRight) << redLeft);
greenTable[i] = ((y >> greenRight) << greenLeft);
blueTable[i] = ((y >> blueRight) << blueLeft);
}
return 0;
}
static int rgbTable32 (int table [1935],
int redMask, int greenMask, int blueMask,
unsigned char gamma[256])
{
int redRight;
int redLeft;
int greenRight;
int greenLeft;
int blueRight;
int blueLeft;
int * redTable;
int * greenTable;
int * blueTable;
int i;
int y;
if (colorMaskToShift (&redRight, &redLeft, redMask) ||
colorMaskToShift (&greenRight, &greenLeft, greenMask) ||
colorMaskToShift (&blueRight, &blueLeft, blueMask))
return 1;
/*
* green blue red +- 2 just to be sure
* green = 0-525 [151-370]
* blue = 594-1297 [834-1053] <834-29>
* red = 1323-1934 [1517-1736] <493-712>
*/
redTable = table + 1501;
greenTable = table + 135;
blueTable = table + 818;
for (i = 0; i < 178; i++) {
redTable[i-178] = 0;
redTable[i+256] = redMask;
}
for (i = 0; i < 135; i++) {
greenTable[i-135] = 0;
greenTable[i+256] = greenMask;
}
for (i = 0; i < 224; i++) {
blueTable[i-224] = 0;
blueTable[i+256] = blueMask;
}
for (i = 0; i < 256; i++) {
y = gamma[i];
redTable[i] = ((y >> redRight) << redLeft);
greenTable[i] = ((y >> greenRight) << greenLeft);
blueTable[i] = ((y >> blueRight) << blueLeft);
}
return 0;
}
#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))
static void yuvToRgb16 (unsigned char * Y,
unsigned char * U, unsigned char * V,
short * dest, short table[1935], int width)
{
int i;
int u;
int v;
int uvRed;
int uvGreen;
int uvBlue;
short * tableY;
i = width >> 4;
while (i--) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
}
i = (width & 15) >> 1;
while (i--) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
}
if (width & 1) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
}
}
static void yuvToRgb24 (unsigned char * Y,
unsigned char * U, unsigned char * V,
char * dest, int table[1935], int width)
{
int i;
int u;
int v;
int uvRed;
int uvGreen;
int uvBlue;
int * tableY;
int tmp24;
i = width >> 3;
while (i--) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
}
i = (width & 7) >> 1;
while (i--) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
}
if (width & 1) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
*(dest++) = tmp24;
*(dest++) = tmp24 >> 8;
*(dest++) = tmp24 >> 16;
}
}
static void yuvToRgb32 (unsigned char * Y,
unsigned char * U, unsigned char * V,
int * dest, int table[1935], int width)
{
int i;
int u;
int v;
int uvRed;
int uvGreen;
int uvBlue;
int * tableY;
i = width >> 4;
while (i--) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
}
i = (width & 15) >> 1;
while (i--) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
}
if (width & 1) {
u = *(U++);
v = *(V++);
uvRed = (V_RED_COEF*v) >> SHIFT;
uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
uvBlue = (U_BLUE_COEF*u) >> SHIFT;
tableY = table + *(Y++);
*(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
uvGreen] |
tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
}
}
/* API routines */
int convertGrey (CONVERTER * convert, DISPLAY * disp)
{
if ((convert == NULL) || (disp == NULL))
return 1;
if (greyRgbTable (disp))
return 1;
switch (disp->bytesPerPixel) {
case 2:
convert->convert = &greyToRgb16;
break;
case 3:
convert->convert = &greyToRgb24;
break;
case 4:
convert->convert = &greyToRgb32;
break;
default:
return 1;
}
convert->table = disp->greyRgbTable;
return 0;
}
static void * greyRgbTable (DISP_COLORS * colors, unsigned char gamma[256])
{
/* FIXME could avoid recalculating the same table */
void * table;
for (i = 0; i < 16; i++)
gamma[i] = 0;
#define Y_COEF ((int)(1.164 * 65536))
for (; i <= 235; i++)
gamma[i] = (Y_COEF * i - Y_COEF * 16) >> 16;
#undef Y_COEF
for (; i < 256; i++)
gamma[i] = 255;
}
switch (colors->bytesPerPixel) {
case 2:
table = malloc (256 * sizeof (short));
if (table == NULL)
break;
if (greyRgb16Table (table,
colors->redMask,
colors->greenMask,
colors->blueMask,
gamma))
goto error;
return table;
case 3:
case 4:
table = malloc (256 * sizeof (int));
if (table == NULL)
break;
if (greyRgb32Table (table,
colors->redMask,
colors->greenMask,
colors->blueMask,
gamma))
goto error;
return table;
error:
free (table);
}
return NULL;
}
static void * rgbTable (DISP_COLORS * colors, unsigned char gamma[256])
{
/* FIXME could avoid recalculating the same table */
void * table;
switch (colors->bytesPerPixel) {
case 2:
table = malloc (1935 * sizeof (short));
if (table == NULL)
break;
if (rgbTable16 (table,
colors->redMask, colors->greenMask, colors->blueMask,
gamma))
goto error;
return table;
case 3:
case 4:
table = malloc (1935 * sizeof (int));
if (table == NULL)
break;
if (rgbTable32 (table,
colors->redMask, colors->greenMask, colors->blueMask,
gamma))
goto error;
return table;
error:
free (table);
}
return NULL;
}
/*******************************************************************************
* yuv_mmx.S: YUV transformation, optimized for MMX processors
* video_yuv_mmx.S: YUV transformation, optimized for MMX processors
* (c)1999 VideoLAN
*******************************************************************************
* Following functions are defined:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment