diff --git a/Makefile b/Makefile index 6859762499e345aad00b81869482863ec71415dc..cb113527fe370b4b1f06789dbaf0649b8d78adfe 100644 --- a/Makefile +++ b/Makefile @@ -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' diff --git a/configure b/configure index 64744ae5bd531a513ceeb3e729eb1d7b426f4e6c..f6714db37bfa9e310ecb955c76d8c24e71ca624e 100755 --- a/configure +++ b/configure @@ -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 diff --git a/configure.in b/configure.in index d318572d1d41356d3041b18f14e3309d922047fc..0e870f3da42314ba03df17e293ea6af640c14f35 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/include/video.h b/include/video.h index 52662edb9a86c3ffb822c7affec572053e85bd74..6c94b5c542f6d05960dfd8d0879627e744a31930 100644 --- a/include/video.h +++ b/include/video.h @@ -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 */ diff --git a/plugins/access/file.c b/plugins/access/file.c index f0b97dbcbfffe590bab751eef91075d01e6b2d9b..7f8b2fd4920abbdbcd0b5992d543ad811b337c5e 100644 --- a/plugins/access/file.c +++ b/plugins/access/file.c @@ -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; diff --git a/plugins/access/http.c b/plugins/access/http.c index 08b69d320b495edf7371ddc3b6f3a93dbfd629e5..54980e26b16be536e8c3ede3d50b9588991d2bd4 100644 --- a/plugins/access/http.c +++ b/plugins/access/http.c @@ -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 ); diff --git a/plugins/access/udp.c b/plugins/access/udp.c index 1d5b667534ca7c5e271a7a8717468bf5e2982258..4af7edc841424a1d86bbae68afc576475499494c 100644 --- a/plugins/access/udp.c +++ b/plugins/access/udp.c @@ -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 ) diff --git a/plugins/dvd/dvd_access.c b/plugins/dvd/dvd_access.c index c7765500dc1da2d9342ce5c303a35f0263767cb0..6243ca4970142849cf6940275ffdbe9b4a8dfa35 100644 --- a/plugins/dvd/dvd_access.c +++ b/plugins/dvd/dvd_access.c @@ -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: St�phane 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 = ""; } } diff --git a/plugins/network/ipv4.c b/plugins/network/ipv4.c index 77f845e81cb7c18f92d3a74dfecda92ae5369ccc..4a875438571402458b3b4c70b86cd695eb6e148b 100644 --- a/plugins/network/ipv4.c +++ b/plugins/network/ipv4.c @@ -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 ) diff --git a/plugins/network/ipv6.c b/plugins/network/ipv6.c index 936ed4fc3482e7df1a76fbe1e76c931d04401c23..808caa236613dd66797723afbfd279bcd2a8894b 100644 --- a/plugins/network/ipv6.c +++ b/plugins/network/ipv6.c @@ -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 ) diff --git a/plugins/spudec/spu_decoder.c b/plugins/spudec/spu_decoder.c index b5c251180e351fc6ff79746942bd69024f4b85ea..309a66b6fa16ef27ed2ccad684447199236a0047 100644 --- a/plugins/spudec/spu_decoder.c +++ b/plugins/spudec/spu_decoder.c @@ -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; + break; + + case 0x0f: + i_len = *p_source++ >> 2; + memset( p_dest - i_x - i_y, + p_spu->p_sys->pi_yuv[i_color][0], i_len ); + i_x -= i_len; + break; + + default: + /* FIXME: we should do transparency */ + i_len = *p_source++ >> 2; + memset( p_dest - i_x - i_y, + p_spu->p_sys->pi_yuv[i_color][0], i_len ); + i_x -= i_len; + break; + } + } + } + + break; + + /* RV16 target, scaling */ + case FOURCC_RV16: + + /* FIXME: get this from the DVD */ + p_clut16[0] = 0xaaaa; p_clut16[1] = 0xffff; + p_clut16[2] = 0x8888; p_clut16[3] = 0x0000; + + i_xscale = ( p_vout->output.i_width << 6 ) / p_vout->render.i_width; + i_yscale = ( p_vout->output.i_height << 6 ) / p_vout->render.i_height; + + i_width = p_spu->i_width * i_xscale; + i_height = p_spu->i_height * i_yscale; + + p_dest = p_pic->p->p_pixels + ( i_width >> 6 ) * 2 + /* Add the picture coordinates and the SPU coordinates */ + + ( (p_spu->i_x * i_xscale) >> 6 ) * 2 + + ( (p_spu->i_y * i_yscale) >> 6 ) * p_vout->output.i_width * 2; + + /* Draw until we reach the bottom of the subtitle */ + for( i_y = 0 ; i_y < i_height ; ) + { + i_ytmp = i_y >> 6; + i_y += i_yscale; + + /* Check whether we need to draw one line or more than one */ + if( i_ytmp + 1 >= ( i_y >> 6 ) ) + { + /* Just one line : we precalculate i_y >> 6 */ + i_yreal = p_vout->output.i_width * 2 * i_ytmp; + + /* Draw until we reach the end of the line */ + for( i_x = 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 -= i_xscale * ( *p_source++ >> 2 ); + break; + + case 0x0f: + i_len = i_xscale * ( *p_source++ >> 2 ); + memset( p_dest - 2 * ( i_x >> 6 ) + i_yreal, + p_clut16[ i_color ], + 2 * ( ( i_len >> 6 ) + 1 ) ); + i_x -= i_len; + break; + + default: + /* FIXME: we should do transparency */ + i_len = i_xscale * ( *p_source++ >> 2 ); + memset( p_dest - 2 * ( i_x >> 6 ) + i_yreal, + p_clut16[ i_color ], + 2 * ( ( i_len >> 6 ) + 1 ) ); + i_x -= i_len; + break; + } + + } + } + else + { + i_yreal = p_vout->output.i_width * 2 * i_ytmp; + i_ynext = p_vout->output.i_width * 2 * i_y >> 6; + + /* Draw until we reach the end of the line */ + for( i_x = i_width ; i_x ; ) + { + /* Get the RLE part, then draw as many lines as needed */ + i_color = *p_source & 0x3; + + switch( p_spu->p_sys->pi_alpha[ i_color ] ) + { + case 0x00: + i_x -= i_xscale * ( *p_source++ >> 2 ); + break; + + case 0x0f: + i_len = i_xscale * ( *p_source++ >> 2 ); + for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; + i_ytmp += p_vout->output.i_width * 2 ) + { + memset( p_dest - 2 * ( i_x >> 6 ) + i_ytmp, + p_clut16[ i_color ], + 2 * ( ( i_len >> 6 ) + 1 ) ); + } + i_x -= i_len; + break; + + default: + /* FIXME: we should do transparency */ + i_len = i_xscale * ( *p_source++ >> 2 ); + for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; + i_ytmp += p_vout->output.i_width * 2 ) + { + memset( p_dest - 2 * ( i_x >> 6 ) + i_ytmp, + p_clut16[ i_color ], + 2 * ( ( i_len >> 6 ) + 1 ) ); + } + i_x -= i_len; + break; + } + } + } + } + + break; + + default: + intf_ErrMsg( "vout error: unknown chroma, can't render SPU" ); + break; + } +} + diff --git a/plugins/spudec/spu_decoder.h b/plugins/spudec/spu_decoder.h index 2f9fa94a1262ab0f5670371205ee079ba745e7c8..c8d95d64631b77069bf5767f69e71fba7d249121 100644 --- a/plugins/spudec/spu_decoder.h +++ b/plugins/spudec/spu_decoder.h @@ -2,7 +2,7 @@ * spu_decoder.h : sub picture unit decoder thread interface ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: spu_decoder.h,v 1.1 2001/12/09 17:01:37 sam Exp $ + * $Id: spu_decoder.h,v 1.2 2002/03/15 04:41:54 sam Exp $ * * Authors: Samuel Hocevar <sam@zoy.org> * @@ -21,6 +21,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +typedef struct subpicture_sys_s +{ + mtime_t i_pts; /* presentation timestamp */ + + int pi_offset[2]; /* byte offsets to data */ + void *p_data; + + /* Color information */ + u8 pi_alpha[4]; + u8 pi_yuv[4][3]; + +} subpicture_sys_t; + /***************************************************************************** * spudec_thread_t : sub picture unit decoder thread descriptor *****************************************************************************/ @@ -47,9 +60,6 @@ typedef struct spudec_thread_s /* * Private properties */ - mtime_t i_pts; /* presentation timestamp */ - - // subpicture_t * p_spu; int i_spu_size; /* size of current SPU packet */ int i_rle_size; /* size of the RLE part */ diff --git a/src/input/input.c b/src/input/input.c index 88ef91948bce6db39bce462e53fd20d23735137c..43d38ccf26df6b700bfb74ba201b4c8082b0b0fd 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -4,7 +4,7 @@ * decoders. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: input.c,v 1.189 2002/03/11 07:23:09 gbazin Exp $ + * $Id: input.c,v 1.190 2002/03/15 04:41:54 sam Exp $ * * Authors: Christophe Massiot <massiot@via.ecp.fr> * Alexis Guillard <alexis.guillard@bt.com> @@ -451,7 +451,7 @@ static int InitThread( input_thread_t * p_input ) if( !*psz_parser ) { - p_input->psz_access = p_input->psz_demux = NULL; + p_input->psz_access = p_input->psz_demux = ""; p_input->psz_name = p_input->psz_source; } else @@ -466,12 +466,12 @@ static int InitThread( input_thread_t * p_input ) if( !*psz_parser ) { /* No access */ - p_input->psz_access = NULL; + p_input->psz_access = ""; } else if( *psz_parser == '/' ) { /* No access */ - p_input->psz_access = NULL; + p_input->psz_access = ""; psz_parser++; } else @@ -492,7 +492,7 @@ static int InitThread( input_thread_t * p_input ) if( !*psz_parser ) { /* No demux */ - p_input->psz_demux = NULL; + p_input->psz_demux = ""; } else { @@ -500,7 +500,7 @@ static int InitThread( input_thread_t * p_input ) } } - intf_WarnMsg( 2, "input: access=%s demux=%s name=%s", + intf_WarnMsg( 2, "input: access `%s', demux `%s', name `%s'", p_input->psz_access, p_input->psz_demux, p_input->psz_name ); diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index d92f82f661c3b16c1213935343b74315f8e18c11..f01c734b46e3def6de077e9b9628bd915fcdbe65 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -5,7 +5,7 @@ * thread, and destroy a previously oppened video output thread. ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: video_output.c,v 1.165 2002/03/11 07:23:10 gbazin Exp $ + * $Id: video_output.c,v 1.166 2002/03/15 04:41:54 sam Exp $ * * Authors: Vincent Seguin <seguin@via.ecp.fr> * @@ -648,7 +648,7 @@ static void EndThread( vout_thread_t *p_vout ) { if( p_vout->p_subpicture[i_index].i_status != FREE_SUBPICTURE ) { - free( p_vout->p_subpicture[i_index].p_data ); + free( p_vout->p_subpicture[i_index].p_sys ); } } diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c index 33f1bcd7ecd322dcf102e3ab7ff2bd6819bfaee2..20a2e8457ddd844681513ab16a4e98c021948cb3 100644 --- a/src/video_output/vout_subpictures.c +++ b/src/video_output/vout_subpictures.c @@ -2,7 +2,7 @@ * vout_subpictures.c : subpicture management functions ***************************************************************************** * Copyright (C) 2000 VideoLAN - * $Id: vout_subpictures.c,v 1.10 2002/03/11 07:23:10 gbazin Exp $ + * $Id: vout_subpictures.c,v 1.11 2002/03/15 04:41:54 sam Exp $ * * Authors: Vincent Seguin <seguin@via.ecp.fr> * Samuel Hocevar <sam@zoy.org> @@ -35,12 +35,6 @@ #include "video.h" #include "video_output.h" -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static void vout_RenderSPU( const vout_thread_t *p_vout, picture_t *p_pic, - const subpicture_t *p_spu ); - /***************************************************************************** * vout_DisplaySubPicture: display a subpicture unit ***************************************************************************** @@ -132,7 +126,7 @@ subpicture_t *vout_CreateSubPicture( vout_thread_t *p_vout, int i_type, { /* No free subpicture or matching destroyed subpictures have been * found, but a destroyed subpicture is still avalaible */ - free( p_destroyed_subpic->p_data ); + free( p_destroyed_subpic->p_sys ); p_free_subpic = p_destroyed_subpic; } @@ -144,22 +138,9 @@ subpicture_t *vout_CreateSubPicture( vout_thread_t *p_vout, int i_type, return( NULL ); } - /* Prepare subpicture */ - switch( i_type ) - { - case TEXT_SUBPICTURE: /* text subpicture */ - p_free_subpic->p_data = memalign( 16, i_size + 1 ); - break; - case DVD_SUBPICTURE: /* DVD subpicture unit */ - p_free_subpic->p_data = memalign( 16, i_size ); - break; - default: - intf_ErrMsg( "vout error: unknown subpicture type %d", i_type ); - p_free_subpic->p_data = NULL; - break; - } + p_free_subpic->p_sys = memalign( 16, i_size ); - if( p_free_subpic->p_data != NULL ) + if( p_free_subpic->p_sys != NULL ) { /* Copy subpicture information, set some default values */ p_free_subpic->i_type = i_type; @@ -209,61 +190,14 @@ void vout_DestroySubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic ) /***************************************************************************** * vout_RenderSubPictures: render a subpicture list ***************************************************************************** - * This function renders a sub picture unit. + * This function renders all sub picture units in the list. *****************************************************************************/ void vout_RenderSubPictures( vout_thread_t *p_vout, picture_t *p_pic, subpicture_t *p_subpic ) { -#if 0 - p_vout_font_t p_font; /* text font */ - int i_width, i_height; /* subpicture dimensions */ -#endif - while( p_subpic != NULL ) { - switch( p_subpic->i_type ) - { - case DVD_SUBPICTURE: /* DVD subpicture unit */ - vout_RenderSPU( p_vout, p_pic, p_subpic ); - break; - -#if 0 - case TEXT_SUBPICTURE: /* single line text */ - /* Select default font if not specified */ - p_font = p_subpic->type.text.p_font; - if( p_font == NULL ) - { - p_font = p_vout->p_default_font; - } - - /* Compute text size (width and height fields are ignored) - * and print it */ - vout_TextSize( p_font, p_subpic->type.text.i_style, - p_subpic->p_data, &i_width, &i_height ); - if( !Align( p_vout, &p_subpic->i_x, &p_subpic->i_y, - i_width, i_height, p_subpic->i_horizontal_align, - p_subpic->i_vertical_align ) ) - { - vout_Print( p_font, - p_vout->p_buffer[ p_vout->i_buffer_index ].p_data + - p_subpic->i_x * p_vout->i_bytes_per_pixel + - p_subpic->i_y * p_vout->i_bytes_per_line, - p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line, p_subpic->type.text.i_char_color, - p_subpic->type.text.i_border_color, - p_subpic->type.text.i_bg_color, - p_subpic->type.text.i_style, p_subpic->p_data, 100 ); - SetBufferArea( p_vout, p_subpic->i_x, p_subpic->i_y, - i_width, i_height ); - } - break; -#endif - - default: - intf_ErrMsg( "vout error: unknown subpicture %p type %d", - p_subpic, p_subpic->i_type ); - break; - } - + p_subpic->pf_render( p_vout, p_pic, p_subpic ); p_subpic = p_subpic->p_next; } } @@ -294,7 +228,7 @@ subpicture_t *vout_SortSubPictures( vout_thread_t *p_vout, if( p_vout->p_subpicture[i_index].i_status == READY_SUBPICTURE ) { /* If it is a DVD subpicture, check its date */ - if( p_vout->p_subpicture[i_index].i_type == DVD_SUBPICTURE ) + if( p_vout->p_subpicture[i_index].i_type == MEMORY_SUBPICTURE ) { if( display_date > p_vout->p_subpicture[i_index].i_stop ) { @@ -378,194 +312,3 @@ subpicture_t *vout_SortSubPictures( vout_thread_t *p_vout, return p_subpic; } -/***************************************************************************** - * vout_RenderSPU: draw an SPU on a picture - ***************************************************************************** - * This is a fast implementation of the subpicture drawing code. The data - * has been preprocessed once in spu_decoder.c, so we don't need to parse the - * RLE buffer again and again. Most sanity checks are done in spu_decoder.c - * so that this routine can be as fast as possible. - *****************************************************************************/ -static void vout_RenderSPU( const vout_thread_t *p_vout, picture_t *p_pic, - const subpicture_t *p_spu ) -{ - /* Common variables */ - u8 p_clut8[4], p_trsp[4]; - u16 p_clut16[4]; - u8 *p_dest; - u16 *p_source = (u16 *)p_spu->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; - - /* FIXME: get this from the DVD */ - p_trsp[0] = 0x00; p_trsp[1] = 0xff; p_trsp[2] = 0xff; p_trsp[3] = 0xff; - - switch( p_vout->output.i_chroma ) - { - /* I420 target, no scaling */ - case FOURCC_I420: - case FOURCC_IYUV: - case FOURCC_YV12: - - /* FIXME: get this from the DVD */ - p_clut8[0] = 0xaa; p_clut8[1] = 0x44; - p_clut8[2] = 0xff; p_clut8[3] = 0x88; - - 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_trsp[ i_color ] ) - { - case 0x00: - i_x -= *p_source++ >> 2; - break; - - case 0xff: - i_len = *p_source++ >> 2; - memset( p_dest - i_x - i_y, p_clut8[ i_color ], i_len ); - i_x -= i_len; - break; - - default: - /* FIXME: we should do transparency */ - i_len = *p_source++ >> 2; - memset( p_dest - i_x - i_y, p_clut8[ i_color ], i_len ); - i_x -= i_len; - break; - } - } - } - - break; - - /* RV16 target, scaling */ - case FOURCC_RV16: - - /* FIXME: get this from the DVD */ - p_clut16[0] = 0xaaaa; p_clut16[1] = 0x4444; - p_clut16[2] = 0xffff; p_clut16[3] = 0x8888; - - i_xscale = ( p_vout->output.i_width << 6 ) / p_vout->render.i_width; - i_yscale = ( p_vout->output.i_height << 6 ) / p_vout->render.i_height; - - i_width = p_spu->i_width * i_xscale; - i_height = p_spu->i_height * i_yscale; - - p_dest = p_pic->p->p_pixels + ( i_width >> 6 ) * 2 - /* Add the picture coordinates and the SPU coordinates */ - + ( (p_spu->i_x * i_xscale) >> 6 ) * 2 - + ( (p_spu->i_y * i_yscale) >> 6 ) * p_vout->output.i_width * 2; - - /* Draw until we reach the bottom of the subtitle */ - for( i_y = 0 ; i_y < i_height ; ) - { - i_ytmp = i_y >> 6; - i_y += i_yscale; - - /* Check whether we need to draw one line or more than one */ - if( i_ytmp + 1 >= ( i_y >> 6 ) ) - { - /* Just one line : we precalculate i_y >> 6 */ - i_yreal = p_vout->output.i_width * 2 * i_ytmp; - - /* Draw until we reach the end of the line */ - for( i_x = i_width ; i_x ; ) - { - /* Get the RLE part, then draw the line */ - i_color = *p_source & 0x3; - - switch( p_trsp[ i_color ] ) - { - case 0x00: - i_x -= i_xscale * ( *p_source++ >> 2 ); - break; - - case 0xff: - i_len = i_xscale * ( *p_source++ >> 2 ); - memset( p_dest - 2 * ( i_x >> 6 ) + i_yreal, - p_clut16[ i_color ], - 2 * ( ( i_len >> 6 ) + 1 ) ); - i_x -= i_len; - break; - - default: - /* FIXME: we should do transparency */ - i_len = i_xscale * ( *p_source++ >> 2 ); - memset( p_dest - 2 * ( i_x >> 6 ) + i_yreal, - p_clut16[ i_color ], - 2 * ( ( i_len >> 6 ) + 1 ) ); - i_x -= i_len; - break; - } - - } - } - else - { - i_yreal = p_vout->output.i_width * 2 * i_ytmp; - i_ynext = p_vout->output.i_width * 2 * i_y >> 6; - - /* Draw until we reach the end of the line */ - for( i_x = i_width ; i_x ; ) - { - /* Get the RLE part, then draw as many lines as needed */ - i_color = *p_source & 0x3; - - switch( p_trsp[ i_color ] ) - { - case 0x00: - i_x -= i_xscale * ( *p_source++ >> 2 ); - break; - - case 0xff: - i_len = i_xscale * ( *p_source++ >> 2 ); - for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; - i_ytmp += p_vout->output.i_width * 2 ) - { - memset( p_dest - 2 * ( i_x >> 6 ) + i_ytmp, - p_clut16[ i_color ], - 2 * ( ( i_len >> 6 ) + 1 ) ); - } - i_x -= i_len; - break; - - default: - /* FIXME: we should do transparency */ - i_len = i_xscale * ( *p_source++ >> 2 ); - for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; - i_ytmp += p_vout->output.i_width * 2 ) - { - memset( p_dest - 2 * ( i_x >> 6 ) + i_ytmp, - p_clut16[ i_color ], - 2 * ( ( i_len >> 6 ) + 1 ) ); - } - i_x -= i_len; - break; - } - } - } - } - - break; - - default: - intf_ErrMsg( "vout error: unknown chroma, can't render SPU" ); - break; - } -} -