Commit 0d972bf5 authored by Sam Hocevar's avatar Sam Hocevar

  * ./Makefile: fixed OS X vlc.app compilation dependencies.
  * ./configure.in: fixed the endianness check under Solaris.

  * ./src/input/input.c: strings are now initialized to "" instead of NULL.

  * ./plugins/spudec/spu_decoder.c: we now properly support the subtitle
    palette information we get from the DVD. Subtitles rox !
  * ./src/video_output/vout_subpictures.c: removed all DVD-specific routines
    and put them into spu_decoder.c.
parent 3dd67e8f
......@@ -533,7 +533,7 @@ gnome-vlc gvlc kvlc qvlc: vlc
rm -f $@ && ln -s vlc $@
.PHONY: vlc.app
vlc.app: Makefile.opts
vlc.app: vlc plugins
ifneq (,$(findstring darwin,$(SYS)))
rm -Rf vlc.app
cd extras/MacOSX ; pbxbuild | grep -v '^ ' | grep -v '^\t'
......
......@@ -3154,11 +3154,11 @@ EOF
if ${CC-cc} conftest.c -o conftest.o >config.log 2>&1 \
&& test -f conftest.o
then
if test `grep -l BIGenDianSyS conftest.o`
if test "`strings conftest.o | grep BIGenDianSyS`"
then
ac_cv_c_bigendian=yes
fi
if test `grep -l LiTTleEnDian conftest.o`
if test "`strings conftest.o | grep LiTTleEnDian`"
then
ac_cv_c_bigendian=no
fi
......@@ -3168,7 +3168,7 @@ EOF
fi
echo "$ac_t""$ac_cv_c_bigendian" 1>&6
if test $ac_cv_c_bigendian = xunknown
if test x$ac_cv_c_bigendian = xunknown
then
{ echo "configure: error: Could not guess endianness, please use --with-words" 1>&2; exit 1; }
fi
......@@ -8792,9 +8792,9 @@ which modules get compiled as plugins.
"
if test x${HAVE_VLC} = x1
then
echo "To build vlc and its plugins, type \`make vlc plugins'."
echo "To build vlc and its plugins, type \`make'."
fi
if test x${HAVE_LIBDVDCSS} = x1
if test x${NEED_LIBDVDCSS} = x1
then
echo "To build libdvdcss only, type \`make libdvdcss'."
fi
......
......@@ -117,18 +117,18 @@ EOF
if ${CC-cc} conftest.c -o conftest.o >config.log 2>&1 \
&& test -f conftest.o
then
if test `grep -l BIGenDianSyS conftest.o`
if test "`strings conftest.o | grep BIGenDianSyS`"
then
ac_cv_c_bigendian=yes
fi
if test `grep -l LiTTleEnDian conftest.o`
if test "`strings conftest.o | grep LiTTleEnDian`"
then
ac_cv_c_bigendian=no
fi
fi
fi
])
if test $ac_cv_c_bigendian = xunknown
if test x$ac_cv_c_bigendian = xunknown
then
AC_MSG_ERROR([Could not guess endianness, please use --with-words])
fi
......@@ -1655,9 +1655,9 @@ which modules get compiled as plugins.
"
if test x${HAVE_VLC} = x1
then
echo "To build vlc and its plugins, type \`make vlc plugins'."
echo "To build vlc and its plugins, type \`make'."
fi
if test x${HAVE_LIBDVDCSS} = x1
if test x${NEED_LIBDVDCSS} = x1
then
echo "To build libdvdcss only, type \`make libdvdcss'."
fi
......
......@@ -4,7 +4,7 @@
* includes all common video types and constants.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video.h,v 1.44 2002/03/01 00:33:18 massiot Exp $
* $Id: video.h,v 1.45 2002/03/15 04:41:54 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -314,6 +314,7 @@ typedef struct subpicture_s
int i_width; /* picture width */
int i_height; /* picture height */
#if 0
/* Additionnal properties depending of the subpicture type */
union
{
......@@ -327,22 +328,22 @@ typedef struct subpicture_s
u32 i_border_color; /* border color */
u32 i_bg_color; /* background color */
} text;
/* DVD subpicture units properties */
struct
{
int i_offset[2]; /* byte offsets to data */
} spu;
} type;
#endif
/* The subpicture rendering routine */
void ( *pf_render ) ( const struct vout_thread_s *, picture_t *,
const struct subpicture_s * );
/* Private data - the subtitle plugin might want to put stuff here to
* keep track of the subpicture */
struct subpicture_sys_s *p_sys; /* subpicture data */
/* Subpicture data, format depends of type - data can always be freely
* modified. p_data itself (the pointer) should NEVER be modified. */
void * p_data; /* subpicture data */
} subpicture_t;
/* Subpicture type */
#define EMPTY_SUBPICTURE 0 /* subtitle slot is empty and available */
#define DVD_SUBPICTURE 100 /* DVD subpicture unit */
#define TEXT_SUBPICTURE 200 /* single line text */
#define MEMORY_SUBPICTURE 100 /* subpicture stored in memory */
/* Subpicture status */
#define FREE_SUBPICTURE 0 /* free and not allocated */
......
......@@ -2,7 +2,7 @@
* file.c: file input (file: access plug-in)
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: file.c,v 1.1 2002/03/01 00:33:18 massiot Exp $
* $Id: file.c,v 1.2 2002/03/15 04:41:54 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -112,8 +112,7 @@ static int FileOpen( input_thread_t * p_input )
vlc_mutex_lock( &p_input->stream.stream_lock );
if( p_input->psz_access != NULL
&& !strncmp( p_input->psz_access, "stream", 7 ) )
if( *p_input->psz_access && !strncmp( p_input->psz_access, "stream", 7 ) )
{
/* stream:%s */
p_input->stream.b_pace_control = 0;
......
......@@ -2,7 +2,7 @@
* http.c: HTTP access plug-in
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: http.c,v 1.3 2002/03/11 07:23:09 gbazin Exp $
* $Id: http.c,v 1.4 2002/03/15 04:41:54 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -216,9 +216,9 @@ static int HTTPOpen( input_thread_t * p_input )
{
_input_socket_t * p_access_data;
char * psz_parser = p_input->psz_name;
char * psz_server_addr = NULL;
char * psz_server_port = NULL;
char * psz_path = NULL;
char * psz_server_addr = "";
char * psz_server_port = "";
char * psz_path = "";
char * psz_proxy;
int i_server_port = 0;
......@@ -229,7 +229,7 @@ static int HTTPOpen( input_thread_t * p_input )
return( -1 );
}
p_access_data->psz_network = NULL;
p_access_data->psz_network = "";
if( config_GetIntVariable( "ipv4" ) )
{
p_access_data->psz_network = "ipv4";
......@@ -238,7 +238,7 @@ static int HTTPOpen( input_thread_t * p_input )
{
p_access_data->psz_network = "ipv6";
}
if( p_input->psz_access != NULL )
if( *p_input->psz_access )
{
/* Find out which shortcut was used */
if( !strncmp( p_input->psz_access, "http6", 5 ) )
......@@ -284,7 +284,7 @@ static int HTTPOpen( input_thread_t * p_input )
}
/* Convert port format */
if( psz_server_port != NULL )
if( *psz_server_port )
{
i_server_port = strtol( psz_server_port, &psz_parser, 10 );
if( *psz_parser )
......@@ -301,7 +301,7 @@ static int HTTPOpen( input_thread_t * p_input )
i_server_port = 80;
}
if( psz_server_addr == NULL )
if( !*psz_server_addr )
{
intf_ErrMsg( "input error: no server given" );
free( p_input->p_access_data );
......
......@@ -2,7 +2,7 @@
* udp.c: raw UDP access plug-in
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: udp.c,v 1.3 2002/03/11 07:23:09 gbazin Exp $
* $Id: udp.c,v 1.4 2002/03/15 04:41:54 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -98,12 +98,12 @@ static int UDPOpen( input_thread_t * p_input )
{
input_socket_t * p_access_data;
struct module_s * p_network;
char * psz_network = NULL;
char * psz_network = "";
char * psz_parser = p_input->psz_name;
char * psz_server_addr = NULL;
char * psz_server_port = NULL;
char * psz_bind_addr = NULL;
char * psz_bind_port = NULL;
char * psz_server_addr = "";
char * psz_server_port = "";
char * psz_bind_addr = "";
char * psz_bind_port = "";
int i_bind_port = 0, i_server_port = 0;
network_socket_t socket_desc;
......@@ -116,7 +116,7 @@ static int UDPOpen( input_thread_t * p_input )
psz_network = "ipv6";
}
if( p_input->psz_access != NULL )
if( *p_input->psz_access )
{
/* Find out which shortcut was used */
if( !strncmp( p_input->psz_access, "udp6", 5 ) )
......@@ -200,7 +200,7 @@ static int UDPOpen( input_thread_t * p_input )
}
/* Convert ports format */
if( psz_server_port != NULL )
if( *psz_server_port )
{
i_server_port = strtol( psz_server_port, &psz_parser, 10 );
if( *psz_parser )
......@@ -211,7 +211,7 @@ static int UDPOpen( input_thread_t * p_input )
}
}
if( psz_bind_port != NULL )
if( *psz_bind_port )
{
i_bind_port = strtol( psz_bind_port, &psz_parser, 10 );
if( *psz_parser )
......
......@@ -8,7 +8,7 @@
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_access.c,v 1.7 2002/03/15 00:57:16 stef Exp $
* $Id: dvd_access.c,v 1.8 2002/03/15 04:41:54 sam Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -662,7 +662,7 @@ static char * DVDParse( input_thread_t * p_input )
}
else
{
psz_raw = NULL;
psz_raw = "";
}
if( *psz_parser && !strtol( psz_parser, NULL, 10 ) )
......@@ -695,7 +695,7 @@ static char * DVDParse( input_thread_t * p_input )
{
/* we have only a partial list of options, no device */
psz_parser = psz_raw;
psz_raw = NULL;
psz_raw = "";
b_options = 1;
break;
}
......@@ -706,7 +706,7 @@ static char * DVDParse( input_thread_t * p_input )
else
{
/* found beginning of options ; no raw device specified */
psz_raw = NULL;
psz_raw = "";
b_options = 1;
}
......@@ -729,7 +729,7 @@ static char * DVDParse( input_thread_t * p_input )
p_dvd->i_angle = i_angle ? i_angle : 1;
}
if( psz_raw )
if( *psz_raw )
{
if( *psz_raw )
{
......@@ -741,7 +741,7 @@ static char * DVDParse( input_thread_t * p_input )
psz_raw, strerror(errno));
/* put back '@' */
*(psz_raw - 1) = '@';
psz_raw = NULL;
psz_raw = "";
}
else
{
......@@ -754,7 +754,7 @@ static char * DVDParse( input_thread_t * p_input )
" not a valid char device", psz_raw );
/* put back '@' */
*(psz_raw - 1) = '@';
psz_raw = NULL;
psz_raw = "";
}
else
#endif
......@@ -768,7 +768,7 @@ static char * DVDParse( input_thread_t * p_input )
}
else
{
psz_raw = NULL;
psz_raw = "";
}
}
......
......@@ -2,7 +2,7 @@
* ipv4.c: IPv4 network abstraction layer
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: ipv4.c,v 1.5 2002/03/11 07:23:09 gbazin Exp $
* $Id: ipv4.c,v 1.6 2002/03/15 04:41:54 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Mathias Kretschmer <mathias@research.att.com>
......@@ -104,7 +104,7 @@ static int BuildAddr( struct sockaddr_in * p_socket,
memset( p_socket, 0, sizeof( struct sockaddr_in ) );
p_socket->sin_family = AF_INET; /* family */
p_socket->sin_port = htons( i_port );
if( psz_address == NULL )
if( !*psz_address )
{
p_socket->sin_addr.s_addr = INADDR_ANY;
}
......@@ -229,7 +229,7 @@ static int OpenUDP( network_socket_t * p_socket )
if (IN_MULTICAST( ntohl( inet_addr(psz_bind_addr) ) ) )
{
psz_bind_win32 = NULL ;
psz_bind_win32 = "";
}
if ( BuildAddr( &sock, psz_bind_win32, i_bind_port ) == -1 )
#else
......@@ -249,7 +249,7 @@ static int OpenUDP( network_socket_t * p_socket )
}
/* Allow broadcast reception if we bound on INADDR_ANY */
if( psz_bind_addr == NULL )
if( !*psz_bind_addr )
{
i_opt = 1;
if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST,
......@@ -289,7 +289,7 @@ static int OpenUDP( network_socket_t * p_socket )
}
}
if( psz_server_addr != NULL )
if( *psz_server_addr )
{
/* Build socket for remote connection */
if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 )
......
......@@ -2,7 +2,7 @@
* ipv6.c: IPv6 network abstraction layer
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: ipv6.c,v 1.2 2002/03/11 07:23:09 gbazin Exp $
* $Id: ipv6.c,v 1.3 2002/03/15 04:41:54 sam Exp $
*
* Authors: Alexis Guillard <alexis.guillard@bt.com>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -104,7 +104,7 @@ static int BuildAddr( struct sockaddr_in6 * p_socket,
memset( p_socket, 0, sizeof( struct sockaddr_in6 ) );
p_socket->sin6_family = AF_INET6; /* family */
p_socket->sin6_port = htons( i_port );
if( psz_address == NULL )
if( !*psz_address )
{
p_socket->sin6_addr = in6addr_any;
}
......@@ -214,7 +214,7 @@ static int OpenUDP( network_socket_t * p_socket )
}
/* Allow broadcast reception if we bound on in6addr_any */
if( psz_bind_addr == NULL )
if( !*psz_bind_addr )
{
i_opt = 1;
if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST,
......@@ -229,7 +229,7 @@ static int OpenUDP( network_socket_t * p_socket )
/* Join the multicast group if the socket is a multicast address */
/* FIXME: To be written */
if( psz_server_addr != NULL )
if( *psz_server_addr )
{
/* Build socket for remote connection */
if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 )
......
......@@ -2,7 +2,7 @@
* spu_decoder.c : spu decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: spu_decoder.c,v 1.11 2002/03/14 01:35:28 stef Exp $
* $Id: spu_decoder.c,v 1.12 2002/03/15 04:41:54 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -57,6 +57,8 @@ static int SyncPacket ( spudec_thread_t * );
static void ParsePacket ( spudec_thread_t * );
static int ParseControlSequences( spudec_thread_t *, subpicture_t * );
static int ParseRLE ( spudec_thread_t *, subpicture_t *, u8 * );
static void RenderSPU ( const vout_thread_t *, picture_t *,
const subpicture_t * );
/*****************************************************************************
* Capabilities
......@@ -102,8 +104,6 @@ static int decoder_Probe( u8 *pi_type )
static int decoder_Run( decoder_config_t * p_config )
{
spudec_thread_t * p_spudec;
int i;
u32 * pi_yuv_color;
intf_WarnMsg( 3, "spudec: thread launched. Initializing ..." );
......@@ -130,17 +130,6 @@ static int decoder_Run( decoder_config_t * p_config )
*/
p_spudec->p_fifo->b_error = InitThread( p_spudec );
pi_yuv_color = p_config->p_demux_data;
for( i=0 ; i<16 ; i++ )
{
intf_WarnMsg( 12, "spudec info: 0x%02x 0x%02x 0x%02x 0x%02x",
*((u8*)(pi_yuv_color)),
*((u8*)(pi_yuv_color) + 1),
*((u8*)(pi_yuv_color) + 2),
*((u8*)(pi_yuv_color) + 3));
pi_yuv_color++;
}
/*
* Main loop - it is not executed if an error occured during
* initialization
......@@ -273,8 +262,9 @@ static void ParsePacket( spudec_thread_t *p_spudec )
}
/* Allocate the subpicture internal data. */
p_spu = vout_CreateSubPicture( p_spudec->p_vout, DVD_SUBPICTURE,
p_spudec->i_rle_size * 4 );
p_spu = vout_CreateSubPicture( p_spudec->p_vout, MEMORY_SUBPICTURE,
sizeof( struct subpicture_sys_s )
+ p_spudec->i_rle_size * 4 );
/* Rationale for the "p_spudec->i_rle_size * 4": we are going to
* expand the RLE stuff so that we won't need to read nibbles later
* on. This will speed things up a lot. Plus, we'll only need to do
......@@ -285,8 +275,13 @@ static void ParsePacket( spudec_thread_t *p_spudec )
return;
}
/* Fill the p_spu structure */
p_spu->pf_render = RenderSPU;
p_spu->p_sys->p_data = (void*)p_spu->p_sys
+ sizeof( struct subpicture_sys_s );
/* Get display time now. If we do it later, we may miss the PTS. */
p_spudec->i_pts = p_spudec->p_fifo->p_first->i_pts;
p_spu->p_sys->i_pts = p_spudec->p_fifo->p_first->i_pts;
/* Allocate the temporary buffer we will parse */
p_src = malloc( p_spudec->i_rle_size );
......@@ -319,7 +314,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
#if 0
/* Dump the subtitle info */
intf_WarnHexDump( 5, p_spu->p_data, p_spudec->i_rle_size );
intf_WarnHexDump( 5, p_spu->p_sys->p_data, p_spudec->i_rle_size );
#endif
/* Getting the control part */
......@@ -345,7 +340,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
intf_WarnMsg( 3, "spudec: total size: 0x%x, RLE offsets: 0x%x 0x%x",
p_spudec->i_spu_size,
p_spu->type.spu.i_offset[0], p_spu->type.spu.i_offset[1] );
p_spu->p_sys->pi_offset[0], p_spu->p_sys->pi_offset[1] );
/* SPU is finished - we can ask the video output to display it */
vout_DisplaySubPicture( p_spudec->p_vout, p_spu );
......@@ -374,6 +369,10 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
u8 i_command;
int i_date;
/* Dummy stuff */
u8 *pi_color;
int i;
/* XXX: temporary variables */
boolean_t b_force_display = 0;
......@@ -403,7 +402,7 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
case SPU_CMD_FORCE_DISPLAY:
/* 00 (force displaying) */
p_spu->i_start = p_spudec->i_pts + ( i_date * 11000 );
p_spu->i_start = p_spu->p_sys->i_pts + ( i_date * 11000 );
b_force_display = 1;
break;
......@@ -412,29 +411,50 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
case SPU_CMD_START_DISPLAY:
/* 01 (start displaying) */
p_spu->i_start = p_spudec->i_pts + ( i_date * 11000 );
p_spu->i_start = p_spu->p_sys->i_pts + ( i_date * 11000 );
break;
case SPU_CMD_STOP_DISPLAY:
/* 02 (stop displaying) */
p_spu->i_stop = p_spudec->i_pts + ( i_date * 11000 );
p_spu->i_stop = p_spu->p_sys->i_pts + ( i_date * 11000 );
break;
case SPU_CMD_SET_PALETTE:
/* 03xxxx (palette) - trashed */
RemoveBits( &p_spudec->bit_stream, 16 );
/* 03xxxx (palette) */
for( i = 0; i < 4 ; i++ )
{
pi_color = (u8*)p_spudec->p_config->p_demux_data
+ 4 * GetBits( &p_spudec->bit_stream, 4 );
if( p_spudec->p_config->p_demux_data )
{
p_spu->p_sys->pi_yuv[3-i][0] = pi_color[2];
p_spu->p_sys->pi_yuv[3-i][1] = pi_color[0];
p_spu->p_sys->pi_yuv[3-i][2] = pi_color[1];
}
else
{
/* No data was available from the IFO file */
p_spu->p_sys->pi_yuv[i][0] = 0x50 * i;
p_spu->p_sys->pi_yuv[i][1] = 0x80;
p_spu->p_sys->pi_yuv[i][2] = 0x80;
}
}
i_index += 2;
break;
case SPU_CMD_SET_ALPHACHANNEL:
/* 04xxxx (alpha channel) - trashed */
RemoveBits( &p_spudec->bit_stream, 16 );
/* 04xxxx (alpha channel) */
for( i = 0; i < 4 ; i++ )
{
p_spu->p_sys->pi_alpha[3-i]
= GetBits( &p_spudec->bit_stream, 4 );
}
i_index += 2;
break;
......@@ -457,10 +477,10 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
case SPU_CMD_SET_OFFSETS:
/* 06xxxxyyyy (byte offsets) */
p_spu->type.spu.i_offset[0] =
p_spu->p_sys->pi_offset[0] =
GetBits( &p_spudec->bit_stream, 16 ) - 4;
p_spu->type.spu.i_offset[1] =
p_spu->p_sys->pi_offset[1] =
GetBits( &p_spudec->bit_stream, 16 ) - 4;
i_index += 4;
......@@ -570,7 +590,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
unsigned int i_height = p_spu->i_height;
unsigned int i_x, i_y;
u16 *p_dest = (u16 *)p_spu->p_data;
u16 *p_dest = (u16 *)p_spu->p_sys->p_data;
/* The subtitles are interlaced, we need two offsets */
unsigned int i_id = 0; /* Start on the even SPU layer */
......@@ -582,8 +602,8 @@ static int ParseRLE( spudec_thread_t *p_spudec,
unsigned int i_skipped_top = 0,
i_skipped_bottom = 0;
pi_table[ 0 ] = p_spu->type.spu.i_offset[ 0 ] << 1;
pi_table[ 1 ] = p_spu->type.spu.i_offset[ 1 ] << 1;
pi_table[ 0 ] = p_spu->p_sys->pi_offset[ 0 ] << 1;
pi_table[ 1 ] = p_spu->p_sys->pi_offset[ 1 ] << 1;
for( i_y = 0 ; i_y < i_height ; i_y++ )
{
......@@ -633,7 +653,8 @@ static int ParseRLE( spudec_thread_t *p_spudec,
return( 1 );
}
if( i_code == (i_width << 2) ) /* FIXME: we assume 0 is transp */
if( (i_code >> 2) == i_width
&& !p_spu->p_sys->pi_alpha[ i_code & 0x3 ] )
{
if( b_empty_top )
{
......@@ -713,3 +734,188 @@ static int ParseRLE( spudec_thread_t *p_spudec,
return( 0 );
}
/*****************************************************************************
* RenderSPU: draw an SPU on a picture
*****************************************************************************
* This is a fast implementation of the subpicture drawing code. The data
* has been preprocessed once, so we don't need to parse the RLE buffer again
* and again. Most sanity checks are already done so that this routine can be
* as fast as possible.
*****************************************************************************/
static void RenderSPU( const vout_thread_t *p_vout, picture_t *p_pic,
const subpicture_t *p_spu )
{
/* Common variables */
u16 p_clut16[4];
u8 *p_dest;
u16 *p_source = (u16 *)p_spu->p_sys->p_data;
int i_x, i_y;
int i_len, i_color;
/* RGB-specific */
int i_xscale, i_yscale, i_width, i_height, i_ytmp, i_yreal, i_ynext;
switch( p_vout->output.i_chroma )
{
/* I420 target, no scaling */
case FOURCC_I420:
case FOURCC_IYUV:
case FOURCC_YV12:
p_dest = p_pic->p->p_pixels + p_spu->i_x + p_spu->i_width
+ p_vout->output.i_width * ( p_spu->i_y + p_spu->i_height );
/* Draw until we reach the bottom of the subtitle */
for( i_y = p_spu->i_height * p_vout->output.i_width ;
i_y ;
i_y -= p_vout->output.i_width )
{
/* Draw until we reach the end of the line */
for( i_x = p_spu->i_width ; i_x ; )
{
/* Get the RLE part, then draw the line */
i_color = *p_source & 0x3;
switch( p_spu->p_sys->pi_alpha[ i_color ] )
{
case 0x00:
i_x -= *p_source++ >> 2;