X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_chroma%2Fi420_rgb.c;h=b08824b66f879ca0a7142f59c7f02d55a2fc384b;hb=eb85f7afc2685c9973973a8d6c1a4530c6b77972;hp=4bf0342d409890272f1262f5009f548a8f6a9fe0;hpb=41a8349dba161e8704ac76dc5cea23bf13afff80;p=vlc diff --git a/modules/video_chroma/i420_rgb.c b/modules/video_chroma/i420_rgb.c index 4bf0342d40..b08824b66f 100644 --- a/modules/video_chroma/i420_rgb.c +++ b/modules/video_chroma/i420_rgb.c @@ -1,16 +1,17 @@ /***************************************************************************** * i420_rgb.c : YUV to bitmap RGB conversion module for vlc ***************************************************************************** - * Copyright (C) 2000, 2001 VideoLAN - * $Id: i420_rgb.c,v 1.4 2003/08/29 18:58:05 fenrir Exp $ + * Copyright (C) 2000, 2001, 2004 the VideoLAN team + * $Id$ * - * Authors: Samuel Hocevar + * Authors: Sam Hocevar + * Damien Fouilleul * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -18,18 +19,20 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ #include /* exp(), pow() */ -#include /* strerror() */ -#include /* malloc(), free() */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include -#include +#include #include "i420_rgb.h" #if defined (MODULE_NAME_IS_i420_rgb) @@ -72,6 +75,11 @@ vlc_module_begin(); "RV15,RV16,RV24,RV32 conversions") ); set_capability( "chroma", 100 ); add_requirement( MMX ); +#elif defined (MODULE_NAME_IS_i420_rgb_sse2) + set_description( _( "SSE2 I420,IYUV,YV12 to " + "RV15,RV16,RV24,RV32 conversions") ); + set_capability( "chroma", 120 ); + add_requirement( SSE2 ); #endif set_callbacks( Activate, Deactivate ); vlc_module_end(); @@ -107,33 +115,78 @@ static int Activate( vlc_object_t *p_this ) #endif case VLC_FOURCC('R','V','1','5'): case VLC_FOURCC('R','V','1','6'): -#if defined (MODULE_NAME_IS_i420_rgb_mmx) +#if ! defined (MODULE_NAME_IS_i420_rgb) /* 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 ) ) + if( ( p_vout->output.i_rmask == 0x7c00 + && p_vout->output.i_gmask == 0x03e0 + && p_vout->output.i_bmask == 0x001f ) ) { - return -1; + /* R5G5B6 pixel format */ + msg_Dbg(p_this, "RGB pixel format is R5G5B5"); + p_vout->chroma.pf_convert = E_(I420_R5G5B5); } -#endif + else if( ( p_vout->output.i_rmask == 0xf800 + && p_vout->output.i_gmask == 0x07e0 + && p_vout->output.i_bmask == 0x001f ) ) + { + /* R5G6B5 pixel format */ + msg_Dbg(p_this, "RGB pixel format is R5G6B5"); + p_vout->chroma.pf_convert = E_(I420_R5G6B5); + } + else + return -1; +#else + // generic C chroma converter */ p_vout->chroma.pf_convert = E_(I420_RGB16); +#endif break; +#if 0 + /* Hmmm, is there only X11 using 32bits per pixel for RV24 ? */ case VLC_FOURCC('R','V','2','4'): +#endif + case VLC_FOURCC('R','V','3','2'): -#if defined (MODULE_NAME_IS_i420_rgb_mmx) +#if ! defined (MODULE_NAME_IS_i420_rgb) /* 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 ) + if( p_vout->output.i_rmask == 0x00ff0000 + && p_vout->output.i_gmask == 0x0000ff00 + && p_vout->output.i_bmask == 0x000000ff ) { - return -1; + /* A8R8G8B8 pixel format */ + msg_Dbg(p_this, "RGB pixel format is A8R8G8B8"); + p_vout->chroma.pf_convert = E_(I420_A8R8G8B8); } -#endif + else if( p_vout->output.i_rmask == 0xff000000 + && p_vout->output.i_gmask == 0x00ff0000 + && p_vout->output.i_bmask == 0x0000ff00 ) + { + /* R8G8B8A8 pixel format */ + msg_Dbg(p_this, "RGB pixel format is R8G8B8A8"); + p_vout->chroma.pf_convert = E_(I420_R8G8B8A8); + } + else if( p_vout->output.i_rmask == 0x0000ff00 + && p_vout->output.i_gmask == 0x00ff0000 + && p_vout->output.i_bmask == 0xff000000 ) + { + /* B8G8R8A8 pixel format */ + msg_Dbg(p_this, "RGB pixel format is B8G8R8A8"); + p_vout->chroma.pf_convert = E_(I420_B8G8R8A8); + } + else if( p_vout->output.i_rmask == 0x000000ff + && p_vout->output.i_gmask == 0x0000ff00 + && p_vout->output.i_bmask == 0x00ff0000 ) + { + /* A8B8G8R8 pixel format */ + msg_Dbg(p_this, "RGB pixel format is A8B8G8R8"); + p_vout->chroma.pf_convert = E_(I420_A8B8G8R8); + } + else + return -1; +#else + /* generic C chroma converter */ p_vout->chroma.pf_convert = E_(I420_RGB32); +#endif break; default: @@ -144,7 +197,7 @@ static int Activate( vlc_object_t *p_this ) default: return -1; } - + p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) ); if( p_vout->chroma.p_sys == NULL ) { @@ -218,7 +271,7 @@ static int Activate( vlc_object_t *p_this ) SetYUV( p_vout ); #endif - return 0; + return 0; } /***************************************************************************** @@ -263,8 +316,10 @@ static void SetGammaTable( int *pi_table, double f_gamma ) *****************************************************************************/ static void SetYUV( vout_thread_t *p_vout ) { - int pi_gamma[256]; /* gamma table */ - int i_index; /* index in tables */ + int pi_gamma[256]; /* gamma table */ + volatile int i_index; /* index in tables */ + /* We use volatile here to work around a strange gcc-3.3.4 + * optimization bug */ /* Build gamma table */ SetGammaTable( pi_gamma, p_vout->f_gamma ); @@ -342,7 +397,10 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 ) int y,u,v; int r,g,b; int i = 0, j = 0; - uint16_t red[ 256 ], green[ 256 ], blue[ 256 ]; + uint16_t *p_cmap_r=p_vout->chroma.p_sys->p_rgb_r; + uint16_t *p_cmap_g=p_vout->chroma.p_sys->p_rgb_g; + uint16_t *p_cmap_b=p_vout->chroma.p_sys->p_rgb_b; + unsigned char p_lookup[PALETTE_TABLE_SIZE]; /* This loop calculates the intersection of an YUV box and the RGB cube. */ @@ -369,9 +427,15 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 ) } /* Clip the colors */ - red[ j ] = CLIP( r ); - green[ j ] = CLIP( g ); - blue[ j ] = CLIP( b ); + p_cmap_r[ j ] = CLIP( r ); + p_cmap_g[ j ] = CLIP( g ); + p_cmap_b[ j ] = CLIP( b ); + +#if 0 + printf("+++Alloc RGB cmap %d (%d, %d, %d)\n", j, + p_cmap_r[ j ] >>8, p_cmap_g[ j ] >>8, + p_cmap_b[ j ] >>8); +#endif /* Allocate color */ p_lookup[ i ] = 1; @@ -388,7 +452,7 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 ) } /* The colors have been allocated, we can set the palette */ - p_vout->output.pf_setpalette( p_vout, red, green, blue ); + p_vout->output.pf_setpalette( p_vout, p_cmap_r, p_cmap_g, p_cmap_b ); #if 0 /* There will eventually be a way to know which colors