Commit d6b20103 authored by Sam Hocevar's avatar Sam Hocevar

* ./modules/video_chroma/i420_rgb16.c: merged the RV15 and RV16 conversions

    because they're basically the same. Also, the MMX conversions now check
    that the bitmasks are the ones we expect.
parent 592dee30
No related merge requests found
......@@ -4,7 +4,7 @@
* includes all common video types and constants.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video.h,v 1.60 2002/11/20 13:37:35 sam Exp $
* $Id: video.h,v 1.61 2002/11/25 19:29:10 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -114,15 +114,6 @@ struct picture_heap_t
void (* pf_setpalette) ( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );
};
/* RGB2PIXEL: assemble RGB components to a pixel value, returns a uint32_t */
#define RGB2PIXEL( p_vout, i_r, i_g, i_b ) \
(((((uint32_t)i_r) >> p_vout->output.i_rrshift) \
<< p_vout->output.i_lrshift) \
| ((((uint32_t)i_g) >> p_vout->output.i_rgshift) \
<< p_vout->output.i_lgshift) \
| ((((uint32_t)i_b) >> p_vout->output.i_rbshift) \
<< p_vout->output.i_lbshift))
/*****************************************************************************
* Flags used to describe the status of a picture
*****************************************************************************/
......
......@@ -2,7 +2,7 @@
* i420_rgb.c : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_rgb.c,v 1.2 2002/11/20 13:37:36 sam Exp $
* $Id: i420_rgb.c,v 1.3 2002/11/25 19:29:10 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -36,6 +36,17 @@
# include "i420_rgb_c.h"
#endif
/*****************************************************************************
* RGB2PIXEL: assemble RGB components to a pixel value, returns a uint32_t
*****************************************************************************/
#define RGB2PIXEL( p_vout, i_r, i_g, i_b ) \
(((((uint32_t)i_r) >> p_vout->output.i_rrshift) \
<< p_vout->output.i_lrshift) \
| ((((uint32_t)i_g) >> p_vout->output.i_rgshift) \
<< p_vout->output.i_lgshift) \
| ((((uint32_t)i_b) >> p_vout->output.i_rbshift) \
<< p_vout->output.i_lbshift))
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
......@@ -54,7 +65,7 @@ static void Set8bppPalette ( vout_thread_t *, u8 * );
vlc_module_begin();
#if defined (MODULE_NAME_IS_i420_rgb)
set_description( _("I420,IYUV,YV12 to "
"RGB,RV15,RV16,RV24,RV32 conversions") );
"RGB2,RV15,RV16,RV24,RV32 conversions") );
set_capability( "chroma", 80 );
#elif defined (MODULE_NAME_IS_i420_rgb_mmx)
set_description( _( "MMX I420,IYUV,YV12 to "
......@@ -95,15 +106,33 @@ static int Activate( vlc_object_t *p_this )
break;
#endif
case VLC_FOURCC('R','V','1','5'):
p_vout->chroma.pf_convert = E_(I420_RGB15);
break;
case VLC_FOURCC('R','V','1','6'):
#if defined (MODULE_NAME_IS_i420_rgb_mmx)
/* If we don't have support for the bitmasks, bail out */
if( ( p_vout->output.i_rmask != 0x7c00
|| p_vout->output.i_gmask != 0x03e0
|| p_vout->output.i_bmask != 0x001f )
&& ( p_vout->output.i_rmask != 0xf800
|| p_vout->output.i_gmask != 0x07e0
|| p_vout->output.i_bmask != 0x001f ) )
{
return -1;
}
#endif
p_vout->chroma.pf_convert = E_(I420_RGB16);
break;
case VLC_FOURCC('R','V','2','4'):
case VLC_FOURCC('R','V','3','2'):
#if defined (MODULE_NAME_IS_i420_rgb_mmx)
/* If we don't have support for the bitmasks, bail out */
if( p_vout->output.i_rmask != 0x00ff0000
|| p_vout->output.i_gmask != 0x0000ff00
|| p_vout->output.i_bmask != 0x000000ff )
{
return -1;
}
#endif
p_vout->chroma.pf_convert = E_(I420_RGB32);
break;
......
......@@ -2,7 +2,7 @@
* i420_rgb.h : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: i420_rgb.h,v 1.1 2002/08/04 17:23:43 sam Exp $
* $Id: i420_rgb.h,v 1.2 2002/11/25 19:29:10 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -46,10 +46,10 @@ struct chroma_sys_t
*****************************************************************************/
#ifdef MODULE_NAME_IS_i420_rgb
void E_(I420_RGB8) ( vout_thread_t *, picture_t *, picture_t * );
void E_(I420_RGB16_dither) ( vout_thread_t *, picture_t *, picture_t * );
#endif
void E_(I420_RGB15)( vout_thread_t *, picture_t *, picture_t * );
void E_(I420_RGB16)( vout_thread_t *, picture_t *, picture_t * );
void E_(I420_RGB32)( vout_thread_t *, picture_t *, picture_t * );
void E_(I420_RGB16) ( vout_thread_t *, picture_t *, picture_t * );
void E_(I420_RGB32) ( vout_thread_t *, picture_t *, picture_t * );
/*****************************************************************************
* CONVERT_*_PIXEL: pixel conversion macros
......@@ -75,6 +75,22 @@ void E_(I420_RGB32)( vout_thread_t *, picture_t *, picture_t * );
i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
CONVERT_Y_PIXEL( BPP ) \
#define CONVERT_Y_PIXEL_DITHER( BPP ) \
/* Only Y sample is present */ \
p_ybase = p_yuv + *p_y++; \
*p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128+p_dither[i_real_y])>>SHIFT) + i_red] | \
p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128+p_dither[i_real_y])>>SHIFT) \
+ i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128+p_dither[i_real_y])>>SHIFT) + i_blue];
#define CONVERT_YUV_PIXEL_DITHER( BPP ) \
/* Y, U and V samples are present */ \
i_uval = *p_u++; \
i_vval = *p_v++; \
i_red = (V_RED_COEF * i_vval) >> SHIFT; \
i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
CONVERT_Y_PIXEL_DITHER( BPP ) \
#define CONVERT_4YUV_PIXEL( CHROMA ) \
*p_pic++ = p_lookup[ \
(((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
......
......@@ -2,7 +2,7 @@
* i420_rgb16.c : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: i420_rgb16.c,v 1.3 2002/11/22 12:11:38 sam Exp $
* $Id: i420_rgb16.c,v 1.4 2002/11/25 19:29:10 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -39,8 +39,9 @@
static void SetOffset( int, int, int, int, vlc_bool_t *, int *, int * );
#if defined (MODULE_NAME_IS_i420_rgb)
/*****************************************************************************
* I420_RGB15: color YUV 4:2:0 to RGB 15 bpp
* I420_RGB16: color YUV 4:2:0 to RGB 16 bpp with dithering
*****************************************************************************
* Horizontal alignment needed:
* - input: 8 pixels (8 Y bytes, 4 U/V bytes), margins not allowed
......@@ -49,7 +50,7 @@ static void SetOffset( int, int, int, int, vlc_bool_t *, int *, int * );
* - input: 2 lines (2 Y lines, 1 U/V line)
* - output: 1 line
*****************************************************************************/
void E_(I420_RGB15)( vout_thread_t *p_vout, picture_t *p_src,
void E_(I420_RGB16_dithering)( vout_thread_t *p_vout, picture_t *p_src,
picture_t *p_dest )
{
/* We got this one from the old arguments */
......@@ -61,18 +62,17 @@ void E_(I420_RGB15)( vout_thread_t *p_vout, picture_t *p_src,
vlc_bool_t b_hscale; /* horizontal scaling type */
int i_vscale; /* vertical scaling type */
unsigned int i_x, i_y; /* horizontal and vertical indexes */
unsigned int i_real_y; /* y % 4 */
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_vout->render.i_width / 2; /* chroma width */
u16 * p_pic_start; /* beginning of the current line for copy */
#if defined (MODULE_NAME_IS_i420_rgb)
int i_uval, i_vval; /* U and V samples */
int i_red, i_green, i_blue; /* U and V modified samples */
u16 * p_yuv = p_vout->chroma.p_sys->p_rgb16;
u16 * p_ybase; /* Y dependant conversion table */
#endif
/* Conversion buffer pointer */
u16 * p_buffer_start = (u16*)p_vout->chroma.p_sys->p_buffer;
......@@ -82,6 +82,20 @@ void E_(I420_RGB15)( vout_thread_t *p_vout, picture_t *p_src,
int * p_offset_start = p_vout->chroma.p_sys->p_offset;
int * p_offset;
/* The dithering matrices */
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 };
for(i_x = 0; i_x < 4; i_x++)
{
dither10[i_x] = dither10[i_x] << (SHIFT - 4 + p_vout->output.i_rrshift);
dither11[i_x] = dither11[i_x] << (SHIFT - 4 + p_vout->output.i_rrshift);
dither12[i_x] = dither12[i_x] << (SHIFT - 4 + p_vout->output.i_rrshift);
dither13[i_x] = dither13[i_x] << (SHIFT - 4 + p_vout->output.i_rrshift);
}
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
if( p_vout->render.i_width & 7 )
......@@ -107,66 +121,60 @@ void E_(I420_RGB15)( vout_thread_t *p_vout, picture_t *p_src,
p_vout->output.i_height : p_vout->render.i_height;
for( i_y = 0; i_y < p_vout->render.i_height; i_y++ )
{
i_real_y = i_y & 0x3;
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_vout->render.i_width / 8; i_x--; )
{
#if defined (MODULE_NAME_IS_i420_rgb)
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
#elif defined (MODULE_NAME_IS_i420_rgb_mmx)
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_15
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
int *p_dither = dither10;
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither11;
CONVERT_Y_PIXEL_DITHER(2);
p_dither = dither12;
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither13;
CONVERT_Y_PIXEL_DITHER(2);
p_dither = dither10;
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither11;
CONVERT_Y_PIXEL_DITHER(2);
p_dither = dither12;
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither13;
CONVERT_Y_PIXEL_DITHER(2);
}
/* Here we do some unaligned reads and duplicate conversions, but
* at least we have all the pixels */
if( i_rewind )
{
int *p_dither = dither10;
p_y -= i_rewind;
p_u -= i_rewind >> 1;
p_v -= i_rewind >> 1;
p_buffer -= i_rewind;
#if defined (MODULE_NAME_IS_i420_rgb)
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
#elif defined (MODULE_NAME_IS_i420_rgb_mmx)
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_15
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither11;
CONVERT_Y_PIXEL_DITHER(2);
p_dither = dither12;
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither13;
CONVERT_Y_PIXEL_DITHER(2);
p_dither = dither10;
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither11;
CONVERT_Y_PIXEL_DITHER(2);
p_dither = dither12;
CONVERT_YUV_PIXEL_DITHER(2);
p_dither = dither13;
CONVERT_Y_PIXEL_DITHER(2);
}
SCALE_WIDTH;
SCALE_HEIGHT( 420, 2 );
}
}
#endif
/*****************************************************************************
* I420_RGB16: color YUV 4:2:0 to RGB 16 bpp
......@@ -239,14 +247,40 @@ void E_(I420_RGB16)( vout_thread_t *p_vout, picture_t *p_src,
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
#if defined (MODULE_NAME_IS_i420_rgb)
for ( i_x = p_vout->render.i_width / 8; i_x--; )
{
#if defined (MODULE_NAME_IS_i420_rgb)
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
}
#elif defined (MODULE_NAME_IS_i420_rgb_mmx)
if( p_vout->output.i_rmask == 0x7c00 )
{
/* 15bpp 5/5/5 */
for ( i_x = p_vout->render.i_width / 8; i_x--; )
{
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_15
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
}
}
else
{
/* 16bpp 5/6/5 */
for ( i_x = p_vout->render.i_width / 8; i_x--; )
{
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
......@@ -260,8 +294,9 @@ void E_(I420_RGB16)( vout_thread_t *p_vout, picture_t *p_src,
p_u += 4;
p_v += 4;
p_buffer += 8;
#endif
}
}
#endif
/* Here we do some unaligned reads and duplicate conversions, but
* at least we have all the pixels */
......@@ -280,11 +315,24 @@ void E_(I420_RGB16)( vout_thread_t *p_vout, picture_t *p_src,
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
if( p_vout->output.i_rmask == 0x7c00 )
{
/* 15bpp 5/5/5 */
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_15
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
}
else
{
/* 16bpp 5/6/5 */
__asm__( ".align 8"
MMX_YUV_MUL
MMX_YUV_ADD
MMX_UNPACK_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
}
p_y += 8;
p_u += 4;
......
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