From 7bb574fdf5724bee95a011cf96f33c95f1ff8645 Mon Sep 17 00:00:00 2001 From: Gildas Bazin Date: Tue, 2 Sep 2003 20:19:26 +0000 Subject: [PATCH] * ALL: Introduction of a new api for decoders. The final aim of this new api is to make it possible to use the decoders from other modules like the transcoder for instance. Only a few decoders have been ported to the new api (a52, libmpeg2, dts, vorbis, theora) so the old api is still supported. Don't hold your breath, there is still much work to do before we reach this goal. * modules/codec/a52.c, libmpeg2., dts.c, vorbis.c, theora.c: Converted to the new api. Merged the a52 and vorbis packetizers in their respective decoders (removes a lot of code duplication). New dts and theora packetizers (merged in their respective decoders). --- configure.ac | 10 +- include/input_ext-dec.h | 25 +- include/vlc/decoder.h | 3 +- include/vlc/input.h | 3 +- include/vlc/sout.h | 3 +- include/vlc_block.h | 11 +- include/vlc_common.h | 4 +- include/vlc_objects.h | 4 +- modules/codec/a52.c | 609 +++++++++++++++++++++-------- modules/codec/adpcm.c | 11 +- modules/codec/araw.c | 9 +- modules/codec/cinepak/cinepak.c | 10 +- modules/codec/dts.c | 674 +++++++++++++++++++++++--------- modules/codec/dv.c | 8 +- modules/codec/faad/decoder.c | 9 +- modules/codec/ffmpeg/ffmpeg.c | 14 +- modules/codec/flacdec.c | 8 +- modules/codec/libmpeg2.c | 531 ++++++++++++------------- modules/codec/lpcm.c | 10 +- modules/codec/mpeg_audio.c | 8 +- modules/codec/quicktime.c | 10 +- modules/codec/rawvideo.c | 9 +- modules/codec/spudec/spudec.c | 11 +- modules/codec/subsdec/subsdec.c | 8 +- modules/codec/tarkin.c | 8 +- modules/codec/theora.c | 493 +++++++++++++++-------- modules/codec/vorbis.c | 537 ++++++++++++++++--------- modules/codec/xvid.c | 13 +- modules/demux/ogg.c | 4 +- modules/misc/dummy/decoder.c | 4 +- modules/packetizer/Modules.am | 2 - modules/packetizer/a52.c | 377 ------------------ modules/packetizer/copy.c | 7 +- modules/packetizer/mpeg4audio.c | 9 +- modules/packetizer/mpeg4video.c | 9 +- modules/packetizer/mpegaudio.c | 8 +- modules/packetizer/mpegvideo.c | 12 +- modules/packetizer/vorbis.c | 376 ------------------ src/input/input_dec.c | 236 +++++++---- src/misc/block.c | 50 +-- src/misc/objects.c | 6 +- 41 files changed, 2219 insertions(+), 1934 deletions(-) delete mode 100644 modules/packetizer/a52.c delete mode 100644 modules/packetizer/vorbis.c diff --git a/configure.ac b/configure.ac index 9617bf2976..604efdeab1 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ dnl Autoconf settings for vlc -dnl $Id: configure.ac,v 1.71 2003/08/31 15:55:56 titer Exp $ +dnl $Id: configure.ac,v 1.72 2003/09/02 20:19:25 gbazin Exp $ AC_INIT(vlc,0.6.3-cvs) @@ -1000,7 +1000,7 @@ if test "${enable_sout}" != "no" then AX_ADD_PLUGINS([access_output_dummy access_output_udp access_output_file access_output_http]) AX_ADD_PLUGINS([mux_ts mux_ps mux_avi mux_mp4 mux_asf mux_dummy]) - AX_ADD_PLUGINS([packetizer_mpegaudio packetizer_mpegvideo packetizer_a52]) + AX_ADD_PLUGINS([packetizer_mpegaudio packetizer_mpegvideo]) AX_ADD_PLUGINS([packetizer_mpeg4video packetizer_mpeg4audio]) AX_ADD_PLUGINS([packetizer_copy]) @@ -1934,11 +1934,7 @@ if test "${enable_vorbis}" != "no" then AC_CHECK_HEADERS(vorbis/codec.h, [ AX_ADD_PLUGINS([vorbis]) - AX_ADD_LDFLAGS([vorbis],[-lvorbis -logg]) - if test "${enable_sout}" != "no"; then - AX_ADD_PLUGINS([packetizer_vorbis]) - AX_ADD_LDFLAGS([packetizer_vorbis],[-lvorbis -logg]) - fi ],[]) + AX_ADD_LDFLAGS([vorbis],[-lvorbis -logg]) ],[]) fi dnl diff --git a/include/input_ext-dec.h b/include/input_ext-dec.h index 75e3e06556..12c8ceadb4 100644 --- a/include/input_ext-dec.h +++ b/include/input_ext-dec.h @@ -2,7 +2,7 @@ * input_ext-dec.h: structures exported to the VideoLAN decoders ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: input_ext-dec.h,v 1.79 2003/03/04 13:21:19 massiot Exp $ + * $Id: input_ext-dec.h,v 1.80 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Christophe Massiot * Michel Kaempf @@ -110,8 +110,29 @@ struct decoder_fifo_t void * p_waveformatex; void * p_bitmapinfoheader; + decoder_t * p_dec; +}; + +/***************************************************************************** + * decoder_t + ***************************************************************************** + * The decoder descriptor. + *****************************************************************************/ +struct decoder_t +{ + VLC_COMMON_MEMBERS + /* Module properties */ - module_t * p_module; + module_t * p_module; + decoder_sys_t * p_sys; + int ( * pf_init ) ( decoder_t * ); + int ( * pf_decode )( decoder_t *, block_t * ); + int ( * pf_end ) ( decoder_t * ); + + /* Input properties */ + decoder_fifo_t * p_fifo; /* stores the PES stream data */ + + /* Tmp field for old decoder api */ int ( * pf_run ) ( decoder_fifo_t * ); }; diff --git a/include/vlc/decoder.h b/include/vlc/decoder.h index 473d81205d..e6b98a684d 100644 --- a/include/vlc/decoder.h +++ b/include/vlc/decoder.h @@ -2,7 +2,7 @@ * decoder.h: header for vlc decoders ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: decoder.h,v 1.1 2002/06/01 12:31:58 sam Exp $ + * $Id: decoder.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $ * * 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 @@ -34,6 +34,7 @@ extern "C" { /***************************************************************************** * Required internal headers *****************************************************************************/ +#include "vlc_block.h" #include "stream_control.h" #include "input_ext-dec.h" diff --git a/include/vlc/input.h b/include/vlc/input.h index 2f3f7b1c7f..cc122968e4 100644 --- a/include/vlc/input.h +++ b/include/vlc/input.h @@ -2,7 +2,7 @@ * input.h: input modules header for vlc ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: input.h,v 1.1 2002/06/01 12:31:58 sam Exp $ + * $Id: input.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $ * * 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 @@ -34,6 +34,7 @@ extern "C" { /***************************************************************************** * Required internal headers *****************************************************************************/ +#include "vlc_block.h" #include "stream_control.h" #include "input_ext-intf.h" /* input_thread_s */ #include "input_ext-dec.h" /* data_packet_s */ diff --git a/include/vlc/sout.h b/include/vlc/sout.h index a01adb1c96..319ffba27a 100644 --- a/include/vlc/sout.h +++ b/include/vlc/sout.h @@ -2,7 +2,7 @@ * sout.h: video output header for vlc ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: sout.h,v 1.2 2003/05/20 16:20:33 zorglub Exp $ + * $Id: sout.h,v 1.3 2003/09/02 20:19:25 gbazin Exp $ * * 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 @@ -34,6 +34,7 @@ extern "C" { /***************************************************************************** * Required internal headers *****************************************************************************/ +#include "vlc_block.h" #include "stream_output.h" # ifdef __cplusplus diff --git a/include/vlc_block.h b/include/vlc_block.h index ea3ccfadfe..c453a24985 100644 --- a/include/vlc_block.h +++ b/include/vlc_block.h @@ -1,8 +1,8 @@ /***************************************************************************** - * block.h + * vlc_block.h: Data blocks management functions ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: vlc_block.h,v 1.1 2003/08/23 22:49:50 fenrir Exp $ + * $Id: vlc_block.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * @@ -21,9 +21,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ -#ifndef _BLOCK_H -#define _BLOCK_H 1 - +#ifndef _VLC_BLOCK_H +#define _VLC_BLOCK_H 1 /* * block @@ -108,4 +107,4 @@ VLC_EXPORT( block_t *, block_FifoGet, ( block_fifo_t * ) ); VLC_EXPORT( block_t *, block_FifoGetFrame, ( block_fifo_t * ) ); VLC_EXPORT( block_t *, block_FifoShow, ( block_fifo_t * ) ); -#endif +#endif /* VLC_BLOCK_H */ diff --git a/include/vlc_common.h b/include/vlc_common.h index 8bfceced67..f010ce7a0e 100644 --- a/include/vlc_common.h +++ b/include/vlc_common.h @@ -3,7 +3,7 @@ * Collection of useful common types and macros definitions ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: vlc_common.h,v 1.75 2003/08/23 22:49:50 fenrir Exp $ + * $Id: vlc_common.h,v 1.76 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Samuel Hocevar * Vincent Seguin @@ -268,6 +268,8 @@ typedef struct slp_session_t slp_session_t;*/ /* Decoders */ typedef struct decoder_fifo_t decoder_fifo_t; +typedef struct decoder_t decoder_t; +typedef struct decoder_sys_t decoder_sys_t; /* Misc */ typedef struct data_packet_t data_packet_t; diff --git a/include/vlc_objects.h b/include/vlc_objects.h index f1e4757e9c..d2954db549 100644 --- a/include/vlc_objects.h +++ b/include/vlc_objects.h @@ -2,7 +2,7 @@ * vlc_objects.h: vlc_object_t definition. ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: vlc_objects.h,v 1.16 2003/02/23 19:07:02 fenrir Exp $ + * $Id: vlc_objects.h,v 1.17 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -30,6 +30,8 @@ #define VLC_OBJECT_ITEM (-6) #define VLC_OBJECT_INPUT (-7) #define VLC_OBJECT_DECODER (-8) +/* tmp for backward compat */ +#define VLC_OBJECT_DECODER_FIFO (-999) #define VLC_OBJECT_VOUT (-9) #define VLC_OBJECT_AOUT (-10) #define VLC_OBJECT_SOUT (-11) diff --git a/modules/codec/a52.c b/modules/codec/a52.c index e2a8e68eb8..0a1a424f5f 100644 --- a/modules/codec/a52.c +++ b/modules/codec/a52.c @@ -2,12 +2,11 @@ * a52.c: A/52 basic parser ***************************************************************************** * Copyright (C) 2001-2002 VideoLAN - * $Id: a52.c,v 1.22 2003/03/31 22:39:27 massiot Exp $ + * $Id: a52.c,v 1.23 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Stéphane Borel * Christophe Massiot - * Michel Lespinasse - * Aaron Holtzman + * Gildas Bazin * * 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 @@ -34,45 +33,85 @@ #include #include +#include #include +#include #ifdef HAVE_UNISTD_H # include #endif +#define A52_HEADER_SIZE 7 + /***************************************************************************** - * dec_thread_t : decoder thread descriptor + * decoder_sys_t : decoder descriptor *****************************************************************************/ -typedef struct dec_thread_t +struct decoder_sys_t { + /* Module mode */ + vlc_bool_t b_packetizer; + /* - * Thread properties + * Input properties */ - vlc_thread_t thread_id; /* id for thread functions */ + int i_state; + + uint8_t p_header[A52_HEADER_SIZE]; + int i_header; + + mtime_t pts; + + int i_frame_size; /* - * Input properties + * Decoder output properties + */ + aout_instance_t * p_aout; /* opaque */ + aout_input_t * p_aout_input; /* opaque */ + audio_sample_format_t aout_format; + + aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */ + + /* + * Packetizer output properties */ - decoder_fifo_t * p_fifo; /* stores the PES stream data */ - bit_stream_t bit_stream; + sout_packetizer_input_t *p_sout_input; + sout_format_t sout_format; + sout_buffer_t * p_sout_buffer; /* current sout buffer */ /* - * Output properties + * Common properties */ - aout_instance_t * p_aout; /* opaque */ - aout_input_t * p_aout_input; /* opaque */ - audio_sample_format_t output_format; -} dec_thread_t; + uint8_t *p_out_buffer; /* output buffer */ + int i_out_buffer; /* position in output buffer */ + audio_date_t end_date; +}; + +enum { + + STATE_NOSYNC, + STATE_PARTIAL_SYNC, + STATE_SYNC, + STATE_HEADER, + STATE_DATA +}; /**************************************************************************** * Local prototypes ****************************************************************************/ -static int OpenDecoder ( vlc_object_t * ); -static int RunDecoder ( decoder_fifo_t * ); +static int OpenDecoder ( vlc_object_t * ); +static int OpenPacketizer( vlc_object_t * ); + +static int InitDecoder ( decoder_t * ); +static int RunDecoder ( decoder_t *, block_t * ); +static int EndDecoder ( decoder_t * ); -static void EndThread ( dec_thread_t * ); +static int SyncInfo ( const byte_t *, int *, int *, int *,int * ); -static int SyncInfo ( const byte_t *, int *, int *, int * ); +static int GetOutBuffer ( decoder_t *, uint8_t ** ); +static int GetAoutBuffer( decoder_t *, aout_buffer_t ** ); +static int GetSoutBuffer( decoder_t *, sout_buffer_t ** ); +static int SendOutBuffer( decoder_t * ); /***************************************************************************** * Module descriptor @@ -81,6 +120,11 @@ vlc_module_begin(); set_description( _("A/52 parser") ); set_capability( "decoder", 100 ); set_callbacks( OpenDecoder, NULL ); + + add_submodule(); + set_description( _("A/52 audio packetizer") ); + set_capability( "packetizer", 10 ); + set_callbacks( OpenPacketizer, NULL ); vlc_module_end(); /***************************************************************************** @@ -88,15 +132,62 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; + + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ') + && p_dec->p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') ) + { + return VLC_EGENERIC; + } - if( p_fifo->i_fourcc != VLC_FOURCC('a','5','2',' ') - && p_fifo->i_fourcc != VLC_FOURCC('a','5','2','b') ) + p_dec->pf_init = InitDecoder; + p_dec->pf_decode = RunDecoder; + p_dec->pf_end = EndDecoder; + + /* Allocate the memory needed to store the decoder's structure */ + if( ( p_dec->p_sys = + (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) { + msg_Err( p_dec, "out of memory" ); return VLC_EGENERIC; } + p_dec->p_sys->b_packetizer = VLC_FALSE; + + return VLC_SUCCESS; +} + +static int OpenPacketizer( vlc_object_t *p_this ) +{ + decoder_t *p_dec = (decoder_t*)p_this; + + int i_ret = OpenDecoder( p_this ); + + if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE; + + return i_ret; +} + +/***************************************************************************** + * InitDecoder: Initalize the decoder + *****************************************************************************/ +static int InitDecoder( decoder_t *p_dec ) +{ + p_dec->p_sys->i_state = STATE_NOSYNC; + + p_dec->p_sys->p_out_buffer = NULL; + p_dec->p_sys->i_out_buffer = 0; + aout_DateSet( &p_dec->p_sys->end_date, 0 ); + + p_dec->p_sys->p_aout = NULL; + p_dec->p_sys->p_aout_input = NULL; + p_dec->p_sys->p_aout_buffer = NULL; + p_dec->p_sys->aout_format.i_format = VLC_FOURCC('a','5','2',' '); + + p_dec->p_sys->p_sout_input = NULL; + p_dec->p_sys->p_sout_buffer = NULL; + p_dec->p_sys->sout_format.i_cat = AUDIO_ES; + p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' ); - p_fifo->pf_run = RunDecoder; return VLC_SUCCESS; } @@ -105,167 +196,350 @@ static int OpenDecoder( vlc_object_t *p_this ) **************************************************************************** * This function is called just after the thread is launched. ****************************************************************************/ -static int RunDecoder( decoder_fifo_t *p_fifo ) +static int RunDecoder( decoder_t *p_dec, block_t *p_block ) { - dec_thread_t * p_dec; - audio_date_t end_date; + decoder_sys_t *p_sys = p_dec->p_sys; + int i_block_pos = 0; + mtime_t i_pts = p_block->i_pts; - /* Allocate the memory needed to store the thread's structure */ - p_dec = malloc( sizeof(dec_thread_t) ); - if( p_dec == NULL ) + while( i_block_pos < p_block->i_buffer ) { - msg_Err( p_fifo, "out of memory" ); - DecoderError( p_fifo ); - return -1; - } + switch( p_sys->i_state ) + { + case STATE_NOSYNC: + /* Look for sync word - should be 0x0b77 */ + while( i_block_pos < p_block->i_buffer && + p_block->p_buffer[i_block_pos] != 0x0b ) + { + i_block_pos++; + } - /* Initialize the thread properties */ - p_dec->p_aout = NULL; - p_dec->p_aout_input = NULL; - p_dec->p_fifo = p_fifo; - p_dec->output_format.i_format = VLC_FOURCC('a','5','2',' '); + if( i_block_pos < p_block->i_buffer ) + { + p_sys->i_state = STATE_PARTIAL_SYNC; + i_block_pos++; + p_sys->p_header[0] = 0x0b; + break; + } + break; - aout_DateSet( &end_date, 0 ); + case STATE_PARTIAL_SYNC: + if( p_block->p_buffer[i_block_pos] == 0x77 ) + { + p_sys->i_state = STATE_SYNC; + i_block_pos++; + p_sys->p_header[1] = 0x77; + p_sys->i_header = 2; + } + else + { + p_sys->i_state = STATE_NOSYNC; + } + break; - /* Init the bitstream */ - if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, - NULL, NULL ) != VLC_SUCCESS ) - { - msg_Err( p_fifo, "cannot initialize bitstream" ); - DecoderError( p_fifo ); - free( p_dec ); - return -1; + case STATE_SYNC: + /* New frame, set the Presentation Time Stamp */ + p_sys->pts = i_pts; i_pts = 0; + if( p_sys->pts != 0 && + p_sys->pts != aout_DateGet( &p_sys->end_date ) ) + { + aout_DateSet( &p_sys->end_date, p_sys->pts ); + } + p_sys->i_state = STATE_HEADER; + break; + + case STATE_HEADER: + /* Get A/52 frame header (A52_HEADER_SIZE bytes) */ + if( p_sys->i_header < A52_HEADER_SIZE ) + { + int i_size = __MIN( A52_HEADER_SIZE - p_sys->i_header, + p_block->i_buffer - i_block_pos ); + + memcpy( p_sys->p_header + p_sys->i_header, + p_block->p_buffer + i_block_pos, i_size ); + i_block_pos += i_size; + p_sys->i_header += i_size; + } + + if( p_sys->i_header < A52_HEADER_SIZE ) + break; + + if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) + != VLC_SUCCESS ) + { + block_Release( p_block ); + return VLC_EGENERIC; + } + + if( !p_sys->p_out_buffer ) + { + p_sys->i_state = STATE_NOSYNC; + break; + } + + memcpy( p_sys->p_out_buffer, p_sys->p_header, A52_HEADER_SIZE ); + p_sys->i_out_buffer = A52_HEADER_SIZE; + p_sys->i_state = STATE_DATA; + break; + + case STATE_DATA: + /* Copy the whole A52 frame into the aout buffer */ + if( p_sys->i_out_buffer < p_sys->i_frame_size ) + { + int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer, + p_block->i_buffer - i_block_pos ); + + memcpy( p_sys->p_out_buffer + p_sys->i_out_buffer, + p_block->p_buffer + i_block_pos, i_size ); + i_block_pos += i_size; + p_sys->i_out_buffer += i_size; + } + + if( p_sys->i_out_buffer < p_sys->i_frame_size ) + break; /* Need more data */ + + SendOutBuffer( p_dec ); + + p_sys->i_state = STATE_NOSYNC; + break; + } } - /* Decoder thread's main loop */ - while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error ) + block_Release( p_block ); + return VLC_SUCCESS; +} + +/***************************************************************************** + * EndDecoder: clean up the decoder + *****************************************************************************/ +static int EndDecoder( decoder_t *p_dec ) +{ + if( p_dec->p_sys->p_aout_input != NULL ) { - int i_bit_rate; - unsigned int i_rate, i_original_channels, i_frame_size; - mtime_t pts; - byte_t p_header[7]; - aout_buffer_t * p_buffer; - - /* Look for sync word - should be 0x0b77 */ - RealignBits( &p_dec->bit_stream ); - while ( (ShowBits( &p_dec->bit_stream, 16 ) ) != 0x0b77 && - (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) ) + if( p_dec->p_sys->p_aout_buffer ) { - RemoveBits( &p_dec->bit_stream, 8 ); + aout_DecDeleteBuffer( p_dec->p_sys->p_aout, + p_dec->p_sys->p_aout_input, + p_dec->p_sys->p_aout_buffer ); } - if ( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break; - /* Set the Presentation Time Stamp */ - NextPTS( &p_dec->bit_stream, &pts, NULL ); - if ( pts != 0 && pts != aout_DateGet( &end_date ) ) + aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input ); + } + + if( p_dec->p_sys->p_sout_input != NULL ) + { + if( p_dec->p_sys->p_sout_buffer ) { - aout_DateSet( &end_date, pts ); + sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout, + p_dec->p_sys->p_sout_buffer ); } - /* Get A/52 frame header */ - GetChunk( &p_dec->bit_stream, p_header, 7 ); - if ( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break; + sout_InputDelete( p_dec->p_sys->p_sout_input ); + } - /* Check if frame is valid and get frame info */ - i_frame_size = SyncInfo( p_header, &i_original_channels, &i_rate, - &i_bit_rate ); + free( p_dec->p_sys ); - if( !i_frame_size ) - { - msg_Warn( p_dec->p_fifo, "a52_syncinfo failed" ); - continue; - } + return VLC_SUCCESS; +} - if( (p_dec->p_aout_input != NULL) && - ( (p_dec->output_format.i_rate != i_rate) - || (p_dec->output_format.i_original_channels - != i_original_channels) - || (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) ) - { - /* Parameters changed - this should not happen. */ - aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input ); - p_dec->p_aout_input = NULL; - } +/***************************************************************************** + * GetOutBuffer: + *****************************************************************************/ +static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + int i_ret; - /* Creating the audio input if not created yet. */ - if( p_dec->p_aout_input == NULL ) - { - p_dec->output_format.i_rate = i_rate; - p_dec->output_format.i_original_channels = i_original_channels; - p_dec->output_format.i_physical_channels - = i_original_channels & AOUT_CHAN_PHYSMASK; - p_dec->output_format.i_bytes_per_frame = i_frame_size; - p_dec->output_format.i_frame_length = A52_FRAME_NB; - aout_DateInit( &end_date, i_rate ); - aout_DateSet( &end_date, pts ); - p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo, - &p_dec->p_aout, - &p_dec->output_format ); - - if ( p_dec->p_aout_input == NULL ) - { - p_dec->p_fifo->b_error = 1; - break; - } - } + if( p_sys->b_packetizer ) + { + i_ret= GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ); + *pp_out_buffer = + p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL; + } + else + { + i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer ); + *pp_out_buffer = + p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer : NULL; + } - if ( !aout_DateGet( &end_date ) ) - { - byte_t p_junk[3840]; + return i_ret; +} - /* We've just started the stream, wait for the first PTS. */ - GetChunk( &p_dec->bit_stream, p_junk, i_frame_size - 7 ); - continue; - } +/***************************************************************************** + * GetAoutBuffer: + *****************************************************************************/ +static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer ) +{ + int i_bit_rate; + unsigned int i_rate, i_channels, i_channels_conf; - p_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input, - A52_FRAME_NB ); - if ( p_buffer == NULL ) + decoder_sys_t *p_sys = p_dec->p_sys; + + /* Check if frame is valid and get frame info */ + p_sys->i_frame_size = SyncInfo( p_sys->p_header, + &i_channels, &i_channels_conf, + &i_rate, &i_bit_rate ); + + if( !p_sys->i_frame_size ) + { + msg_Warn( p_dec, "a52 syncinfo failed" ); + *pp_buffer = NULL; + return VLC_SUCCESS; + } + + if( p_sys->p_aout_input != NULL && ( p_sys->aout_format.i_rate != i_rate + || p_sys->aout_format.i_original_channels != i_channels_conf + || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) ) + { + /* Parameters changed - this should not happen. */ + aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input ); + p_sys->p_aout_input = NULL; + } + + /* Creating the audio input if not created yet. */ + if( p_sys->p_aout_input == NULL ) + { + p_sys->aout_format.i_rate = i_rate; + p_sys->aout_format.i_original_channels = i_channels_conf; + p_sys->aout_format.i_physical_channels + = i_channels_conf & AOUT_CHAN_PHYSMASK; + p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size; + p_sys->aout_format.i_frame_length = A52_FRAME_NB; + aout_DateInit( &p_sys->end_date, i_rate ); + aout_DateSet( &p_sys->end_date, p_sys->pts ); + p_sys->p_aout_input = aout_DecNew( p_dec, + &p_sys->p_aout, + &p_sys->aout_format ); + + if ( p_sys->p_aout_input == NULL ) { - p_dec->p_fifo->b_error = 1; - break; + *pp_buffer = NULL; + return VLC_SUCCESS; } - p_buffer->start_date = aout_DateGet( &end_date ); - p_buffer->end_date = aout_DateIncrement( &end_date, - A52_FRAME_NB ); - - /* Get the whole frame. */ - memcpy( p_buffer->p_buffer, p_header, 7 ); - GetChunk( &p_dec->bit_stream, p_buffer->p_buffer + 7, - i_frame_size - 7 ); - if( p_dec->p_fifo->b_die ) + } + + if( !aout_DateGet( &p_sys->end_date ) ) + { + /* We've just started the stream, wait for the first PTS. */ + *pp_buffer = NULL; + return VLC_SUCCESS; + } + + *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input, + A52_FRAME_NB ); + if( *pp_buffer == NULL ) + { + return VLC_SUCCESS; + } + + (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date ); + (*pp_buffer)->end_date = + aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ); + + return VLC_SUCCESS; +} + +/***************************************************************************** + * GetSoutBuffer: + *****************************************************************************/ +static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer ) +{ + int i_bit_rate; + unsigned int i_rate, i_channels, i_channels_conf; + + decoder_sys_t *p_sys = p_dec->p_sys; + + /* Check if frame is valid and get frame info */ + p_sys->i_frame_size = SyncInfo( p_sys->p_header, + &i_channels, &i_channels_conf, + &i_rate, &i_bit_rate ); + + if( !p_sys->i_frame_size ) + { + msg_Warn( p_dec, "a52 syncinfo failed" ); + *pp_buffer = NULL; + return VLC_SUCCESS; + } + + if( p_sys->p_sout_input != NULL && + ( p_sys->sout_format.i_sample_rate != (int)i_rate + || p_sys->sout_format.i_channels != (int)i_channels ) ) + { + /* Parameters changed - this should not happen. */ + } + + /* Creating the sout input if not created yet. */ + if( p_sys->p_sout_input == NULL ) + { + p_sys->sout_format.i_sample_rate = i_rate; + p_sys->sout_format.i_channels = i_channels; + p_sys->sout_format.i_block_align = 0; + p_sys->sout_format.i_bitrate = i_bit_rate; + p_sys->sout_format.i_extra_data = 0; + p_sys->sout_format.p_extra_data = NULL; + + aout_DateInit( &p_sys->end_date, i_rate ); + aout_DateSet( &p_sys->end_date, p_sys->pts ); + + p_sys->p_sout_input = sout_InputNew( p_dec, + &p_sys->sout_format ); + + if( p_sys->p_sout_input == NULL ) { - aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input, - p_buffer ); - break; + msg_Err( p_dec, "cannot add a new stream" ); + *pp_buffer = NULL; + return VLC_EGENERIC; } + msg_Info( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d", + i_channels, i_rate, i_bit_rate ); + } - /* Send the buffer to the aout core. */ - aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer ); + if( !aout_DateGet( &p_sys->end_date ) ) + { + /* We've just started the stream, wait for the first PTS. */ + *pp_buffer = NULL; + return VLC_SUCCESS; } - if( p_dec->p_fifo->b_error ) + *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout, + p_sys->i_frame_size ); + if( *pp_buffer == NULL ) { - DecoderError( p_dec->p_fifo ); + return VLC_SUCCESS; } - EndThread( p_dec ); + (*pp_buffer)->i_pts = + (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date ); + + (*pp_buffer)->i_length = + aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) + - (*pp_buffer)->i_pts; - return 0; + return VLC_SUCCESS; } /***************************************************************************** - * EndThread : thread destruction + * SendOutBuffer: *****************************************************************************/ -static void EndThread( dec_thread_t * p_dec ) +static int SendOutBuffer( decoder_t *p_dec ) { - if ( p_dec->p_aout_input != NULL ) + decoder_sys_t *p_sys = p_dec->p_sys; + + if( p_sys->b_packetizer ) + { + sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer ); + p_sys->p_sout_buffer = NULL; + } + else { - aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input ); + /* We have all we need, send the buffer to the aout core. */ + aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, + p_sys->p_aout_buffer ); + p_sys->p_aout_buffer = NULL; } - CloseBitstream( &p_dec->bit_stream ); - free( p_dec ); + return VLC_SUCCESS; } /***************************************************************************** @@ -275,7 +549,8 @@ static void EndThread( dec_thread_t * p_dec ) * since we don't want to oblige S/PDIF people to use liba52 just to get * their SyncInfo... *****************************************************************************/ -static int SyncInfo( const byte_t * p_buf, int * pi_channels, +static int SyncInfo( const byte_t * p_buf, + int * pi_channels, int * pi_channels_conf, int * pi_sample_rate, int * pi_bit_rate ) { static const uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 }; @@ -301,52 +576,67 @@ static int SyncInfo( const byte_t * p_buf, int * pi_channels, if ( (p_buf[6] & 0xf8) == 0x50 ) { /* Dolby surround = stereo + Dolby */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT - | AOUT_CHAN_DOLBYSTEREO; + *pi_channels = 2; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT + | AOUT_CHAN_DOLBYSTEREO; } else switch ( acmod ) { case 0x0: /* Dual-mono = stereo + dual-mono */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT - | AOUT_CHAN_DUALMONO; + *pi_channels = 2; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT + | AOUT_CHAN_DUALMONO; break; case 0x1: /* Mono */ - *pi_channels = AOUT_CHAN_CENTER; + *pi_channels = 1; + *pi_channels_conf = AOUT_CHAN_CENTER; break; case 0x2: /* Stereo */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; + *pi_channels = 2; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; break; case 0x3: /* 3F */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER; + *pi_channels = 3; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT + | AOUT_CHAN_CENTER; break; case 0x4: /* 2F1R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER; + *pi_channels = 3; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT + | AOUT_CHAN_REARCENTER; break; case 0x5: /* 3F1R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER - | AOUT_CHAN_REARCENTER; + *pi_channels = 4; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER + | AOUT_CHAN_REARCENTER; break; case 0x6: /* 2F2R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT - | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; + *pi_channels = 4; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT + | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; break; case 0x7: /* 3F2R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER - | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; + *pi_channels = 5; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER + | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; break; default: return 0; } - if ( p_buf[6] & lfeon[acmod] ) *pi_channels |= AOUT_CHAN_LFE; + if ( p_buf[6] & lfeon[acmod] ) + { + (*pi_channels)++; + *pi_channels_conf |= AOUT_CHAN_LFE; + } frmsizecod = p_buf[4] & 63; if (frmsizecod >= 38) @@ -368,4 +658,3 @@ static int SyncInfo( const byte_t * p_buf, int * pi_channels, return 0; } } - diff --git a/modules/codec/adpcm.c b/modules/codec/adpcm.c index 16e092b089..b3aed5bdc8 100644 --- a/modules/codec/adpcm.c +++ b/modules/codec/adpcm.c @@ -2,7 +2,7 @@ * adpcm.c : adpcm variant audio decoder ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: adpcm.c,v 1.12 2003/08/17 23:02:51 fenrir Exp $ + * $Id: adpcm.c,v 1.13 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * @@ -151,9 +151,9 @@ static int i_adaptation_coeff2[7] = *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - switch( p_fifo->i_fourcc ) + switch( p_dec->p_fifo->i_fourcc ) { case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */ case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */ @@ -161,13 +161,12 @@ static int OpenDecoder( vlc_object_t *p_this ) case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */ case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */ - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; default: return VLC_EGENERIC; } - } /***************************************************************************** @@ -874,5 +873,3 @@ static void DecodeAdpcmDk3( adec_thread_t *p_adec, } } - - diff --git a/modules/codec/araw.c b/modules/codec/araw.c index d6a3d7227e..4695178629 100644 --- a/modules/codec/araw.c +++ b/modules/codec/araw.c @@ -2,7 +2,7 @@ * araw.c: Pseudo audio decoder; for raw pcm data ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: araw.c,v 1.16 2003/08/17 23:02:51 fenrir Exp $ + * $Id: araw.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * @@ -80,9 +80,9 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - switch( p_fifo->i_fourcc ) + switch( p_dec->p_fifo->i_fourcc ) { case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */ case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/ @@ -90,13 +90,12 @@ static int OpenDecoder( vlc_object_t *p_this ) case VLC_FOURCC('a','l','a','w'): case VLC_FOURCC('u','l','a','w'): - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; default: return VLC_EGENERIC; } - } static int pi_channels_maps[6] = diff --git a/modules/codec/cinepak/cinepak.c b/modules/codec/cinepak/cinepak.c index 6fb5a8cc4f..4ae778102a 100644 --- a/modules/codec/cinepak/cinepak.c +++ b/modules/codec/cinepak/cinepak.c @@ -2,7 +2,7 @@ * cinepak.c: cinepak video decoder ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: cinepak.c,v 1.11 2003/08/17 23:02:51 fenrir Exp $ + * $Id: cinepak.c,v 1.12 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * @@ -70,13 +70,13 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - switch( p_fifo->i_fourcc ) + switch( p_dec->p_fifo->i_fourcc ) { case VLC_FOURCC('c','v','i','d'): case VLC_FOURCC('C','V','I','D'): - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } @@ -834,5 +834,3 @@ static void EndThread( videodec_thread_t *p_vdec ) free( p_vdec ); } - - diff --git a/modules/codec/dts.c b/modules/codec/dts.c index 9c54c32230..84e41ed2e2 100644 --- a/modules/codec/dts.c +++ b/modules/codec/dts.c @@ -2,9 +2,10 @@ * dts.c: DTS basic parser ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: dts.c,v 1.3 2003/03/18 00:25:27 jlj Exp $ + * $Id: dts.c,v 1.4 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Jon Lech Johansen + * Gildas Bazin * * 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 @@ -31,47 +32,88 @@ #include #include +#include #include +#include #ifdef HAVE_UNISTD_H # include #endif +#define DTS_HEADER_SIZE 10 + /***************************************************************************** - * dec_thread_t : decoder thread descriptor + * decoder_sys_t : decoder descriptor *****************************************************************************/ -typedef struct dec_thread_t +struct decoder_sys_t { + /* Module mode */ + vlc_bool_t b_packetizer; + /* - * Thread properties + * Input properties */ - vlc_thread_t thread_id; /* id for thread functions */ + int i_state; + + uint8_t p_header[DTS_HEADER_SIZE]; + int i_header; + + mtime_t pts; + + int i_frame_size; /* - * Input properties + * Decoder output properties */ - decoder_fifo_t * p_fifo; /* stores the PES stream data */ - bit_stream_t bit_stream; + aout_instance_t * p_aout; /* opaque */ + aout_input_t * p_aout_input; /* opaque */ + audio_sample_format_t aout_format; + aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */ + /* This is very hacky. For DTS over S/PDIF we apparently need to send + * 3 frames at a time. This should likely be moved to the output stage. */ + int i_frames_in_buf; /* - * Output properties + * Packetizer output properties */ - aout_instance_t * p_aout; /* opaque */ - aout_input_t * p_aout_input; /* opaque */ - audio_sample_format_t output_format; -} dec_thread_t; + sout_packetizer_input_t *p_sout_input; + sout_format_t sout_format; + sout_buffer_t * p_sout_buffer; /* current sout buffer */ + + /* + * Common properties + */ + uint8_t *p_out_buffer; /* output buffer */ + int i_out_buffer; /* position in output buffer */ + audio_date_t end_date; +}; + +enum { + + STATE_NOSYNC, + STATE_PARTIAL_SYNC, + STATE_SYNC, + STATE_HEADER, + STATE_DATA +}; /**************************************************************************** * Local prototypes ****************************************************************************/ -static int OpenDecoder ( vlc_object_t * ); -static int RunDecoder ( decoder_fifo_t * ); +static int OpenDecoder ( vlc_object_t * ); +static int OpenPacketizer( vlc_object_t * ); + +static int InitDecoder ( decoder_t * ); +static int RunDecoder ( decoder_t *, block_t * ); +static int EndDecoder ( decoder_t * ); -static void EndThread ( dec_thread_t * ); +static int SyncInfo ( const byte_t *, unsigned int *, unsigned int *, + unsigned int *, unsigned int *, unsigned int * ); -static int SyncInfo ( const byte_t *, unsigned int *, - unsigned int *, unsigned int *, - unsigned int * ); +static int GetOutBuffer ( decoder_t *, uint8_t ** ); +static int GetAoutBuffer( decoder_t *, aout_buffer_t ** ); +static int GetSoutBuffer( decoder_t *, sout_buffer_t ** ); +static int SendOutBuffer( decoder_t * ); /***************************************************************************** * Module descriptor @@ -80,6 +122,11 @@ vlc_module_begin(); set_description( _("DTS parser") ); set_capability( "decoder", 100 ); set_callbacks( OpenDecoder, NULL ); + + add_submodule(); + set_description( _("DTS audio packetizer") ); + set_capability( "packetizer", 10 ); + set_callbacks( OpenPacketizer, NULL ); vlc_module_end(); /***************************************************************************** @@ -87,214 +134,463 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; + + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ') + && p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') ) + { + return VLC_EGENERIC; + } + + p_dec->pf_init = InitDecoder; + p_dec->pf_decode = RunDecoder; + p_dec->pf_end = EndDecoder; - if( p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ') - && p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') ) + /* Allocate the memory needed to store the decoder's structure */ + if( ( p_dec->p_sys = + (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) { + msg_Err( p_dec, "out of memory" ); return VLC_EGENERIC; } + p_dec->p_sys->b_packetizer = VLC_FALSE; - p_fifo->pf_run = RunDecoder; return VLC_SUCCESS; } -/**************************************************************************** - * RunDecoder: the whole thing - **************************************************************************** - * This function is called just after the thread is launched. - ****************************************************************************/ -static int RunDecoder( decoder_fifo_t *p_fifo ) +static int OpenPacketizer( vlc_object_t *p_this ) { - dec_thread_t * p_dec; - audio_date_t end_date; + decoder_t *p_dec = (decoder_t*)p_this; - /* Allocate the memory needed to store the thread's structure */ - p_dec = malloc( sizeof(dec_thread_t) ); - if( p_dec == NULL ) - { - msg_Err( p_fifo, "out of memory" ); - DecoderError( p_fifo ); - return -1; - } + int i_ret = OpenDecoder( p_this ); - /* Initialize the thread properties */ - p_dec->p_aout = NULL; - p_dec->p_aout_input = NULL; - p_dec->p_fifo = p_fifo; - p_dec->output_format.i_format = VLC_FOURCC('d','t','s',' '); + if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE; - aout_DateSet( &end_date, 0 ); + return i_ret; +} - /* Init the bitstream */ - if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, - NULL, NULL ) != VLC_SUCCESS ) - { - msg_Err( p_fifo, "cannot initialize bitstream" ); - DecoderError( p_fifo ); - free( p_dec ); - return -1; - } +/***************************************************************************** + * InitDecoder: Initalize the decoder + *****************************************************************************/ +static int InitDecoder( decoder_t *p_dec ) +{ + p_dec->p_sys->i_state = STATE_NOSYNC; - /* Decoder thread's main loop */ - while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error ) - { - int i; - mtime_t pts; - byte_t p_header[10]; + p_dec->p_sys->p_out_buffer = NULL; + p_dec->p_sys->i_out_buffer = 0; + aout_DateSet( &p_dec->p_sys->end_date, 0 ); + + p_dec->p_sys->p_aout = NULL; + p_dec->p_sys->p_aout_input = NULL; + p_dec->p_sys->p_aout_buffer = NULL; + p_dec->p_sys->aout_format.i_format = VLC_FOURCC('d','t','s',' '); - unsigned int i_rate; - unsigned int i_bit_rate; - unsigned int i_frame_size; - unsigned int i_frame_length; - unsigned int i_original_channels; + p_dec->p_sys->p_sout_input = NULL; + p_dec->p_sys->p_sout_buffer = NULL; + p_dec->p_sys->sout_format.i_cat = AUDIO_ES; + p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC('d','t','s',' '); + + return VLC_SUCCESS; +} - aout_buffer_t * p_buffer = NULL; +/**************************************************************************** + * RunDecoder: the whole thing + **************************************************************************** + * This function is called just after the thread is launched. + ****************************************************************************/ +static int RunDecoder( decoder_t *p_dec, block_t *p_block ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + int i, i_block_pos = 0; + mtime_t i_pts = p_block->i_pts; - for( i = 0; i < 3; i++ ) + while( i_block_pos < p_block->i_buffer ) + { + switch( p_sys->i_state ) { - RealignBits( &p_dec->bit_stream ); - while( (ShowBits( &p_dec->bit_stream, 32 ) ) != 0x7ffe8001 && - (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) ) + case STATE_NOSYNC: + /* Look for sync dword - should be 0x7ffe8001 */ + while( i_block_pos < p_block->i_buffer && + p_block->p_buffer[i_block_pos] != 0x7f ) { - RemoveBits( &p_dec->bit_stream, 8 ); + i_block_pos++; } - if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break; - if( i == 0 ) + if( i_block_pos < p_block->i_buffer ) { - /* Set the Presentation Time Stamp */ - NextPTS( &p_dec->bit_stream, &pts, NULL ); - if( pts != 0 && pts != aout_DateGet( &end_date ) ) - { - aout_DateSet( &end_date, pts ); - } + p_sys->i_state = STATE_PARTIAL_SYNC; + i_block_pos++; + p_sys->p_header[0] = 0x7f; + p_sys->i_header = 1; + break; } + break; - /* Get DTS frame header */ - GetChunk( &p_dec->bit_stream, p_header, 10 ); - if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break; - - i_frame_size = SyncInfo( p_header, &i_original_channels, &i_rate, - &i_bit_rate, &i_frame_length ); - if( !i_frame_size ) + case STATE_PARTIAL_SYNC: + /* Get the full 4 sync bytes */ + if( p_sys->i_header < 4 ) { - msg_Warn( p_dec->p_fifo, "dts_syncinfo failed" ); - i--; continue; + int i_size = __MIN( 4 - p_sys->i_header, + p_block->i_buffer - i_block_pos ); + + memcpy( p_sys->p_header + p_sys->i_header, + p_block->p_buffer + i_block_pos, i_size ); + i_block_pos += i_size; + p_sys->i_header += i_size; } - if( i == 0 ) + if( p_sys->i_header < 4 ) + break; + + if( p_sys->p_header[0] == 0x7f && p_sys->p_header[1] == 0xfe && + p_sys->p_header[2] == 0x80 && p_sys->p_header[3] == 0x01 ) { - if( (p_dec->p_aout_input != NULL) && - ( (p_dec->output_format.i_rate != i_rate) - || (p_dec->output_format.i_original_channels - != i_original_channels) - || (p_dec->output_format.i_bytes_per_frame - != i_frame_size * 3) ) ) + p_sys->i_state = STATE_SYNC; + } + else + { + for( i = 1; i < 4; i++ ) { - /* Parameters changed - this should not happen. */ - aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input ); - p_dec->p_aout_input = NULL; + if( p_sys->p_header[i] == 0x7f ) break; } - /* Creating the audio input if not created yet. */ - if( p_dec->p_aout_input == NULL ) + if( p_sys->p_header[i] == 0x7f ) { - p_dec->output_format.i_rate = i_rate; - p_dec->output_format.i_original_channels - = i_original_channels; - p_dec->output_format.i_physical_channels - = i_original_channels & AOUT_CHAN_PHYSMASK; - p_dec->output_format.i_bytes_per_frame = i_frame_size * 3; - p_dec->output_format.i_frame_length = i_frame_length * 3; - aout_DateInit( &end_date, i_rate ); - p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo, - &p_dec->p_aout, - &p_dec->output_format ); - - if( p_dec->p_aout_input == NULL ) - { - p_dec->p_fifo->b_error = 1; - break; - } + /* Potential new sync */ + p_sys->i_header -= i; + memmove( p_sys->p_header, &p_sys->p_header[i], + p_sys->i_header ); + break; } + + /* retry to sync*/ + p_sys->i_state = STATE_NOSYNC; + } + break; + + case STATE_SYNC: + /* New frame, set the Presentation Time Stamp */ + p_sys->pts = i_pts; i_pts = 0; + if( p_sys->pts != 0 && + p_sys->pts != aout_DateGet( &p_sys->end_date ) ) + { + aout_DateSet( &p_sys->end_date, p_sys->pts ); } + p_sys->i_state = STATE_HEADER; + break; - if( !aout_DateGet( &end_date ) ) + case STATE_HEADER: + /* Get DTS frame header (DTS_HEADER_SIZE bytes) */ + if( p_sys->i_header < DTS_HEADER_SIZE ) { - byte_t p_junk[ i_frame_size ]; + int i_size = __MIN( DTS_HEADER_SIZE - p_sys->i_header, + p_block->i_buffer - i_block_pos ); - /* We've just started the stream, wait for the first PTS. */ - GetChunk( &p_dec->bit_stream, p_junk, i_frame_size - 10 ); - i--; continue; + memcpy( p_sys->p_header + p_sys->i_header, + p_block->p_buffer + i_block_pos, i_size ); + i_block_pos += i_size; + p_sys->i_header += i_size; } - if( i == 0 ) + if( p_sys->i_header < DTS_HEADER_SIZE ) + break; + + if( GetOutBuffer( p_dec, &p_sys->p_out_buffer ) + != VLC_SUCCESS ) { - p_buffer = aout_DecNewBuffer( p_dec->p_aout, - p_dec->p_aout_input, - i_frame_length * 3 ); - if( p_buffer == NULL ) - { - p_dec->p_fifo->b_error = 1; - break; - } - p_buffer->start_date = aout_DateGet( &end_date ); - p_buffer->end_date = aout_DateIncrement( &end_date, - i_frame_length * 3 ); + block_Release( p_block ); + return VLC_EGENERIC; } - /* Get the whole frame. */ - memcpy( p_buffer->p_buffer + (i * i_frame_size), p_header, 10 ); - GetChunk( &p_dec->bit_stream, - p_buffer->p_buffer + (i * i_frame_size) + 10, - i_frame_size - 10 ); - if( p_dec->p_fifo->b_die ) break; - } + if( !p_sys->p_out_buffer ) + { + p_sys->i_state = STATE_NOSYNC; + break; + } - if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) - { - if( p_buffer != NULL ) + memcpy( p_sys->p_out_buffer, p_sys->p_header, DTS_HEADER_SIZE ); + p_sys->i_out_buffer = DTS_HEADER_SIZE; + p_sys->i_state = STATE_DATA; + break; + + case STATE_DATA: + /* Copy the whole DTS frame into the aout buffer */ + if( p_sys->i_out_buffer < p_sys->i_frame_size ) { - aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input, - p_buffer ); + int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer, + p_block->i_buffer - i_block_pos ); + + memcpy( p_sys->p_out_buffer + p_sys->i_out_buffer, + p_block->p_buffer + i_block_pos, i_size ); + i_block_pos += i_size; + p_sys->i_out_buffer += i_size; } + if( p_sys->i_out_buffer < p_sys->i_frame_size ) + break; /* Need more data */ + + SendOutBuffer( p_dec ); + + p_sys->i_state = STATE_NOSYNC; break; } + } + + block_Release( p_block ); + return VLC_SUCCESS; +} + +/***************************************************************************** + * EndDecoder: clean up the decoder + *****************************************************************************/ +static int EndDecoder( decoder_t *p_dec ) +{ + if( p_dec->p_sys->p_aout_input != NULL ) + { + if( p_dec->p_sys->p_aout_buffer ) + { + aout_DecDeleteBuffer( p_dec->p_sys->p_aout, + p_dec->p_sys->p_aout_input, + p_dec->p_sys->p_aout_buffer ); + } + + aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input ); + } + + if( p_dec->p_sys->p_sout_input != NULL ) + { + if( p_dec->p_sys->p_sout_buffer ) + { + sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout, + p_dec->p_sys->p_sout_buffer ); + } + + sout_InputDelete( p_dec->p_sys->p_sout_input ); + } + + free( p_dec->p_sys ); + + return VLC_SUCCESS; +} + +/***************************************************************************** + * GetOutBuffer: + *****************************************************************************/ +static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + int i_ret; + + if( p_sys->b_packetizer ) + { + i_ret= GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ); + *pp_out_buffer = + p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL; + } + else + { + i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer ); + if( p_sys->i_frames_in_buf == 1 ) + *pp_out_buffer = p_sys->p_aout_buffer ? + p_sys->p_aout_buffer->p_buffer : NULL; + else + *pp_out_buffer = p_sys->p_aout_buffer ? + p_sys->p_aout_buffer->p_buffer + p_sys->i_frame_size * + (p_sys->i_frames_in_buf - 1) : NULL; + } + + return i_ret; +} + +/***************************************************************************** + * GetAoutBuffer: + *****************************************************************************/ +static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer ) +{ + int i_bit_rate; + unsigned int i_frame_length, i_rate, i_channels, i_channels_conf; + + decoder_sys_t *p_sys = p_dec->p_sys; + + /* Check if frame is valid and get frame info */ + p_sys->i_frame_size = SyncInfo( p_sys->p_header, + &i_channels, &i_channels_conf, + &i_rate, &i_bit_rate, &i_frame_length ); + + if( !p_sys->i_frame_size ) + { + msg_Warn( p_dec, "dts syncinfo failed" ); + *pp_buffer = NULL; + return VLC_SUCCESS; + } + + if( p_sys->p_aout_input != NULL && ( p_sys->aout_format.i_rate != i_rate + || p_sys->aout_format.i_original_channels != i_channels_conf + || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) ) + { + /* Parameters changed - this should not happen. */ + aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input ); + p_sys->p_aout_input = NULL; + } + + /* Creating the audio input if not created yet. */ + if( p_sys->p_aout_input == NULL ) + { + p_sys->aout_format.i_rate = i_rate; + p_sys->aout_format.i_original_channels = i_channels_conf; + p_sys->aout_format.i_physical_channels + = i_channels_conf & AOUT_CHAN_PHYSMASK; + p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size; + p_sys->aout_format.i_frame_length = i_frame_length; + aout_DateInit( &p_sys->end_date, i_rate ); + aout_DateSet( &p_sys->end_date, p_sys->pts ); + p_sys->i_frames_in_buf = 3; + p_sys->p_aout_input = aout_DecNew( p_dec, + &p_sys->p_aout, + &p_sys->aout_format ); + + if ( p_sys->p_aout_input == NULL ) + { + *pp_buffer = NULL; + return VLC_SUCCESS; + } + } - /* Send the buffer to the aout core. */ - aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer ); + if( !aout_DateGet( &p_sys->end_date ) ) + { + /* We've just started the stream, wait for the first PTS. */ + *pp_buffer = NULL; + return VLC_SUCCESS; } - if( p_dec->p_fifo->b_error ) + if( p_sys->i_frames_in_buf == 3 ) { - DecoderError( p_dec->p_fifo ); + p_sys->i_frames_in_buf = 0; + *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input, + i_frame_length * 3 ); + if( *pp_buffer == NULL ) + { + return VLC_SUCCESS; + } + + (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date ); + (*pp_buffer)->end_date = + aout_DateIncrement( &p_sys->end_date, i_frame_length * 3 ); } - EndThread( p_dec ); + p_sys->i_frames_in_buf++; - return 0; + return VLC_SUCCESS; } /***************************************************************************** - * EndThread : thread destruction + * GetSoutBuffer: *****************************************************************************/ -static void EndThread( dec_thread_t * p_dec ) +static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer ) { - if ( p_dec->p_aout_input != NULL ) + int i_bit_rate; + unsigned int i_frame_length, i_rate, i_channels, i_channels_conf; + + decoder_sys_t *p_sys = p_dec->p_sys; + + /* Check if frame is valid and get frame info */ + p_sys->i_frame_size = SyncInfo( p_sys->p_header, + &i_channels, &i_channels_conf, + &i_rate, &i_bit_rate, &i_frame_length ); + + if( !p_sys->i_frame_size ) { - aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input ); + msg_Warn( p_dec, "dts syncinfo failed" ); + *pp_buffer = NULL; + return VLC_SUCCESS; } - CloseBitstream( &p_dec->bit_stream ); - free( p_dec ); + if( p_sys->p_sout_input != NULL && + ( p_sys->sout_format.i_sample_rate != (int)i_rate + || p_sys->sout_format.i_channels != (int)i_channels ) ) + { + /* Parameters changed - this should not happen. */ + } + + /* Creating the sout input if not created yet. */ + if( p_sys->p_sout_input == NULL ) + { + p_sys->sout_format.i_sample_rate = i_rate; + p_sys->sout_format.i_channels = i_channels; + p_sys->sout_format.i_block_align = 0; + p_sys->sout_format.i_bitrate = i_bit_rate; + p_sys->sout_format.i_extra_data = 0; + p_sys->sout_format.p_extra_data = NULL; + + aout_DateInit( &p_sys->end_date, i_rate ); + aout_DateSet( &p_sys->end_date, p_sys->pts ); + + p_sys->p_sout_input = sout_InputNew( p_dec, + &p_sys->sout_format ); + + if( p_sys->p_sout_input == NULL ) + { + msg_Err( p_dec, "cannot add a new stream" ); + *pp_buffer = NULL; + return VLC_EGENERIC; + } + msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d", + i_channels, i_rate, i_bit_rate ); + } + + if( !aout_DateGet( &p_sys->end_date ) ) + { + /* We've just started the stream, wait for the first PTS. */ + *pp_buffer = NULL; + return VLC_SUCCESS; + } + + *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout, + p_sys->i_frame_size ); + if( *pp_buffer == NULL ) + { + return VLC_SUCCESS; + } + + (*pp_buffer)->i_pts = + (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date ); + + (*pp_buffer)->i_length = + aout_DateIncrement( &p_sys->end_date, i_frame_length ) + - (*pp_buffer)->i_pts; + + return VLC_SUCCESS; +} + +/***************************************************************************** + * SendOutBuffer: + *****************************************************************************/ +static int SendOutBuffer( decoder_t *p_dec ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + + if( p_sys->b_packetizer ) + { + sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer ); + p_sys->p_sout_buffer = NULL; + } + else if( p_sys->i_frames_in_buf == 3 ) + { + /* We have all we need, send the buffer to the aout core. */ + aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, + p_sys->p_aout_buffer ); + p_sys->p_aout_buffer = NULL; + } + + return VLC_SUCCESS; } /***************************************************************************** * SyncInfo: parse DTS sync info *****************************************************************************/ -static int SyncInfo( const byte_t * p_buf, unsigned int * pi_channels, +static int SyncInfo( const byte_t * p_buf, + unsigned int * pi_channels, + unsigned int * pi_channels_conf, unsigned int * pi_sample_rate, unsigned int * pi_bit_rate, unsigned int * pi_frame_length ) @@ -340,71 +636,83 @@ static int SyncInfo( const byte_t * p_buf, unsigned int * pi_channels, { case 0x0: /* Mono */ - *pi_channels = AOUT_CHAN_CENTER; + *pi_channels_conf = AOUT_CHAN_CENTER; break; case 0x1: /* Dual-mono = stereo + dual-mono */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_DUALMONO; break; case 0x2: case 0x3: case 0x4: /* Stereo */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; + *pi_channels = 2; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; break; case 0x5: /* 3F */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER; + *pi_channels = 3; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_CENTER; break; case 0x6: /* 2F/LFE */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE; + *pi_channels = 3; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_LFE; break; case 0x7: /* 3F/LFE */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | - AOUT_CHAN_CENTER | AOUT_CHAN_LFE; + *pi_channels = 4; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_CENTER | AOUT_CHAN_LFE; break; case 0x8: /* 2F2R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | - AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; + *pi_channels = 4; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; break; case 0x9: /* 3F2R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | - AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | - AOUT_CHAN_REARRIGHT; + *pi_channels = 5; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | + AOUT_CHAN_REARRIGHT; break; case 0xA: case 0xB: /* 2F2M2R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | - AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | - AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; + *pi_channels = 6; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | + AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; break; case 0xC: /* 3F2M2R */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | - AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT | - AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT | - AOUT_CHAN_REARRIGHT; + *pi_channels = 7; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT | + AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT | + AOUT_CHAN_REARRIGHT; break; case 0xD: case 0xE: /* 3F2M2R/LFE */ - *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | - AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT | - AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT | - AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE; + *pi_channels = 8; + *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | + AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT | + AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT | + AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE; break; default: if( i_audio_mode <= 63 ) { /* User defined */ - *pi_channels = 0; + *pi_channels = 0; + *pi_channels_conf = 0; } else { diff --git a/modules/codec/dv.c b/modules/codec/dv.c index 298dc03909..d84b1a7bb9 100644 --- a/modules/codec/dv.c +++ b/modules/codec/dv.c @@ -2,7 +2,7 @@ * dv.c: a decoder for DV video ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: dv.c,v 1.4 2003/01/28 16:57:28 sam Exp $ + * $Id: dv.c,v 1.5 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -57,14 +57,14 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder ( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } diff --git a/modules/codec/faad/decoder.c b/modules/codec/faad/decoder.c index d43a833e73..1d2e134196 100644 --- a/modules/codec/faad/decoder.c +++ b/modules/codec/faad/decoder.c @@ -2,7 +2,7 @@ * decoder.c: AAC decoder using libfaad2 ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: decoder.c,v 1.29 2003/08/24 23:22:02 gbazin Exp $ + * $Id: decoder.c,v 1.30 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * @@ -65,14 +65,14 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } @@ -480,4 +480,3 @@ static void EndThread (adec_thread_t *p_adec) free( p_adec ); } - diff --git a/modules/codec/ffmpeg/ffmpeg.c b/modules/codec/ffmpeg/ffmpeg.c index 2e8702d2b2..db67bf8199 100644 --- a/modules/codec/ffmpeg/ffmpeg.c +++ b/modules/codec/ffmpeg/ffmpeg.c @@ -2,7 +2,7 @@ * ffmpeg.c: video decoder using ffmpeg library ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: ffmpeg.c,v 1.48 2003/08/15 13:16:38 fenrir Exp $ + * $Id: ffmpeg.c,v 1.49 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * @@ -189,15 +189,16 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*) p_this; - if( ffmpeg_GetFfmpegCodec( p_fifo->i_fourcc, NULL, NULL, NULL ) ) + if( !ffmpeg_GetFfmpegCodec( p_dec->p_fifo->i_fourcc, NULL, NULL, NULL ) ) { - p_fifo->pf_run = RunDecoder; - return VLC_SUCCESS; + return VLC_EGENERIC; } - return VLC_EGENERIC; + p_dec->pf_run = RunDecoder; + + return VLC_SUCCESS; } typedef union decoder_thread_u @@ -208,7 +209,6 @@ typedef union decoder_thread_u } decoder_thread_t; - /***************************************************************************** * RunDecoder: this function is called just after the thread is created *****************************************************************************/ diff --git a/modules/codec/flacdec.c b/modules/codec/flacdec.c index 942d1832fd..4f3c886280 100644 --- a/modules/codec/flacdec.c +++ b/modules/codec/flacdec.c @@ -2,7 +2,7 @@ * flac.c: flac decoder module making use of libflac ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: flacdec.c,v 1.3 2003/08/17 13:56:26 gbazin Exp $ + * $Id: flacdec.c,v 1.4 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Sigmund Augdal * @@ -114,14 +114,14 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('f','l','a','c') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('f','l','a','c') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c index 6711989d63..ac72e02bab 100755 --- a/modules/codec/libmpeg2.c +++ b/modules/codec/libmpeg2.c @@ -2,9 +2,10 @@ * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: libmpeg2.c,v 1.25 2003/08/18 13:16:43 zorglub Exp $ + * $Id: libmpeg2.c,v 1.26 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Gildas Bazin + * Christophe Massiot * * 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 @@ -43,9 +44,9 @@ #define AR_221_1_PICTURE 4 /* 2.21:1 picture (movie) */ /***************************************************************************** - * dec_thread_t : libmpeg2 decoder thread descriptor + * decoder_sys_t : libmpeg2 decoder descriptor *****************************************************************************/ -typedef struct dec_thread_t +struct decoder_sys_t { /* * libmpeg2 properties @@ -57,7 +58,6 @@ typedef struct dec_thread_t /* * Input properties */ - decoder_fifo_t *p_fifo; /* stores the PES stream data */ pes_packet_t *p_pes; /* current PES we are decoding */ mtime_t i_pts; mtime_t i_previous_pts; @@ -76,16 +76,17 @@ typedef struct dec_thread_t vout_thread_t *p_vout; vout_synchro_t *p_synchro; -} dec_thread_t; +}; /***************************************************************************** * Local prototypes *****************************************************************************/ static int OpenDecoder ( vlc_object_t * ); -static int RunDecoder ( decoder_fifo_t * ); -static void CloseDecoder ( dec_thread_t * ); +static int InitDecoder ( decoder_t * ); +static int RunDecoder ( decoder_t *, block_t * ); +static int EndDecoder ( decoder_t * ); -static picture_t *GetNewPicture( dec_thread_t *, uint8_t ** ); +static picture_t *GetNewPicture( decoder_t *, uint8_t ** ); /***************************************************************************** * Module descriptor @@ -102,93 +103,100 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('m','p','g','v') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','v') && + p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','1') && + p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','g','2') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_init = InitDecoder; + p_dec->pf_decode = RunDecoder; + p_dec->pf_end = EndDecoder; + return VLC_SUCCESS; } /***************************************************************************** - * RunDecoder: the libmpeg2 decoder + * InitDecoder: Initalize the decoder *****************************************************************************/ -static int RunDecoder( decoder_fifo_t *p_fifo ) +static int InitDecoder( decoder_t *p_dec ) { - dec_thread_t *p_dec; - data_packet_t *p_data = NULL; - mpeg2_state_t state; - picture_t *p_pic; - int i_aspect; - int i_pic; - - /* Allocate the memory needed to store the thread's structure */ - if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) ) - == NULL) + /* Allocate the memory needed to store the decoder's structure */ + if( ( p_dec->p_sys = + (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) { - msg_Err( p_fifo, "out of memory" ); - goto error; + msg_Err( p_dec, "out of memory" ); + return VLC_EGENERIC; } /* Initialize the thread properties */ - memset( p_dec, 0, sizeof(dec_thread_t) ); - p_dec->p_fifo = p_fifo; - p_dec->p_pes = NULL; - p_dec->p_vout = NULL; - p_dec->p_mpeg2dec = NULL; - p_dec->p_synchro = NULL; - p_dec->p_info = NULL; - p_dec->i_pts = mdate() + DEFAULT_PTS_DELAY; - p_dec->i_current_pts = 0; - p_dec->i_previous_pts = 0; - p_dec->i_period_remainder = 0; - p_dec->p_picture_to_destroy = NULL; - p_dec->b_garbage_pic = 0; - p_dec->b_slice_i = 0; - p_dec->b_skip = 0; + memset( p_dec->p_sys, 0, sizeof(decoder_sys_t) ); + p_dec->p_sys->p_pes = NULL; + p_dec->p_sys->p_vout = NULL; + p_dec->p_sys->p_mpeg2dec = NULL; + p_dec->p_sys->p_synchro = NULL; + p_dec->p_sys->p_info = NULL; + p_dec->p_sys->i_pts = mdate() + DEFAULT_PTS_DELAY; + p_dec->p_sys->i_current_pts = 0; + p_dec->p_sys->i_previous_pts = 0; + p_dec->p_sys->i_period_remainder = 0; + p_dec->p_sys->p_picture_to_destroy = NULL; + p_dec->p_sys->b_garbage_pic = 0; + p_dec->p_sys->b_slice_i = 0; + p_dec->p_sys->b_skip = 0; /* Initialize decoder */ - p_dec->p_mpeg2dec = mpeg2_init(); - if( p_dec->p_mpeg2dec == NULL) - goto error; + p_dec->p_sys->p_mpeg2dec = mpeg2_init(); + if( p_dec->p_sys->p_mpeg2dec == NULL) + { + msg_Err( p_dec, "mpeg2_init() failed" ); + free( p_dec->p_sys ); + return VLC_EGENERIC; + } - p_dec->p_info = mpeg2_info( p_dec->p_mpeg2dec ); + p_dec->p_sys->p_info = mpeg2_info( p_dec->p_sys->p_mpeg2dec ); + + return VLC_SUCCESS; +} - /* libmpeg2 decoder thread's main loop */ - while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) ) +/***************************************************************************** + * RunDecoder: the libmpeg2 decoder + *****************************************************************************/ +static int RunDecoder( decoder_t *p_dec, block_t *p_block ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + mpeg2_state_t state; + picture_t *p_pic; + int i_aspect; + + vlc_bool_t b_need_more_data = VLC_FALSE; + + while( 1 ) { - state = mpeg2_parse( p_dec->p_mpeg2dec ); + state = mpeg2_parse( p_sys->p_mpeg2dec ); switch( state ) { case STATE_BUFFER: - /* Feed libmpeg2 a data packet at a time */ - if( p_data == NULL ) - { - /* Get the next PES */ - if( p_dec->p_pes ) - input_DeletePES( p_dec->p_fifo->p_packets_mgt, - p_dec->p_pes ); - - input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes ); - if( !p_dec->p_pes ) + if( !p_block->i_buffer || b_need_more_data ) { - p_dec->p_fifo->b_error = 1; - break; + block_Release( p_block ); + return VLC_SUCCESS; } - if( p_dec->p_pes->b_discontinuity && p_dec->p_synchro - && p_dec->p_info->sequence->width != (unsigned)-1 ) +#if 0 + if( p_pes->b_discontinuity && p_sys->p_synchro + && p_sys->p_info->sequence->width != (unsigned)-1 ) { - vout_SynchroReset( p_dec->p_synchro ); - if ( p_dec->p_info->current_fbuf != NULL - && p_dec->p_info->current_fbuf->id != NULL ) + vout_SynchroReset( p_sys->p_synchro ); + if ( p_sys->p_info->current_fbuf != NULL + && p_sys->p_info->current_fbuf->id != NULL ) { - p_dec->b_garbage_pic = 1; - p_pic = p_dec->p_info->current_fbuf->id; + p_sys->b_garbage_pic = 1; + p_pic = p_sys->p_info->current_fbuf->id; } else { @@ -196,49 +204,43 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) buf[0] = buf[1] = buf[2] = NULL; if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break; - mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic ); + mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic ); } - p_dec->p_picture_to_destroy = p_pic; + p_sys->p_picture_to_destroy = p_pic; memset( p_pic->p[0].p_pixels, 0, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height ); memset( p_pic->p[1].p_pixels, 0x80, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height / 4 ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); memset( p_pic->p[2].p_pixels, 0x80, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height / 4 ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); - if ( p_dec->b_slice_i ) + if ( p_sys->b_slice_i ) { - vout_SynchroNewPicture( p_dec->p_synchro, - I_CODING_TYPE, 2, 0, 0, p_dec->i_current_rate ); - vout_SynchroDecode( p_dec->p_synchro ); - vout_SynchroEnd( p_dec->p_synchro, I_CODING_TYPE, 0 ); + vout_SynchroNewPicture( p_sys->p_synchro, + I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate ); + vout_SynchroDecode( p_sys->p_synchro ); + vout_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); } } +#endif - if( p_dec->p_pes->i_pts ) - { - mpeg2_pts( p_dec->p_mpeg2dec, - (uint32_t)p_dec->p_pes->i_pts ); - p_dec->i_previous_pts = p_dec->i_current_pts; - p_dec->i_current_pts = p_dec->p_pes->i_pts; - } - - p_dec->i_current_rate = p_dec->p_pes->i_rate; - p_data = p_dec->p_pes->p_first; + if( p_block->i_pts ) + { + mpeg2_pts( p_sys->p_mpeg2dec, (uint32_t)p_block->i_pts ); + p_sys->i_previous_pts = p_sys->i_current_pts; + p_sys->i_current_pts = p_block->i_pts; } - if( p_data != NULL ) - { - mpeg2_buffer( p_dec->p_mpeg2dec, - p_data->p_payload_start, - p_data->p_payload_end ); + p_sys->i_current_rate = DEFAULT_RATE;//p_pes->i_rate; - p_data = p_data->p_next; - } + mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer, + p_block->p_buffer + p_block->i_buffer ); + + b_need_more_data = VLC_TRUE; break; case STATE_SEQUENCE: @@ -266,99 +268,105 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) case AR_SQUARE_PICTURE: default: i_aspect = VOUT_ASPECT_FACTOR * - p_dec->p_info->sequence->width / - p_dec->p_info->sequence->height; + p_sys->p_info->sequence->width / + p_sys->p_info->sequence->height; break; } } else { /* Use the value provided in the MPEG sequence header */ - i_aspect = ((uint64_t)p_dec->p_info->sequence->display_width) * - p_dec->p_info->sequence->pixel_width * VOUT_ASPECT_FACTOR / - p_dec->p_info->sequence->display_height / - p_dec->p_info->sequence->pixel_height; + i_aspect = ((uint64_t)p_sys->p_info->sequence->display_width) * + p_sys->p_info->sequence->pixel_width * VOUT_ASPECT_FACTOR / + p_sys->p_info->sequence->display_height / + p_sys->p_info->sequence->pixel_height; } - if ( p_dec->p_vout != NULL ) - { + if ( p_dec->p_sys->p_vout != NULL ) + { + int i_pic; /* Temporary hack to free the pictures in use by libmpeg2 */ - for ( i_pic = 0; i_pic < p_dec->p_vout->render.i_pictures; i_pic++ ) + for ( i_pic = 0; i_pic < p_dec->p_sys->p_vout->render.i_pictures; i_pic++ ) { - if( p_dec->p_vout->render.pp_picture[i_pic]->i_status == + if( p_dec->p_sys->p_vout->render.pp_picture[i_pic]->i_status == RESERVED_PICTURE ) - vout_DestroyPicture( p_dec->p_vout, - p_dec->p_vout->render.pp_picture[i_pic] ); - if( p_dec->p_vout->render.pp_picture[i_pic]->i_refcount > 0 ) - vout_UnlinkPicture( p_dec->p_vout, - p_dec->p_vout->render.pp_picture[i_pic] ); + vout_DestroyPicture( p_dec->p_sys->p_vout, + p_dec->p_sys->p_vout->render.pp_picture[i_pic] ); + if( p_dec->p_sys->p_vout->render.pp_picture[i_pic]->i_refcount > 0 ) + vout_UnlinkPicture( p_dec->p_sys->p_vout, + p_dec->p_sys->p_vout->render.pp_picture[i_pic] ); } } - p_dec->p_vout = vout_Request( p_dec->p_fifo, p_dec->p_vout, - p_dec->p_info->sequence->width, - p_dec->p_info->sequence->height, - VLC_FOURCC('Y','V','1','2'), i_aspect ); - - if(p_dec->p_vout == NULL ) + p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout, + p_sys->p_info->sequence->width, + p_sys->p_info->sequence->height, + VLC_FOURCC('Y','V','1','2'), + i_aspect ); + + if(p_sys->p_vout == NULL ) { - msg_Err( p_dec->p_fifo , "cannot create vout" ); + msg_Err( p_dec, "cannot create vout" ); + block_Release( p_block ); return -1; } - - msg_Dbg( p_dec->p_fifo, "%dx%d, aspect %d, %u.%03u fps", - p_dec->p_info->sequence->width, - p_dec->p_info->sequence->height, i_aspect, - (u32)((u64)1001000000 * 27 / p_dec->p_info->sequence->frame_period / 1001), - (u32)((u64)1001000000 * 27 / p_dec->p_info->sequence->frame_period % 1001) ); - mpeg2_custom_fbuf( p_dec->p_mpeg2dec, 1 ); + msg_Dbg( p_dec, "%dx%d, aspect %d, %u.%03u fps", + p_sys->p_info->sequence->width, + p_sys->p_info->sequence->height, i_aspect, + (uint32_t)((u64)1001000000 * 27 / + p_sys->p_info->sequence->frame_period / 1001), + (uint32_t)((u64)1001000000 * 27 / + p_sys->p_info->sequence->frame_period % 1001) ); + + mpeg2_custom_fbuf( p_sys->p_mpeg2dec, 1 ); /* Set the first 2 reference frames */ - mpeg2_set_buf( p_dec->p_mpeg2dec, buf, NULL ); + mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL ); if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break; memset( p_pic->p[0].p_pixels, 0, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height ); memset( p_pic->p[1].p_pixels, 0x80, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height / 4 ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); memset( p_pic->p[2].p_pixels, 0x80, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height / 4 ); - mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); + mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic ); /* This picture will never go through display_picture. */ - vout_DatePicture( p_dec->p_vout, p_pic, 0 ); - vout_DisplayPicture( p_dec->p_vout, p_pic ); + vout_DatePicture( p_sys->p_vout, p_pic, 0 ); + vout_DisplayPicture( p_sys->p_vout, p_pic ); /* For some reason, libmpeg2 will put this pic twice in * discard_picture. This can be considered a bug in libmpeg2. */ - vout_LinkPicture( p_dec->p_vout, p_pic ); + vout_LinkPicture( p_sys->p_vout, p_pic ); - if ( p_dec->p_synchro ) + if ( p_sys->p_synchro ) { - vout_SynchroRelease( p_dec->p_synchro ); + vout_SynchroRelease( p_sys->p_synchro ); } - p_dec->p_synchro = vout_SynchroInit( p_dec->p_fifo, p_dec->p_vout, - (u32)((u64)1001000000 * 27 / p_dec->p_info->sequence->frame_period) ); - p_dec->b_after_sequence_header = 1; + p_sys->p_synchro = vout_SynchroInit( p_dec, p_sys->p_vout, + (uint32_t)((uint64_t)1001000000 * 27 / + p_sys->p_info->sequence->frame_period) ); + p_sys->b_after_sequence_header = 1; } break; case STATE_PICTURE_2ND: - vout_SynchroNewPicture( p_dec->p_synchro, - p_dec->p_info->current_picture->flags & PIC_MASK_CODING_TYPE, - p_dec->p_info->current_picture->nb_fields, + vout_SynchroNewPicture( p_sys->p_synchro, + p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE, + p_sys->p_info->current_picture->nb_fields, 0, 0, - p_dec->i_current_rate ); + p_sys->i_current_rate ); - if ( p_dec->b_skip ) + if ( p_sys->b_skip ) { - vout_SynchroTrash( p_dec->p_synchro ); + vout_SynchroTrash( p_sys->p_synchro ); } else { - vout_SynchroDecode( p_dec->p_synchro ); + vout_SynchroDecode( p_sys->p_synchro ); } break; @@ -367,85 +375,84 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) uint8_t *buf[3]; buf[0] = buf[1] = buf[2] = NULL; - if ( p_dec->b_after_sequence_header - && ((p_dec->p_info->current_picture->flags + if ( p_sys->b_after_sequence_header + && ((p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_P) ) { /* Intra-slice refresh. Simulate a blank I picture. */ - msg_Dbg( p_dec->p_fifo, "intra-slice refresh stream" ); - vout_SynchroNewPicture( p_dec->p_synchro, - I_CODING_TYPE, 2, 0, 0, p_dec->i_current_rate ); - vout_SynchroDecode( p_dec->p_synchro ); - vout_SynchroEnd( p_dec->p_synchro, I_CODING_TYPE, 0 ); - p_dec->b_slice_i = 1; + msg_Dbg( p_dec, "intra-slice refresh stream" ); + vout_SynchroNewPicture( p_sys->p_synchro, + I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate ); + vout_SynchroDecode( p_sys->p_synchro ); + vout_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); + p_sys->b_slice_i = 1; } - p_dec->b_after_sequence_header = 0; - - vout_SynchroNewPicture( p_dec->p_synchro, - p_dec->p_info->current_picture->flags & PIC_MASK_CODING_TYPE, - p_dec->p_info->current_picture->nb_fields, - (p_dec->p_info->current_picture->flags & PIC_FLAG_PTS) ? - ( (p_dec->p_info->current_picture->pts == - (uint32_t)p_dec->i_current_pts) ? - p_dec->i_current_pts : p_dec->i_previous_pts ) : 0, - 0, - p_dec->i_current_rate ); - - if ( !(p_dec->b_slice_i - && ((p_dec->p_info->current_picture->flags + p_sys->b_after_sequence_header = 0; + + vout_SynchroNewPicture( p_sys->p_synchro, + p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE, + p_sys->p_info->current_picture->nb_fields, + (p_sys->p_info->current_picture->flags & PIC_FLAG_PTS) ? + ( ( p_sys->p_info->current_picture->pts == + (uint32_t)p_sys->i_current_pts ) ? + p_sys->i_current_pts : p_sys->i_previous_pts ) : 0, + 0, p_sys->i_current_rate ); + + if ( !(p_sys->b_slice_i + && ((p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE) == P_CODING_TYPE)) - && !vout_SynchroChoose( p_dec->p_synchro, - p_dec->p_info->current_picture->flags + && !vout_SynchroChoose( p_sys->p_synchro, + p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE ) ) { - mpeg2_skip( p_dec->p_mpeg2dec, 1 ); - p_dec->b_skip = 1; - vout_SynchroTrash( p_dec->p_synchro ); - mpeg2_set_buf( p_dec->p_mpeg2dec, buf, NULL ); + mpeg2_skip( p_sys->p_mpeg2dec, 1 ); + p_sys->b_skip = 1; + vout_SynchroTrash( p_sys->p_synchro ); + mpeg2_set_buf( p_sys->p_mpeg2dec, buf, NULL ); } else { - mpeg2_skip( p_dec->p_mpeg2dec, 0 ); - p_dec->b_skip = 0; - vout_SynchroDecode( p_dec->p_synchro ); + mpeg2_skip( p_sys->p_mpeg2dec, 0 ); + p_sys->b_skip = 0; + vout_SynchroDecode( p_sys->p_synchro ); if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break; - mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic ); + mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic ); } } break; case STATE_END: case STATE_SLICE: - if( p_dec->p_info->display_fbuf - && p_dec->p_info->display_fbuf->id ) + if( p_sys->p_info->display_fbuf + && p_sys->p_info->display_fbuf->id ) { - p_pic = (picture_t *)p_dec->p_info->display_fbuf->id; + p_pic = (picture_t *)p_sys->p_info->display_fbuf->id; - vout_SynchroEnd( p_dec->p_synchro, - p_dec->p_info->display_picture->flags + vout_SynchroEnd( p_sys->p_synchro, + p_sys->p_info->display_picture->flags & PIC_MASK_CODING_TYPE, - p_dec->b_garbage_pic ); - p_dec->b_garbage_pic = 0; - vout_DisplayPicture( p_dec->p_vout, p_pic ); + p_sys->b_garbage_pic ); + p_sys->b_garbage_pic = 0; + vout_DisplayPicture( p_sys->p_vout, p_pic ); - if ( p_dec->p_picture_to_destroy != p_pic ) + if ( p_sys->p_picture_to_destroy != p_pic ) { - vout_DatePicture( p_dec->p_vout, p_pic, - vout_SynchroDate( p_dec->p_synchro ) ); + vout_DatePicture( p_sys->p_vout, p_pic, + vout_SynchroDate( p_sys->p_synchro ) ); } else { - p_dec->p_picture_to_destroy = NULL; - vout_DatePicture( p_dec->p_vout, p_pic, 0 ); + p_sys->p_picture_to_destroy = NULL; + vout_DatePicture( p_sys->p_vout, p_pic, 0 ); } } - if( p_dec->p_info->discard_fbuf && - p_dec->p_info->discard_fbuf->id ) + if( p_sys->p_info->discard_fbuf && + p_sys->p_info->discard_fbuf->id ) { - p_pic = (picture_t *)p_dec->p_info->discard_fbuf->id; - vout_UnlinkPicture( p_dec->p_vout, p_pic ); + p_pic = (picture_t *)p_sys->p_info->discard_fbuf->id; + vout_UnlinkPicture( p_sys->p_vout, p_pic ); } break; @@ -454,46 +461,46 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) uint8_t *buf[3]; buf[0] = buf[1] = buf[2] = NULL; - msg_Warn( p_dec->p_fifo, "invalid picture encountered" ); - if ( ( p_dec->p_info->current_picture == NULL ) || - ( ( p_dec->p_info->current_picture->flags & PIC_MASK_CODING_TYPE) + msg_Warn( p_dec, "invalid picture encountered" ); + if ( ( p_sys->p_info->current_picture == NULL ) || + ( ( p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE) != B_CODING_TYPE ) ) { - vout_SynchroReset( p_dec->p_synchro ); + vout_SynchroReset( p_sys->p_synchro ); } - mpeg2_skip( p_dec->p_mpeg2dec, 1 ); - p_dec->b_skip = 1; + mpeg2_skip( p_sys->p_mpeg2dec, 1 ); + p_sys->b_skip = 1; - if( p_dec->p_info->current_fbuf && - p_dec->p_info->current_fbuf->id ) + if( p_sys->p_info->current_fbuf && + p_sys->p_info->current_fbuf->id ) { - p_dec->b_garbage_pic = 1; - p_pic = p_dec->p_info->current_fbuf->id; + p_sys->b_garbage_pic = 1; + p_pic = p_sys->p_info->current_fbuf->id; } else { if( (p_pic = GetNewPicture( p_dec, buf )) == NULL ) break; - mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic ); + mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic ); } - p_dec->p_picture_to_destroy = p_pic; + p_sys->p_picture_to_destroy = p_pic; memset( p_pic->p[0].p_pixels, 0, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height ); memset( p_pic->p[1].p_pixels, 0x80, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height / 4 ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); memset( p_pic->p[2].p_pixels, 0x80, - p_dec->p_info->sequence->width - * p_dec->p_info->sequence->height / 4 ); + p_sys->p_info->sequence->width + * p_sys->p_info->sequence->height / 4 ); - if ( p_dec->b_slice_i ) + if ( p_sys->b_slice_i ) { - vout_SynchroNewPicture( p_dec->p_synchro, - I_CODING_TYPE, 2, 0, 0, p_dec->i_current_rate ); - vout_SynchroDecode( p_dec->p_synchro ); - vout_SynchroEnd( p_dec->p_synchro, I_CODING_TYPE, 0 ); + vout_SynchroNewPicture( p_sys->p_synchro, + I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate ); + vout_SynchroDecode( p_sys->p_synchro ); + vout_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); } break; } @@ -503,86 +510,68 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) } } - /* If b_error is set, the libmpeg2 decoder thread enters the error loop */ - if( p_dec->p_fifo->b_error ) - { - DecoderError( p_dec->p_fifo ); - } - - /* End of the libmpeg2 decoder thread */ - CloseDecoder( p_dec ); - - return 0; - - error: - DecoderError( p_fifo ); - if( p_dec ) - { - if( p_dec->p_fifo ) - p_dec->p_fifo->b_error = 1; - - /* End of the libmpeg2 decoder thread */ - CloseDecoder( p_dec ); - } - - return -1; + block_Release( p_block ); + return VLC_EGENERIC; } /***************************************************************************** - * CloseDecoder: libmpeg2 decoder destruction + * EndDecoder: libmpeg2 decoder destruction *****************************************************************************/ -static void CloseDecoder( dec_thread_t * p_dec ) +static int EndDecoder( decoder_t * p_dec ) { - if( p_dec ) + decoder_sys_t *p_sys = p_dec->p_sys; + + if( p_sys ) { int i_pic; - if( p_dec->p_pes ) - input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_dec->p_pes ); - - if( p_dec->p_synchro ) - vout_SynchroRelease( p_dec->p_synchro ); + if( p_sys->p_synchro ) + vout_SynchroRelease( p_sys->p_synchro ); - if( p_dec->p_vout ) + if( p_sys->p_vout ) { /* Temporary hack to free the pictures in use by libmpeg2 */ - for( i_pic = 0; i_pic < p_dec->p_vout->render.i_pictures; i_pic++ ) + for( i_pic = 0; i_pic < p_sys->p_vout->render.i_pictures; i_pic++ ) { - if( p_dec->p_vout->render.pp_picture[i_pic]->i_status == + if( p_sys->p_vout->render.pp_picture[i_pic]->i_status == RESERVED_PICTURE ) - vout_DestroyPicture( p_dec->p_vout, - p_dec->p_vout->render.pp_picture[i_pic] ); - if( p_dec->p_vout->render.pp_picture[i_pic]->i_refcount > 0 ) - vout_UnlinkPicture( p_dec->p_vout, - p_dec->p_vout->render.pp_picture[i_pic] ); + vout_DestroyPicture( p_sys->p_vout, + p_sys->p_vout->render.pp_picture[i_pic] ); + if( p_sys->p_vout->render.pp_picture[i_pic]->i_refcount > 0 ) + vout_UnlinkPicture( p_sys->p_vout, + p_sys->p_vout->render.pp_picture[i_pic] ); } - vout_Request( p_dec->p_fifo, p_dec->p_vout, 0, 0, 0, 0 ); + vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 ); } - if( p_dec->p_mpeg2dec ) mpeg2_close( p_dec->p_mpeg2dec ); + if( p_sys->p_mpeg2dec ) mpeg2_close( p_sys->p_mpeg2dec ); - free( p_dec ); + free( p_sys ); } + + return VLC_SUCCESS; } /***************************************************************************** * GetNewPicture: Get a new picture from the vout and set the buf struct *****************************************************************************/ -static picture_t *GetNewPicture( dec_thread_t *p_dec, uint8_t **pp_buf ) +static picture_t *GetNewPicture( decoder_t *p_dec, uint8_t **pp_buf ) { + decoder_sys_t *p_sys = p_dec->p_sys; + picture_t *p_pic; - vlc_bool_t b_progressive = p_dec->p_info->current_picture != NULL ? - p_dec->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : + vlc_bool_t b_progressive = p_sys->p_info->current_picture != NULL ? + p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME : 1; - vlc_bool_t b_top_field_first = p_dec->p_info->current_picture != NULL ? - p_dec->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : + vlc_bool_t b_top_field_first = p_sys->p_info->current_picture != NULL ? + p_sys->p_info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST : 1; - unsigned int i_nb_fields = p_dec->p_info->current_picture != NULL ? - p_dec->p_info->current_picture->nb_fields : 2; + unsigned int i_nb_fields = p_sys->p_info->current_picture != NULL ? + p_sys->p_info->current_picture->nb_fields : 2; /* Get a new picture */ - while( !(p_pic = vout_CreatePicture( p_dec->p_vout, + while( !(p_pic = vout_CreatePicture( p_sys->p_vout, b_progressive, b_top_field_first, i_nb_fields )) ) { if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) @@ -592,7 +581,7 @@ static picture_t *GetNewPicture( dec_thread_t *p_dec, uint8_t **pp_buf ) } if( p_pic == NULL ) return NULL; - vout_LinkPicture( p_dec->p_vout, p_pic ); + vout_LinkPicture( p_sys->p_vout, p_pic ); pp_buf[0] = p_pic->p[0].p_pixels; pp_buf[1] = p_pic->p[1].p_pixels; diff --git a/modules/codec/lpcm.c b/modules/codec/lpcm.c index 055f7e39bd..fc73cc36be 100644 --- a/modules/codec/lpcm.c +++ b/modules/codec/lpcm.c @@ -2,7 +2,7 @@ * lpcm.c: lpcm decoder module ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: lpcm.c,v 1.16 2003/06/10 23:01:40 massiot Exp $ + * $Id: lpcm.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Samuel Hocevar * Henri Fallon @@ -102,15 +102,15 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('l','p','c','m') - && p_fifo->i_fourcc != VLC_FOURCC('l','p','c','b') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('l','p','c','m') + && p_dec->p_fifo->i_fourcc != VLC_FOURCC('l','p','c','b') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } diff --git a/modules/codec/mpeg_audio.c b/modules/codec/mpeg_audio.c index 972f82dc24..0a72022918 100644 --- a/modules/codec/mpeg_audio.c +++ b/modules/codec/mpeg_audio.c @@ -2,7 +2,7 @@ * mpeg_audio.c: parse MPEG audio sync info and packetize the stream ***************************************************************************** * Copyright (C) 2001-2003 VideoLAN - * $Id: mpeg_audio.c,v 1.16 2003/06/25 00:40:41 fenrir Exp $ + * $Id: mpeg_audio.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * Eric Petit @@ -94,14 +94,14 @@ vlc_module_end(); *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } diff --git a/modules/codec/quicktime.c b/modules/codec/quicktime.c index d1d6d52e4b..968e8b5154 100644 --- a/modules/codec/quicktime.c +++ b/modules/codec/quicktime.c @@ -2,7 +2,7 @@ * quicktime.c: a quicktime decoder that uses the QT library/dll ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: quicktime.c,v 1.11 2003/08/17 23:02:51 fenrir Exp $ + * $Id: quicktime.c,v 1.12 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * Derk-Jan Hartman @@ -273,9 +273,9 @@ static int GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes ) *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - switch( p_fifo->i_fourcc ) + switch( p_dec->p_fifo->i_fourcc ) { case VLC_FOURCC('S','V','Q','3'): /* Sorenson v3 */ /* case VLC_FOURCC('S','V','Q','1'): Sorenson v1 @@ -285,7 +285,7 @@ static int OpenDecoder( vlc_object_t *p_this ) case VLC_FOURCC('r','l','e',' '): /* QuickTime animation (RLE) */ case VLC_FOURCC('r','p','z','a'): /* QuickTime Apple Video */ case VLC_FOURCC('a','z','p','r'): /* QuickTime animation (RLE) */ - p_fifo->pf_run = RunDecoderVideo; + p_dec->pf_run = RunDecoderVideo; return VLC_SUCCESS; case VLC_FOURCC('m','p','4','a'): /* MPEG-4 audio */ @@ -309,7 +309,7 @@ static int OpenDecoder( vlc_object_t *p_this ) case 0x6D730002: /* Microsoft ADPCM-ACM */ case 0x6D730011: /* DVI Intel IMAADPCM-ACM */ - p_fifo->pf_run = RunDecoderAudio; + p_dec->pf_run = RunDecoderAudio; return VLC_SUCCESS; default: return VLC_EGENERIC; diff --git a/modules/codec/rawvideo.c b/modules/codec/rawvideo.c index bb2817f71f..eb8a1d14ac 100644 --- a/modules/codec/rawvideo.c +++ b/modules/codec/rawvideo.c @@ -2,7 +2,7 @@ * rawvideo.c: Pseudo audio decoder; for raw video data ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: rawvideo.c,v 1.5 2003/05/02 03:40:01 fenrir Exp $ + * $Id: rawvideo.c,v 1.6 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Laurent Aimar * @@ -76,9 +76,9 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - switch( p_fifo->i_fourcc ) + switch( p_dec->p_fifo->i_fourcc ) { /* Planar YUV */ case VLC_FOURCC('I','4','4','4'): @@ -99,13 +99,12 @@ static int OpenDecoder( vlc_object_t *p_this ) case VLC_FOURCC('R','V','1','6'): case VLC_FOURCC('R','V','1','5'): - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; default: return VLC_EGENERIC; } - } /***************************************************************************** diff --git a/modules/codec/spudec/spudec.c b/modules/codec/spudec/spudec.c index a31aaf6c42..cd7c7f072c 100644 --- a/modules/codec/spudec/spudec.c +++ b/modules/codec/spudec/spudec.c @@ -2,7 +2,7 @@ * spudec.c : SPU decoder thread ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: spudec.c,v 1.24 2003/07/22 20:49:10 hartman Exp $ + * $Id: spudec.c,v 1.25 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -59,15 +59,15 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ') - && p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ') + && p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } @@ -230,4 +230,3 @@ static void EndThread( spudec_thread_t *p_spudec ) CloseBitstream( &p_spudec->bit_stream ); free( p_spudec ); } - diff --git a/modules/codec/subsdec/subsdec.c b/modules/codec/subsdec/subsdec.c index 2285784bb9..bbaa6bccbf 100644 --- a/modules/codec/subsdec/subsdec.c +++ b/modules/codec/subsdec/subsdec.c @@ -2,7 +2,7 @@ * subsdec.c : SPU decoder thread ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: subsdec.c,v 1.8 2003/08/27 12:24:52 sigmunau Exp $ + * $Id: subsdec.c,v 1.9 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Gildas Bazin * Samuel Hocevar @@ -95,14 +95,14 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; var_Create( p_this, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); #if defined(HAVE_ICONV) diff --git a/modules/codec/tarkin.c b/modules/codec/tarkin.c index ea27d15978..f2b81c217c 100644 --- a/modules/codec/tarkin.c +++ b/modules/codec/tarkin.c @@ -2,7 +2,7 @@ * tarkin.c: tarkin decoder module making use of libtarkin. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: tarkin.c,v 1.4 2002/11/28 21:00:48 gbazin Exp $ + * $Id: tarkin.c,v 1.5 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Gildas Bazin * @@ -103,14 +103,14 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('t','a','r','k') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','a','r','k') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } diff --git a/modules/codec/theora.c b/modules/codec/theora.c index 41b607716d..bbc6917ce6 100644 --- a/modules/codec/theora.c +++ b/modules/codec/theora.c @@ -2,7 +2,7 @@ * theora.c: theora decoder module making use of libtheora. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: theora.c,v 1.5 2003/06/11 15:53:50 gbazin Exp $ + * $Id: theora.c,v 1.6 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Gildas Bazin * @@ -24,27 +24,32 @@ /***************************************************************************** * Preamble *****************************************************************************/ +#include /* malloc(), free() */ +#include /* memcpy(), memset() */ + #include #include -#include #include - -#include /* malloc(), free() */ -#include /* memcpy(), memset() */ +#include +#include +#include #include #include /***************************************************************************** - * dec_thread_t : theora decoder thread descriptor + * decoder_sys_t : theora decoder descriptor *****************************************************************************/ -typedef struct dec_thread_t +struct decoder_sys_t { + /* Module mode */ + vlc_bool_t b_packetizer; + /* - * Thread properties + * Input properties */ - vlc_thread_t thread_id; /* id for thread functions */ + int i_headers; /* * Theora properties @@ -54,29 +59,39 @@ typedef struct dec_thread_t theora_state td; /* theora bitstream user comments */ /* - * Input properties + * Output properties */ - decoder_fifo_t *p_fifo; /* stores the PES stream data */ - pes_packet_t *p_pes; /* current PES we are decoding */ + vout_thread_t *p_vout; /* - * Output properties + * Packetizer output properties */ - vout_thread_t *p_vout; + sout_packetizer_input_t *p_sout_input; + sout_format_t sout_format; -} dec_thread_t; + /* + * Common properties + */ + mtime_t i_pts; +}; /***************************************************************************** * Local prototypes *****************************************************************************/ -static int OpenDecoder ( vlc_object_t * ); -static int RunDecoder ( decoder_fifo_t * ); -static void CloseDecoder ( dec_thread_t * ); +static int OpenDecoder ( vlc_object_t * ); +static int OpenPacketizer( vlc_object_t * ); + +static int InitDecoder ( decoder_t * ); +static int RunDecoder ( decoder_t *, block_t * ); +static int EndDecoder ( decoder_t * ); -static void DecodePacket ( dec_thread_t * ); -static int GetOggPacket ( dec_thread_t *, ogg_packet *, mtime_t * ); +static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t ); +static int DecodePacket ( decoder_t *, ogg_packet * ); +static int SendPacket ( decoder_t *, ogg_packet * ); -static void theora_CopyPicture( dec_thread_t *, picture_t *, yuv_buffer * ); +static void ParseTheoraComments( decoder_t * ); + +static void theora_CopyPicture( decoder_t *, picture_t *, yuv_buffer * ); /***************************************************************************** * Module descriptor @@ -86,6 +101,12 @@ vlc_module_begin(); set_capability( "decoder", 100 ); set_callbacks( OpenDecoder, NULL ); add_shortcut( "theora" ); + + add_submodule(); + set_description( _("Theora video packetizer") ); + set_capability( "packetizer", 100 ); + set_callbacks( OpenPacketizer, NULL ); + add_shortcut( "theora" ); vlc_module_end(); /***************************************************************************** @@ -93,224 +114,375 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('t','h','e','o') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('t','h','e','o') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_init = InitDecoder; + p_dec->pf_decode = RunDecoder; + p_dec->pf_end = EndDecoder; + + /* Allocate the memory needed to store the decoder's structure */ + if( ( p_dec->p_sys = + (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) + { + msg_Err( p_dec, "out of memory" ); + return VLC_EGENERIC; + } + p_dec->p_sys->b_packetizer = VLC_FALSE; + return VLC_SUCCESS; } + +static int OpenPacketizer( vlc_object_t *p_this ) +{ + decoder_t *p_dec = (decoder_t*)p_this; + + int i_ret = OpenDecoder( p_this ); + + if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE; + + return i_ret; +} + /***************************************************************************** - * RunDecoder: the theora decoder + * InitDecoder: Initalize the decoder *****************************************************************************/ -static int RunDecoder( decoder_fifo_t *p_fifo ) +static int InitDecoder( decoder_t *p_dec ) { - dec_thread_t *p_dec; - ogg_packet oggpacket; - int i_chroma, i_aspect; - mtime_t i_pts; + decoder_sys_t *p_sys = p_dec->p_sys; - /* Allocate the memory needed to store the thread's structure */ - if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) ) - == NULL) - { - msg_Err( p_fifo, "out of memory" ); - goto error; - } + p_sys->i_pts = 0; - /* Initialize the thread properties */ - memset( p_dec, 0, sizeof(dec_thread_t) ); - p_dec->p_fifo = p_fifo; - p_dec->p_pes = NULL; - p_dec->p_vout = NULL; + p_sys->p_sout_input = NULL; + p_sys->sout_format.i_cat = VIDEO_ES; + p_sys->sout_format.i_fourcc = VLC_FOURCC( 't', 'h', 'e', 'o' ); + p_sys->sout_format.i_width = 0; + p_sys->sout_format.i_height = 0; + p_sys->sout_format.i_bitrate = 0; + p_sys->sout_format.i_extra_data = 0; + p_sys->sout_format.p_extra_data = NULL; /* Init supporting Theora structures needed in header parsing */ - theora_comment_init( &p_dec->tc ); - theora_info_init( &p_dec->ti ); - - /* Take care of the initial Theora header */ - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; + theora_comment_init( &p_sys->tc ); + theora_info_init( &p_sys->ti ); - oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */ - if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 ) - { - msg_Err( p_dec->p_fifo, "This bitstream does not contain Theora " - "video data" ); - goto error; - } + p_sys->i_headers = 0; - /* The next two packets in order are the comment and codebook headers. - We need to watch out that these packets are not missing as a - missing or corrupted header is fatal. */ - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; + return VLC_SUCCESS; +} - if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 ) - { - msg_Err( p_dec->p_fifo, "2nd Theora header is corrupted" ); - goto error; - } +/**************************************************************************** + * RunDecoder: the whole thing + **************************************************************************** + * This function must be fed with ogg packets. + ****************************************************************************/ +static int RunDecoder( decoder_t *p_dec, block_t *p_block ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + ogg_packet oggpacket; + int i_ret; - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; + /* Block to Ogg packet */ + oggpacket.packet = p_block->p_buffer; + oggpacket.bytes = p_block->i_buffer; + oggpacket.granulepos = p_block->i_dts; + oggpacket.b_o_s = 0; + oggpacket.e_o_s = 0; + oggpacket.packetno = 0; - if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 ) + if( p_sys->i_headers == 0 ) { - msg_Err( p_dec->p_fifo, "3rd Theora header is corrupted" ); - goto error; - } + /* Take care of the initial Theora header */ - /* We have all the headers, initialize decoder */ - theora_decode_init( &p_dec->td, &p_dec->ti ); - msg_Dbg( p_dec->p_fifo, "%dx%d %.02f fps video, frame content is %dx%d " - "with offset (%d,%d)", - p_dec->ti.width, p_dec->ti.height, - (double)p_dec->ti.fps_numerator/p_dec->ti.fps_denominator, - p_dec->ti.frame_width, p_dec->ti.frame_height, - p_dec->ti.offset_x, p_dec->ti.offset_y ); - - /* Initialize video output */ - if( p_dec->ti.aspect_denominator ) - i_aspect = VOUT_ASPECT_FACTOR * p_dec->ti.aspect_numerator / - p_dec->ti.aspect_denominator; - else - i_aspect = VOUT_ASPECT_FACTOR * p_dec->ti.width / p_dec->ti.height; + oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */ + if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 ) + { + msg_Err( p_dec->p_fifo, "This bitstream does not contain Theora " + "video data" ); + block_Release( p_block ); + return VLC_EGENERIC; + } + p_sys->i_headers++; - i_chroma = VLC_FOURCC('Y','V','1','2'); + + if( p_sys->b_packetizer ) + { + /* add a input for the stream ouput */ + p_sys->sout_format.i_width = p_sys->ti.width; + p_sys->sout_format.i_height = p_sys->ti.height; + + p_sys->p_sout_input = + sout_InputNew( p_dec, &p_sys->sout_format ); + + if( !p_sys->p_sout_input ) + { + msg_Err( p_dec, "cannot add a new stream" ); + block_Release( p_block ); + return VLC_EGENERIC; + } + } + else + { + /* Initialize video output */ + int i_chroma, i_aspect; + + if( p_sys->ti.aspect_denominator ) + i_aspect = VOUT_ASPECT_FACTOR * p_sys->ti.aspect_numerator / + p_sys->ti.aspect_denominator; + else + i_aspect = VOUT_ASPECT_FACTOR * + p_sys->ti.frame_width / p_sys->ti.frame_height; + + i_chroma = VLC_FOURCC('Y','V','1','2'); + + p_sys->p_vout = + vout_Request( p_dec, NULL, + p_sys->ti.frame_width, p_sys->ti.frame_height, + i_chroma, i_aspect ); + if( p_sys->p_vout == NULL ) + { + msg_Err( p_dec, "failed to create video output" ); + block_Release( p_block ); + return VLC_EGENERIC; + } + } - p_dec->p_vout = vout_Request( p_dec->p_fifo, p_dec->p_vout, - p_dec->ti.width, p_dec->ti.height, - i_chroma, i_aspect ); + msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content " + "is %dx%d with offset (%d,%d)", + p_sys->ti.width, p_sys->ti.height, + (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator, + p_sys->ti.frame_width, p_sys->ti.frame_height, + p_sys->ti.offset_x, p_sys->ti.offset_y ); - /* theora decoder thread's main loop */ - while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) ) + if( p_sys->b_packetizer ) + { + i_ret = SendPacket( p_dec, &oggpacket ); + block_Release( p_block ); + return i_ret; + } + else + { + block_Release( p_block ); + return VLC_SUCCESS; + } + } + + if( p_sys->i_headers == 1 ) { - DecodePacket( p_dec ); + /* The next packet in order is the comments header */ + if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 ) + { + msg_Err( p_dec, "2nd Theora header is corrupted" ); + return VLC_EGENERIC; + } + p_sys->i_headers++; + + ParseTheoraComments( p_dec ); + + if( p_sys->b_packetizer ) + { + i_ret = SendPacket( p_dec, &oggpacket ); + block_Release( p_block ); + return i_ret; + } + else + { + block_Release( p_block ); + return VLC_SUCCESS; + } } - /* If b_error is set, the theora decoder thread enters the error loop */ - if( p_dec->p_fifo->b_error ) + if( p_sys->i_headers == 2 ) { - DecoderError( p_dec->p_fifo ); + /* The next packet in order is the codebooks header + We need to watch out that this packet is not missing as a + missing or corrupted header is fatal. */ + if( theora_decode_header( &p_sys->ti, &p_sys->tc, &oggpacket ) < 0 ) + { + msg_Err( p_dec, "3rd Theora header is corrupted" ); + return VLC_EGENERIC; + } + p_sys->i_headers++; + + if( !p_sys->b_packetizer ) + { + /* We have all the headers, initialize decoder */ + theora_decode_init( &p_sys->td, &p_sys->ti ); + } + + if( p_sys->b_packetizer ) + { + i_ret = SendPacket( p_dec, &oggpacket ); + block_Release( p_block ); + return i_ret; + } + else + { + block_Release( p_block ); + return VLC_SUCCESS; + } } - /* End of the theora decoder thread */ - CloseDecoder( p_dec ); + i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts ); + block_Release( p_block ); + return i_ret; +} - return 0; +/***************************************************************************** + * ProcessPacket: processes a Vorbis packet. + *****************************************************************************/ +static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket, + mtime_t i_pts ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; - error: - DecoderError( p_fifo ); - if( p_dec ) + /* Date management */ + if( i_pts > 0 && i_pts != p_sys->i_pts ) { - if( p_dec->p_fifo ) - p_dec->p_fifo->b_error = 1; - - /* End of the theora decoder thread */ - CloseDecoder( p_dec ); + p_sys->i_pts = i_pts; } - return -1; + if( p_sys->b_packetizer ) + { + return SendPacket( p_dec, p_oggpacket ); + } + else + { + return DecodePacket( p_dec, p_oggpacket ); + } } /***************************************************************************** * DecodePacket: decodes a Theora packet. *****************************************************************************/ -static void DecodePacket( dec_thread_t *p_dec ) +static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket ) { - ogg_packet oggpacket; picture_t *p_pic; - mtime_t i_pts; yuv_buffer yuv; - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - { - /* This should mean an eos */ - return; - } + decoder_sys_t *p_sys = p_dec->p_sys; - theora_decode_packetin( &p_dec->td, &oggpacket ); + theora_decode_packetin( &p_sys->td, p_oggpacket ); /* Decode */ - theora_decode_YUVout( &p_dec->td, &yuv ); + theora_decode_YUVout( &p_sys->td, &yuv ); /* Get a new picture */ - while( !(p_pic = vout_CreatePicture( p_dec->p_vout, 0, 0, 0 ) ) ) + while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) ) { if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) { - return; + return VLC_EGENERIC; } msleep( VOUT_OUTMEM_SLEEP ); } - if( !p_pic ) - return; + if( !p_pic ) return VLC_EGENERIC; theora_CopyPicture( p_dec, p_pic, &yuv ); - vout_DatePicture( p_dec->p_vout, p_pic, i_pts ); - vout_DisplayPicture( p_dec->p_vout, p_pic ); + vout_DatePicture( p_sys->p_vout, p_pic, p_sys->i_pts ); + vout_DisplayPicture( p_sys->p_vout, p_pic ); + + /* Date management */ + p_sys->i_pts += ( 1000000 * p_sys->ti.fps_numerator / + p_sys->ti.fps_denominator ); /* 1 frame per packet */ + + return VLC_SUCCESS; } /***************************************************************************** - * GetOggPacket: get the following theora packet from the stream and send back - * the result in an ogg packet (for easy decoding by libtheora). - ***************************************************************************** - * Returns VLC_EGENERIC in case of eof. + * SendPacket: send an ogg packet to the stream output. *****************************************************************************/ -static int GetOggPacket( dec_thread_t *p_dec, ogg_packet *p_oggpacket, - mtime_t *p_pts ) +static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket ) { - if( p_dec->p_pes ) input_DeletePES( p_dec->p_fifo->p_packets_mgt, - p_dec->p_pes ); + decoder_sys_t *p_sys = p_dec->p_sys; + + sout_buffer_t *p_sout_buffer = + sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes ); - input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes ); - if( !p_dec->p_pes ) return VLC_EGENERIC; + if( !p_sout_buffer ) return VLC_EGENERIC; - p_oggpacket->packet = p_dec->p_pes->p_first->p_payload_start; - p_oggpacket->bytes = p_dec->p_pes->i_pes_size; - p_oggpacket->granulepos = p_dec->p_pes->i_dts; - p_oggpacket->b_o_s = 0; - p_oggpacket->e_o_s = 0; - p_oggpacket->packetno = 0; + p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer, + p_oggpacket->packet, + p_oggpacket->bytes ); - *p_pts = p_dec->p_pes->i_pts; + /* Date management */ + p_sout_buffer->i_dts = p_sout_buffer->i_pts = p_sys->i_pts; + p_sys->i_pts += ( 1000000 * p_sys->ti.fps_numerator / + p_sys->ti.fps_denominator ); /* 1 frame per packet */ + + if( p_sys->i_headers >= 3 ) + p_sout_buffer->i_length = p_sys->i_pts - p_sout_buffer->i_pts; + else + p_sout_buffer->i_length = 0; + + sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer ); return VLC_SUCCESS; } /***************************************************************************** - * CloseDecoder: theora decoder destruction + * ParseTheoraComments: FIXME should be done in demuxer *****************************************************************************/ -static void CloseDecoder( dec_thread_t * p_dec ) +static void ParseTheoraComments( decoder_t *p_dec ) { - - if( p_dec ) + input_thread_t *p_input = (input_thread_t *)p_dec->p_parent; + input_info_category_t *p_cat = + input_InfoCategory( p_input, _("Theora Comment") ); + int i = 0; + char *psz_name, *psz_value, *psz_comment; + while ( i < p_dec->p_sys->tc.comments ) { - if( p_dec->p_pes ) - input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_dec->p_pes ); + psz_comment = strdup( p_dec->p_sys->tc.user_comments[i] ); + if( !psz_comment ) + { + msg_Warn( p_dec, "Out of memory" ); + break; + } + psz_name = psz_comment; + psz_value = strchr( psz_comment, '=' ); + if( psz_value ) + { + *psz_value = '\0'; + psz_value++; + input_AddInfo( p_cat, psz_name, psz_value ); + } + free( psz_comment ); + i++; + } +} + +/***************************************************************************** + * EndDecoder: theora decoder destruction + *****************************************************************************/ +static int EndDecoder( decoder_t *p_dec ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; - vout_Request( p_dec->p_fifo, p_dec->p_vout, 0, 0, 0, 0 ); + if( !p_sys->b_packetizer ) + vout_Request( p_dec, p_sys->p_vout, 0, 0, 0, 0 ); - theora_info_clear( &p_dec->ti ); - theora_comment_clear( &p_dec->tc ); + theora_info_clear( &p_sys->ti ); + theora_comment_clear( &p_sys->tc ); - free( p_dec ); - } + free( p_sys ); + + return VLC_SUCCESS; } /***************************************************************************** * theora_CopyPicture: copy a picture from theora internal buffers to a * picture_t structure. *****************************************************************************/ -static void theora_CopyPicture( dec_thread_t *p_dec, picture_t *p_pic, +static void theora_CopyPicture( decoder_t *p_dec, picture_t *p_pic, yuv_buffer *yuv ) { int i_plane, i_line, i_width, i_dst_stride, i_src_stride; + int i_src_xoffset, i_src_yoffset; u8 *p_dst, *p_src; for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ ) @@ -318,12 +490,21 @@ static void theora_CopyPicture( dec_thread_t *p_dec, picture_t *p_pic, p_dst = p_pic->p[i_plane].p_pixels; p_src = i_plane ? (i_plane - 1 ? yuv->v : yuv->u ) : yuv->y; i_width = p_pic->p[i_plane].i_visible_pitch; - i_dst_stride = p_pic->p[i_plane].i_pitch; - i_src_stride = i_plane ? yuv->uv_stride : yuv->y_stride; + i_dst_stride = p_pic->p[i_plane].i_pitch; + i_src_stride = i_plane ? yuv->uv_stride : yuv->y_stride; + i_src_xoffset = p_dec->p_sys->ti.offset_x; + i_src_yoffset = p_dec->p_sys->ti.offset_y; + if( i_plane ) + { + i_src_xoffset /= 2; + i_src_yoffset /= 2; + } + + p_src += (i_src_yoffset * i_src_stride + i_src_yoffset); for( i_line = 0; i_line < p_pic->p[i_plane].i_lines; i_line++ ) { - p_dec->p_fifo->p_vlc->pf_memcpy( p_dst, p_src, i_width ); + p_dec->p_vlc->pf_memcpy( p_dst, p_src, i_width ); p_src += i_src_stride; p_dst += i_dst_stride; } diff --git a/modules/codec/vorbis.c b/modules/codec/vorbis.c index 84e4ea9d18..05ee7eceb4 100644 --- a/modules/codec/vorbis.c +++ b/modules/codec/vorbis.c @@ -2,7 +2,7 @@ * vorbis.c: vorbis decoder module making use of libvorbis. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: vorbis.c,v 1.16 2003/03/30 18:14:36 gbazin Exp $ + * $Id: vorbis.c,v 1.17 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Gildas Bazin * @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -42,14 +44,17 @@ #endif /***************************************************************************** - * dec_thread_t : vorbis decoder thread descriptor + * decoder_sys_t : vorbis decoder descriptor *****************************************************************************/ -typedef struct dec_thread_t +struct decoder_sys_t { + /* Module mode */ + vlc_bool_t b_packetizer; + /* - * Thread properties + * Input properties */ - vlc_thread_t thread_id; /* id for thread functions */ + int i_headers; /* * Vorbis properties @@ -62,21 +67,26 @@ typedef struct dec_thread_t * decoder */ vorbis_block vb; /* local working space for packet->PCM decode */ - /* - * Input properties - */ - decoder_fifo_t *p_fifo; /* stores the PES stream data */ - pes_packet_t *p_pes; /* current PES we are decoding */ - /* * Output properties */ aout_instance_t *p_aout; aout_input_t *p_aout_input; - audio_sample_format_t output_format; - audio_date_t end_date; + audio_sample_format_t aout_format; -} dec_thread_t; + /* + * Packetizer output properties + */ + sout_packetizer_input_t *p_sout_input; + sout_format_t sout_format; + + /* + * Common properties + */ + audio_date_t end_date; + int i_last_block_size; + +}; static int pi_channels_maps[6] = { @@ -89,15 +99,21 @@ static int pi_channels_maps[6] = | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT }; -/***************************************************************************** +/**************************************************************************** * Local prototypes - *****************************************************************************/ -static int OpenDecoder ( vlc_object_t * ); -static int RunDecoder ( decoder_fifo_t * ); -static void CloseDecoder ( dec_thread_t * ); + ****************************************************************************/ +static int OpenDecoder ( vlc_object_t * ); +static int OpenPacketizer( vlc_object_t * ); + +static int InitDecoder ( decoder_t * ); +static int RunDecoder ( decoder_t *, block_t * ); +static int EndDecoder ( decoder_t * ); -static void DecodePacket ( dec_thread_t * ); -static int GetOggPacket ( dec_thread_t *, ogg_packet *, mtime_t * ); +static int ProcessPacket ( decoder_t *, ogg_packet *, mtime_t ); +static int DecodePacket ( decoder_t *, ogg_packet * ); +static int SendPacket ( decoder_t *, ogg_packet * ); + +static void ParseVorbisComments( decoder_t * ); #ifdef MODULE_NAME_IS_tremor static void Interleave ( int32_t *, const int32_t **, int, int ); @@ -116,6 +132,11 @@ vlc_module_begin(); set_capability( "decoder", 100 ); #endif set_callbacks( OpenDecoder, NULL ); + + add_submodule(); + set_description( _("Vorbis audio packetizer") ); + set_capability( "packetizer", 100 ); + set_callbacks( OpenPacketizer, NULL ); vlc_module_end(); /***************************************************************************** @@ -123,256 +144,381 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('v','o','r','b') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('v','o','r','b') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_init = InitDecoder; + p_dec->pf_decode = RunDecoder; + p_dec->pf_end = EndDecoder; + + /* Allocate the memory needed to store the decoder's structure */ + if( ( p_dec->p_sys = + (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) + { + msg_Err( p_dec, "out of memory" ); + return VLC_EGENERIC; + } + p_dec->p_sys->b_packetizer = VLC_FALSE; + return VLC_SUCCESS; } +static int OpenPacketizer( vlc_object_t *p_this ) +{ + decoder_t *p_dec = (decoder_t*)p_this; + + int i_ret = OpenDecoder( p_this ); + + if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE; + + return i_ret; +} + /***************************************************************************** - * RunDecoder: the vorbis decoder + * InitDecoder: Initalize the decoder *****************************************************************************/ -static int RunDecoder( decoder_fifo_t * p_fifo ) +static int InitDecoder( decoder_t *p_dec ) { - dec_thread_t *p_dec; - ogg_packet oggpacket; - mtime_t i_pts; + decoder_sys_t *p_sys = p_dec->p_sys; - /* Allocate the memory needed to store the thread's structure */ - if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) ) - == NULL) - { - msg_Err( p_fifo, "out of memory" ); - goto error; - } + aout_DateSet( &p_sys->end_date, 0 ); - /* Initialize the thread properties */ - memset( p_dec, 0, sizeof(dec_thread_t) ); - p_dec->p_fifo = p_fifo; - p_dec->p_pes = NULL; + p_sys->p_aout = NULL; + p_sys->p_aout_input = NULL; + p_sys->aout_format.i_format = VLC_FOURCC('v','o','r','b'); - /* Take care of the initial Vorbis header */ - vorbis_info_init( &p_dec->vi ); - vorbis_comment_init( &p_dec->vc ); + p_sys->p_sout_input = NULL; + p_sys->sout_format.i_cat = AUDIO_ES; + p_sys->sout_format.i_fourcc = VLC_FOURCC( 'v', 'o', 'r', 'b' ); + p_sys->sout_format.i_block_align = 0; + p_sys->sout_format.i_bitrate = 0; + p_sys->sout_format.i_extra_data = 0; + p_sys->sout_format.p_extra_data = NULL; - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; + /* Take care of vorbis init */ + vorbis_info_init( &p_sys->vi ); + vorbis_comment_init( &p_sys->vc ); - oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */ - if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 ) - { - msg_Err( p_dec->p_fifo, "This bitstream does not contain Vorbis " - "audio data"); - goto error; - } + p_sys->i_headers = 0; - /* The next two packets in order are the comment and codebook headers. - We need to watch out that these packets are not missing as a - missing or corrupted header is fatal. */ - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; + return VLC_SUCCESS; +} - if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 ) - { - msg_Err( p_dec->p_fifo, "2nd Vorbis header is corrupted" ); - goto error; - } - /* parse the vorbis comment. FIXME should be done in demuxer*/ +/**************************************************************************** + * RunDecoder: the whole thing + **************************************************************************** + * This function must be fed with ogg packets. + ****************************************************************************/ +static int RunDecoder( decoder_t *p_dec, block_t *p_block ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; + ogg_packet oggpacket; + int i_ret; + + /* Block to Ogg packet */ + oggpacket.packet = p_block->p_buffer; + oggpacket.bytes = p_block->i_buffer; + oggpacket.granulepos = p_block->i_dts; + oggpacket.b_o_s = 0; + oggpacket.e_o_s = 0; + oggpacket.packetno = 0; + + if( p_sys->i_headers == 0 ) { - input_thread_t *p_input = (input_thread_t *)p_fifo->p_parent; - input_info_category_t *p_cat = input_InfoCategory( p_input, - _("Vorbis Comment") ); - int i = 0; - char *psz_name, *psz_value, *psz_comment; - while ( i < p_dec->vc.comments ) + /* Take care of the initial Vorbis header */ + + oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */ + if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, + &oggpacket ) < 0 ) + { + msg_Err( p_dec->p_fifo, "This bitstream does not contain Vorbis " + "audio data"); + block_Release( p_block ); + return VLC_EGENERIC; + } + p_sys->i_headers++; + + + if( p_sys->b_packetizer ) { - psz_comment = strdup( p_dec->vc.user_comments[i] ); - if ( !psz_comment ) + /* add a input for the stream ouput */ + p_sys->sout_format.i_sample_rate = p_sys->vi.rate; + p_sys->sout_format.i_channels = p_sys->vi.channels; + p_sys->sout_format.i_block_align = 1; + p_sys->sout_format.i_bitrate = p_sys->vi.bitrate_nominal; + + p_sys->p_sout_input = + sout_InputNew( p_dec, &p_sys->sout_format ); + + if( !p_sys->p_sout_input ) { - msg_Warn( p_dec->p_fifo, "Out of memory" ); - break; + msg_Err( p_dec, "cannot add a new stream" ); + block_Release( p_block ); + return VLC_EGENERIC; } - psz_name = psz_comment; - psz_value = strchr( psz_comment, '=' ); - if( psz_value ) + } + else + { +#ifdef MODULE_NAME_IS_tremor + p_sys->aout_format.i_format = VLC_FOURCC('f','i','3','2'); +#else + p_sys->aout_format.i_format = VLC_FOURCC('f','l','3','2'); +#endif + p_sys->aout_format.i_physical_channels = + p_sys->aout_format.i_original_channels = + pi_channels_maps[p_sys->vi.channels]; + p_sys->aout_format.i_rate = p_sys->vi.rate; + + p_sys->p_aout = NULL; + p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout, + &p_sys->aout_format ); + + if( p_sys->p_aout_input == NULL ) { - *psz_value = '\0'; - psz_value++; - input_AddInfo( p_cat, psz_name, psz_value ); + msg_Err( p_dec, "failed to create aout fifo" ); + block_Release( p_block ); + return VLC_EGENERIC; } - free( psz_comment ); - i++; } - } - - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; - if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 ) - { - msg_Err( p_dec->p_fifo, "3rd Vorbis header is corrupted" ); - goto error; - } + aout_DateInit( &p_sys->end_date, p_sys->vi.rate ); - /* Initialize the Vorbis packet->PCM decoder */ - vorbis_synthesis_init( &p_dec->vd, &p_dec->vi ); - vorbis_block_init( &p_dec->vd, &p_dec->vb ); + msg_Dbg( p_dec, "channels:%d samplerate:%ld bitrate:%ld", + p_sys->vi.channels, p_sys->vi.rate, + p_sys->vi.bitrate_nominal ); -#ifdef MODULE_NAME_IS_tremor - p_dec->output_format.i_format = VLC_FOURCC('f','i','3','2'); -#else - p_dec->output_format.i_format = VLC_FOURCC('f','l','3','2'); -#endif - p_dec->output_format.i_physical_channels = - p_dec->output_format.i_original_channels = - pi_channels_maps[p_dec->vi.channels]; - p_dec->output_format.i_rate = p_dec->vi.rate; - - aout_DateInit( &p_dec->end_date, p_dec->vi.rate ); - p_dec->p_aout = NULL; - p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo, - &p_dec->p_aout, - &p_dec->output_format ); - - if( p_dec->p_aout_input == NULL ) - { - msg_Err( p_dec->p_fifo, "failed to create aout fifo" ); - goto error; + if( p_sys->b_packetizer ) + { + i_ret = SendPacket( p_dec, &oggpacket ); + block_Release( p_block ); + return i_ret; + } + else + { + block_Release( p_block ); + return VLC_SUCCESS; + } } - /* vorbis decoder thread's main loop */ - while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) ) + if( p_sys->i_headers == 1 ) { - DecodePacket( p_dec ); + /* The next packet in order is the comments header */ + if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) + < 0 ) + { + msg_Err( p_dec, "2nd Vorbis header is corrupted" ); + return VLC_EGENERIC; + } + p_sys->i_headers++; + + ParseVorbisComments( p_dec ); + + if( p_sys->b_packetizer ) + { + i_ret = SendPacket( p_dec, &oggpacket ); + block_Release( p_block ); + return i_ret; + } + else + { + block_Release( p_block ); + return VLC_SUCCESS; + } } - /* If b_error is set, the vorbis decoder thread enters the error loop */ - if( p_dec->p_fifo->b_error ) + if( p_sys->i_headers == 2 ) { - DecoderError( p_dec->p_fifo ); + /* The next packet in order is the codebooks header + We need to watch out that this packet is not missing as a + missing or corrupted header is fatal. */ + if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) + < 0 ) + { + msg_Err( p_dec, "3rd Vorbis header is corrupted" ); + return VLC_EGENERIC; + } + p_sys->i_headers++; + + if( !p_sys->b_packetizer ) + { + /* Initialize the Vorbis packet->PCM decoder */ + vorbis_synthesis_init( &p_sys->vd, &p_sys->vi ); + vorbis_block_init( &p_sys->vd, &p_sys->vb ); + } + + if( p_sys->b_packetizer ) + { + i_ret = SendPacket( p_dec, &oggpacket ); + block_Release( p_block ); + return i_ret; + } + else + { + block_Release( p_block ); + return VLC_SUCCESS; + } } - /* End of the vorbis decoder thread */ - CloseDecoder( p_dec ); + i_ret = ProcessPacket( p_dec, &oggpacket, p_block->i_pts ); + block_Release( p_block ); + return i_ret; +} - return 0; +/***************************************************************************** + * ProcessPacket: processes a Vorbis packet. + *****************************************************************************/ +static int ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket, + mtime_t i_pts ) +{ + decoder_sys_t *p_sys = p_dec->p_sys; - error: - DecoderError( p_fifo ); - if( p_dec ) + /* Date management */ + if( i_pts > 0 && i_pts != aout_DateGet( &p_sys->end_date ) ) { - if( p_dec->p_fifo ) - p_dec->p_fifo->b_error = 1; - - /* End of the vorbis decoder thread */ - CloseDecoder( p_dec ); + aout_DateSet( &p_sys->end_date, i_pts ); } - return -1; - + if( p_sys->b_packetizer ) + { + return SendPacket( p_dec, p_oggpacket ); + } + else + { + return DecodePacket( p_dec, p_oggpacket ); + } } /***************************************************************************** * DecodePacket: decodes a Vorbis packet. *****************************************************************************/ -static void DecodePacket( dec_thread_t *p_dec ) +static int DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket ) { - aout_buffer_t *p_aout_buffer; - ogg_packet oggpacket; + decoder_sys_t *p_sys = p_dec->p_sys; + int i_samples; + #ifdef MODULE_NAME_IS_tremor int32_t **pp_pcm; #else float **pp_pcm; #endif - int i_samples; - mtime_t i_pts; - if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS ) - { - /* This should mean an eos */ - return; - } - - /* Date management */ - if( i_pts > 0 && i_pts != aout_DateGet( &p_dec->end_date ) ) - { - aout_DateSet( &p_dec->end_date, i_pts ); - } - - if( vorbis_synthesis( &p_dec->vb, &oggpacket ) == 0 ) - vorbis_synthesis_blockin( &p_dec->vd, &p_dec->vb ); + if( vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 ) + vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb ); /* **pp_pcm is a multichannel float vector. In stereo, for * example, pp_pcm[0] is left, and pp_pcm[1] is right. i_samples is * the size of each channel. Convert the float values * (-1.<=range<=1.) to whatever PCM format and write it out */ - while( ( i_samples = vorbis_synthesis_pcmout( &p_dec->vd, &pp_pcm ) ) > 0 ) + while( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 ) { - p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input, + aout_buffer_t *p_aout_buffer; + p_aout_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input, i_samples ); if( !p_aout_buffer ) { - msg_Err( p_dec->p_fifo, "cannot get aout buffer" ); - p_dec->p_fifo->b_error = 1; - return; + msg_Err( p_dec, "cannot get aout buffer" ); + return VLC_SUCCESS; } /* Interleave the samples */ #ifdef MODULE_NAME_IS_tremor Interleave( (int32_t *)p_aout_buffer->p_buffer, - (const int32_t **)pp_pcm, p_dec->vi.channels, i_samples ); + (const int32_t **)pp_pcm, p_sys->vi.channels, i_samples ); #else Interleave( (float *)p_aout_buffer->p_buffer, - (const float **)pp_pcm, p_dec->vi.channels, i_samples ); + (const float **)pp_pcm, p_sys->vi.channels, i_samples ); #endif /* Tell libvorbis how many samples we actually consumed */ - vorbis_synthesis_read( &p_dec->vd, i_samples ); + vorbis_synthesis_read( &p_sys->vd, i_samples ); /* Date management */ - p_aout_buffer->start_date = aout_DateGet( &p_dec->end_date ); - p_aout_buffer->end_date = aout_DateIncrement( &p_dec->end_date, + p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date ); + p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples ); - aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer ); + aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, p_aout_buffer ); } } /***************************************************************************** - * GetOggPacket: get the following vorbis packet from the stream and send back - * the result in an ogg packet (for easy decoding by libvorbis). - ***************************************************************************** - * Returns VLC_EGENERIC in case of eof. + * SendPacket: send an ogg packet to the stream output. *****************************************************************************/ -static int GetOggPacket( dec_thread_t *p_dec, ogg_packet *p_oggpacket, - mtime_t *p_pts ) +static int SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket ) { - if( p_dec->p_pes ) input_DeletePES( p_dec->p_fifo->p_packets_mgt, - p_dec->p_pes ); + decoder_sys_t *p_sys = p_dec->p_sys; + int i_block_size, i_samples; + + sout_buffer_t *p_sout_buffer = + sout_BufferNew( p_sys->p_sout_input->p_sout, p_oggpacket->bytes ); - input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes ); - if( !p_dec->p_pes ) return VLC_EGENERIC; + if( !p_sout_buffer ) return VLC_EGENERIC; - p_oggpacket->packet = p_dec->p_pes->p_first->p_payload_start; - p_oggpacket->bytes = p_dec->p_pes->i_pes_size; - p_oggpacket->granulepos = p_dec->p_pes->i_dts; - p_oggpacket->b_o_s = 0; - p_oggpacket->e_o_s = 0; - p_oggpacket->packetno = 0; + i_block_size = vorbis_packet_blocksize( &p_sys->vi, p_oggpacket ); + if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */ + i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2; + p_sys->i_last_block_size = i_block_size; - *p_pts = p_dec->p_pes->i_pts; + p_dec->p_vlc->pf_memcpy( p_sout_buffer->p_buffer, + p_oggpacket->packet, + p_oggpacket->bytes ); + + p_sout_buffer->i_bitrate = p_sys->vi.bitrate_nominal; + + /* Date management */ + p_sout_buffer->i_dts = p_sout_buffer->i_pts = + aout_DateGet( &p_sys->end_date ); + + if( p_sys->i_headers >= 3 ) + p_sout_buffer->i_length = + aout_DateIncrement( &p_sys->end_date, i_samples ) - + p_sout_buffer->i_pts; + else + p_sout_buffer->i_length = 0; + + sout_InputSendBuffer( p_sys->p_sout_input, p_sout_buffer ); return VLC_SUCCESS; } +/***************************************************************************** + * ParseVorbisComments: FIXME should be done in demuxer + *****************************************************************************/ +static void ParseVorbisComments( decoder_t *p_dec ) +{ + input_thread_t *p_input = (input_thread_t *)p_dec->p_parent; + input_info_category_t *p_cat = + input_InfoCategory( p_input, _("Vorbis Comment") ); + int i = 0; + char *psz_name, *psz_value, *psz_comment; + while ( i < p_dec->p_sys->vc.comments ) + { + psz_comment = strdup( p_dec->p_sys->vc.user_comments[i] ); + if( !psz_comment ) + { + msg_Warn( p_dec, "Out of memory" ); + break; + } + psz_name = psz_comment; + psz_value = strchr( psz_comment, '=' ); + if( psz_value ) + { + *psz_value = '\0'; + psz_value++; + input_AddInfo( p_cat, psz_name, psz_value ); + } + free( psz_comment ); + i++; + } +} + /***************************************************************************** * Interleave: helper function to interleave channels *****************************************************************************/ @@ -395,23 +541,32 @@ static void Interleave( float *p_out, const float **pp_in, } /***************************************************************************** - * CloseDecoder: vorbis decoder destruction + * EndDecoder: vorbis decoder destruction *****************************************************************************/ -static void CloseDecoder( dec_thread_t * p_dec ) +static int EndDecoder( decoder_t * p_dec ) { - if( p_dec->p_aout_input != NULL ) + decoder_sys_t *p_sys = p_dec->p_sys; + + if( p_sys->p_aout_input != NULL ) + { + aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input ); + } + + if( p_sys->p_sout_input != NULL ) { - aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input ); + sout_InputDelete( p_sys->p_sout_input ); } - if( p_dec ) + if( !p_sys->b_packetizer && p_sys->i_headers >= 3 ) { - if( p_dec->p_pes ) - input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_dec->p_pes ); - vorbis_block_clear( &p_dec->vb ); - vorbis_dsp_clear( &p_dec->vd ); - vorbis_comment_clear( &p_dec->vc ); - vorbis_info_clear( &p_dec->vi ); /* must be called last */ - free( p_dec ); + vorbis_block_clear( &p_sys->vb ); + vorbis_dsp_clear( &p_sys->vd ); } + + vorbis_comment_clear( &p_sys->vc ); + vorbis_info_clear( &p_sys->vi ); /* must be called last */ + + free( p_sys ); + + return VLC_SUCCESS; } diff --git a/modules/codec/xvid.c b/modules/codec/xvid.c index ff2fda6daa..acf8a98f79 100644 --- a/modules/codec/xvid.c +++ b/modules/codec/xvid.c @@ -2,7 +2,7 @@ * xvid.c: a decoder for libxvidcore, the Xvid video codec ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: xvid.c,v 1.5 2003/02/20 01:52:45 sigmunau Exp $ + * $Id: xvid.c,v 1.6 2003/09/02 20:19:25 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -59,16 +59,16 @@ vlc_module_end(); *****************************************************************************/ static int OpenDecoder ( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC('x','v','i','d') - && p_fifo->i_fourcc != VLC_FOURCC('X','V','I','D') - && p_fifo->i_fourcc != VLC_FOURCC('D','I','V','X') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('x','v','i','d') + && p_dec->p_fifo->i_fourcc != VLC_FOURCC('X','V','I','D') + && p_dec->p_fifo->i_fourcc != VLC_FOURCC('D','I','V','X') ) { return VLC_EGENERIC; } - p_fifo->pf_run = RunDecoder; + p_dec->pf_run = RunDecoder; return VLC_SUCCESS; } @@ -271,4 +271,3 @@ static int RunDecoder ( decoder_fifo_t *p_fifo ) return VLC_SUCCESS; } - diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c index dcfbf662f2..17aa3cbbe8 100644 --- a/modules/demux/ogg.c +++ b/modules/demux/ogg.c @@ -2,7 +2,7 @@ * ogg.c : ogg stream input module for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: ogg.c,v 1.31 2003/08/17 23:02:52 fenrir Exp $ + * $Id: ogg.c,v 1.32 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Gildas Bazin * @@ -601,7 +601,7 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg) i_keyframe_frequency_force >>= 1; } - p_stream->f_rate = (float)i_fps_numerator / + p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator; msg_Dbg( p_input, "found theora header, bitrate: %i, rate: %f", diff --git a/modules/misc/dummy/decoder.c b/modules/misc/dummy/decoder.c index 86f770f32a..8c2c0aeee6 100644 --- a/modules/misc/dummy/decoder.c +++ b/modules/misc/dummy/decoder.c @@ -2,7 +2,7 @@ * dec_dummy.c: dummy decoder plugin for vlc. ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: decoder.c,v 1.5 2003/03/03 16:49:14 gbazin Exp $ + * $Id: decoder.c,v 1.6 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -56,7 +56,7 @@ static int Run ( decoder_fifo_t * ); *****************************************************************************/ int E_(OpenDecoder) ( vlc_object_t *p_this ) { - ((decoder_fifo_t*)p_this)->pf_run = Run; + ((decoder_t*)p_this)->pf_run = Run; return VLC_SUCCESS; } diff --git a/modules/packetizer/Modules.am b/modules/packetizer/Modules.am index 0f4275c55c..9d3b660f84 100644 --- a/modules/packetizer/Modules.am +++ b/modules/packetizer/Modules.am @@ -1,7 +1,5 @@ SOURCES_packetizer_copy = copy.c -SOURCES_packetizer_a52 = a52.c SOURCES_packetizer_mpegaudio = mpegaudio.c SOURCES_packetizer_mpegvideo = mpegvideo.c SOURCES_packetizer_mpeg4video = mpeg4video.c SOURCES_packetizer_mpeg4audio = mpeg4audio.c -SOURCES_packetizer_vorbis = vorbis.c diff --git a/modules/packetizer/a52.c b/modules/packetizer/a52.c deleted file mode 100644 index 0f768fc9a9..0000000000 --- a/modules/packetizer/a52.c +++ /dev/null @@ -1,377 +0,0 @@ -/***************************************************************************** - * a52.c - ***************************************************************************** - * Copyright (C) 2001, 2002 VideoLAN - * $Id: a52.c,v 1.5 2003/05/03 02:09:41 fenrir Exp $ - * - * Authors: Laurent Aimar - * Eric Petit - * - * 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 - * GNU General Public License for more details. - * - * 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. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include -#include -#include -#include -#include - -#include /* malloc(), free() */ -#include /* strdup() */ -#include "codecs.h" /* WAVEFORMATEX BITMAPINFOHEADER */ -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -typedef struct packetizer_s -{ - /* Input properties */ - decoder_fifo_t *p_fifo; - bit_stream_t bit_stream; - - /* Output properties */ - sout_packetizer_input_t *p_sout_input; - sout_format_t output_format; - - uint64_t i_samplescount; - - mtime_t i_last_pts; -} packetizer_t; - -static int Open ( vlc_object_t * ); -static int Run ( decoder_fifo_t * ); - -static int InitThread ( packetizer_t * ); -static void PacketizeThread ( packetizer_t * ); -static void EndThread ( packetizer_t * ); - -static int SyncInfo( const byte_t *, int *, int *, int * ); - -#define FREE( p ) if( p ) free( p ); p = NULL - -/***************************************************************************** - * Module descriptor - *****************************************************************************/ - -vlc_module_begin(); - set_description( _("A/52 audio packetizer") ); - set_capability( "packetizer", 10 ); - set_callbacks( Open, NULL ); -vlc_module_end(); - - - -/***************************************************************************** - * OpenDecoder: probe the packetizer and return score - ***************************************************************************** - * Tries to launch a decoder and return score so that the interface is able - * to choose. - *****************************************************************************/ -static int Open( vlc_object_t *p_this ) -{ - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; - - if( p_fifo->i_fourcc != VLC_FOURCC( 'a', '5', '2', ' ') && - p_fifo->i_fourcc != VLC_FOURCC( 'a', '5', '2', 'b') ) - { - return VLC_EGENERIC; - } - - p_fifo->pf_run = Run; - return VLC_SUCCESS; -} - -/***************************************************************************** - * RunDecoder: this function is called just after the thread is created - *****************************************************************************/ -static int Run( decoder_fifo_t *p_fifo ) -{ - packetizer_t *p_pack; - int b_error; - - msg_Info( p_fifo, "Running A/52 packetizer" ); - if( !( p_pack = malloc( sizeof( packetizer_t ) ) ) ) - { - msg_Err( p_fifo, "out of memory" ); - DecoderError( p_fifo ); - return( -1 ); - } - memset( p_pack, 0, sizeof( packetizer_t ) ); - - p_pack->p_fifo = p_fifo; - - if( InitThread( p_pack ) != 0 ) - { - DecoderError( p_fifo ); - return( -1 ); - } - - while( ( !p_pack->p_fifo->b_die )&&( !p_pack->p_fifo->b_error ) ) - { - PacketizeThread( p_pack ); - } - - - if( ( b_error = p_pack->p_fifo->b_error ) ) - { - DecoderError( p_pack->p_fifo ); - } - - EndThread( p_pack ); - - if( b_error ) - { - return( -1 ); - } - - return( 0 ); -} - - - -/***************************************************************************** - * InitThread: initialize data before entering main loop - *****************************************************************************/ - -static int InitThread( packetizer_t *p_pack ) -{ - - p_pack->output_format.i_cat = AUDIO_ES; - p_pack->output_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' ); - - p_pack->p_sout_input = NULL; - - p_pack->i_samplescount = 0; - p_pack->i_last_pts = 0; - - if( InitBitstream( &p_pack->bit_stream, p_pack->p_fifo, - NULL, NULL ) != VLC_SUCCESS ) - { - msg_Err( p_pack->p_fifo, "cannot initialize bitstream" ); - return -1; - } - - return( 0 ); -} - -/***************************************************************************** - * PacketizeThread: packetize an unit (here copy a complete pes) - *****************************************************************************/ -static void PacketizeThread( packetizer_t *p_pack ) -{ - sout_buffer_t *p_sout_buffer; - - - uint8_t p_header[7]; - int i_channels, i_samplerate, i_bitrate; - int i_framelength; - mtime_t i_pts; - - /* search a valid start code */ - for( ;; ) - { - int i_skip = 0; - - RealignBits( &p_pack->bit_stream ); - while( ShowBits( &p_pack->bit_stream, 16 ) != 0x0b77 && - !p_pack->p_fifo->b_die && !p_pack->p_fifo->b_error ) - { - RemoveBits( &p_pack->bit_stream, 8 ); - i_skip++; - } - if( i_skip ) - { - msg_Warn( p_pack->p_fifo, "trashing %d bytes", i_skip ); - } - if( p_pack->p_fifo->b_die || p_pack->p_fifo->b_error ) - { - return; - } - - /* Set the Presentation Time Stamp */ - NextPTS( &p_pack->bit_stream, &i_pts, NULL ); - - GetChunk( &p_pack->bit_stream, p_header, 7 ); - if( p_pack->p_fifo->b_die ) return; - - /* Check if frame is valid and get frame info */ - i_framelength = SyncInfo( p_header, &i_channels, &i_samplerate, - &i_bitrate ); - - if( !i_framelength ) - { - msg_Warn( p_pack->p_fifo, "invalid header found" ); - continue; - } - else - { -// msg_Dbg( p_pack->p_fifo, "frame length %d b", i_framelength ); - break; - } - } - - if( !p_pack->p_sout_input ) - { - p_pack->output_format.i_sample_rate = i_samplerate; - p_pack->output_format.i_channels = i_channels; - p_pack->output_format.i_block_align = 0; - p_pack->output_format.i_bitrate = 0; - p_pack->output_format.i_extra_data = 0; - p_pack->output_format.p_extra_data = NULL; - - p_pack->p_sout_input = - sout_InputNew( p_pack->p_fifo, - &p_pack->output_format ); - - if( !p_pack->p_sout_input ) - { - msg_Err( p_pack->p_fifo, - "cannot add a new stream" ); - p_pack->p_fifo->b_error = 1; - return; - } - msg_Info( p_pack->p_fifo, - "A/52 channels:%d samplerate:%d bitrate:%d", - i_channels, i_samplerate, i_bitrate ); - } - - if( i_pts <= 0 && p_pack->i_last_pts <= 0 ) - { - msg_Dbg( p_pack->p_fifo, "need a starting pts" ); - return; - } - - /* fix pts */ - if( i_pts <= 0 ) - { - i_pts = p_pack->i_last_pts + - (uint64_t)1000000 * - (uint64_t)A52_FRAME_NB / - (uint64_t)i_samplerate; - } - p_pack->i_last_pts = i_pts; - - p_sout_buffer = - sout_BufferNew( p_pack->p_sout_input->p_sout, i_framelength ); - if( !p_sout_buffer ) - { - p_pack->p_fifo->b_error = 1; - return; - } - memcpy( p_sout_buffer->p_buffer, p_header, 7 ); - p_sout_buffer->i_bitrate = i_bitrate; - - p_sout_buffer->i_pts = - p_sout_buffer->i_dts = i_pts; - - p_sout_buffer->i_length = - (uint64_t)1000000 * - (uint64_t)A52_FRAME_NB / - (uint64_t)i_samplerate; - - p_pack->i_samplescount += A52_FRAME_NB; - - /* we are already aligned */ - GetChunk( &p_pack->bit_stream, - p_sout_buffer->p_buffer + 7, - i_framelength - 7 ); - - sout_InputSendBuffer( p_pack->p_sout_input, - p_sout_buffer ); -} - - -/***************************************************************************** - * EndThread : packetizer thread destruction - *****************************************************************************/ -static void EndThread ( packetizer_t *p_pack) -{ - if( p_pack->p_sout_input ) - { - sout_InputDelete( p_pack->p_sout_input ); - } - free( p_pack ); -} - -/***************************************************************************** - * SyncInfo: parse A52 sync info - ***************************************************************************** - * This code is borrowed from liba52 by Aaron Holtzman & Michel Lespinasse, - * since we don't want to oblige S/PDIF people to use liba52 just to get - * their SyncInfo... - * fenrir: I've change it to report channels count - *****************************************************************************/ -static int SyncInfo( const byte_t * p_buf, int * pi_channels, - int * pi_sample_rate, int * pi_bit_rate ) -{ - static const uint8_t halfrate[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 }; - static const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, - 128, 160, 192, 224, 256, 320, 384, 448, - 512, 576, 640 }; - static const uint8_t lfeon[8] = { 0x10, 0x10, 0x04, 0x04, - 0x04, 0x01, 0x04, 0x01 }; - static const int acmod_to_channels[8] = { 2, 1, 2, 3, 3, 4, 4, 5 }; - int frmsizecod; - int bitrate; - int half; - int acmod; - - if ((p_buf[0] != 0x0b) || (p_buf[1] != 0x77)) /* syncword */ - return 0; - - if (p_buf[5] >= 0x60) /* bsid >= 12 */ - return 0; - half = halfrate[p_buf[5] >> 3]; - - /* acmod, dsurmod and lfeon */ - acmod = p_buf[6] >> 5; - if ( (p_buf[6] & 0xf8) == 0x50 ) - { - /* Dolby surround = stereo + Dolby */ -/* *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT - | AOUT_CHAN_DOLBYSTEREO;*/ - *pi_channels = 2; /* FIXME ??? */ - } - else - { - *pi_channels = acmod_to_channels[acmod&0x07]; - } - - if ( p_buf[6] & lfeon[acmod] ) *pi_channels += 1;//|= AOUT_CHAN_LFEA; - - frmsizecod = p_buf[4] & 63; - if (frmsizecod >= 38) - return 0; - bitrate = rate [frmsizecod >> 1]; - *pi_bit_rate = (bitrate * 1000) >> half; - - switch (p_buf[4] & 0xc0) { - case 0: - *pi_sample_rate = 48000 >> half; - return 4 * bitrate; - case 0x40: - *pi_sample_rate = 44100 >> half; - return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); - case 0x80: - *pi_sample_rate = 32000 >> half; - return 6 * bitrate; - default: - return 0; - } -} - - diff --git a/modules/packetizer/copy.c b/modules/packetizer/copy.c index 0664f963c0..a90c03febd 100644 --- a/modules/packetizer/copy.c +++ b/modules/packetizer/copy.c @@ -2,7 +2,7 @@ * copy.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: copy.c,v 1.15 2003/08/11 20:19:45 fenrir Exp $ + * $Id: copy.c,v 1.16 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Laurent Aimar * Eric Petit @@ -80,9 +80,9 @@ static void input_ShowPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes ); *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - p_fifo->pf_run = Run; + p_dec->pf_run = Run; return VLC_SUCCESS; } @@ -672,4 +672,3 @@ static void input_ShowPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes ) *pp_pes = p_fifo->p_first; vlc_mutex_unlock( &p_fifo->data_lock ); } - diff --git a/modules/packetizer/mpeg4audio.c b/modules/packetizer/mpeg4audio.c index 8b5e0f0105..f7427ae7a0 100644 --- a/modules/packetizer/mpeg4audio.c +++ b/modules/packetizer/mpeg4audio.c @@ -2,7 +2,7 @@ * mpeg4audio.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: mpeg4audio.c,v 1.6 2003/05/03 02:09:41 fenrir Exp $ + * $Id: mpeg4audio.c,v 1.7 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Laurent Aimar * @@ -100,11 +100,11 @@ vlc_module_end(); *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - p_fifo->pf_run = Run; + p_dec->pf_run = Run; - if( p_fifo->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'a') ) + if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'a') ) { return( VLC_SUCCESS ); } @@ -363,4 +363,3 @@ static void EndThread ( packetizer_thread_t *p_pack) } free( p_pack ); } - diff --git a/modules/packetizer/mpeg4video.c b/modules/packetizer/mpeg4video.c index b521a4b21b..a29583fdd9 100644 --- a/modules/packetizer/mpeg4video.c +++ b/modules/packetizer/mpeg4video.c @@ -2,7 +2,7 @@ * mpeg4video.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: mpeg4video.c,v 1.12 2003/05/03 02:09:41 fenrir Exp $ + * $Id: mpeg4video.c,v 1.13 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Laurent Aimar * Eric Petit @@ -104,11 +104,11 @@ vlc_module_end(); *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - p_fifo->pf_run = Run; + p_dec->pf_run = Run; - switch( p_fifo->i_fourcc ) + switch( p_dec->p_fifo->i_fourcc ) { case VLC_FOURCC( 'm', '4', 's', '2'): case VLC_FOURCC( 'M', '4', 'S', '2'): @@ -485,4 +485,3 @@ static void input_ShowPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes ) *pp_pes = p_pes; } } - diff --git a/modules/packetizer/mpegaudio.c b/modules/packetizer/mpegaudio.c index dabe01ddd6..71a0fd884d 100644 --- a/modules/packetizer/mpegaudio.c +++ b/modules/packetizer/mpegaudio.c @@ -2,7 +2,7 @@ * mpegaudio.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: mpegaudio.c,v 1.7 2003/08/26 23:12:37 fenrir Exp $ + * $Id: mpegaudio.c,v 1.8 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Laurent Aimar * Eric Petit @@ -110,14 +110,14 @@ static int mpegaudio_samplerate[2][4] = /* version 1 then 2 */ *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'a') ) { return VLC_EGENERIC; } - p_fifo->pf_run = Run; + p_dec->pf_run = Run; return VLC_SUCCESS; } diff --git a/modules/packetizer/mpegvideo.c b/modules/packetizer/mpegvideo.c index ca5bf49bf7..659e73d64e 100644 --- a/modules/packetizer/mpegvideo.c +++ b/modules/packetizer/mpegvideo.c @@ -2,7 +2,7 @@ * mpegvideo.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: mpegvideo.c,v 1.18 2003/08/11 18:52:41 gbazin Exp $ + * $Id: mpegvideo.c,v 1.19 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Laurent Aimar * Eric Petit @@ -98,16 +98,16 @@ vlc_module_end(); *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; + decoder_t *p_dec = (decoder_t*)p_this; - if( p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'v') && - p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '1') && - p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '2') ) + if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', 'v') && + p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '1') && + p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', 'g', '2') ) { return VLC_EGENERIC; } - p_fifo->pf_run = Run; + p_dec->pf_run = Run; return VLC_SUCCESS; } diff --git a/modules/packetizer/vorbis.c b/modules/packetizer/vorbis.c deleted file mode 100644 index efca22514f..0000000000 --- a/modules/packetizer/vorbis.c +++ /dev/null @@ -1,376 +0,0 @@ -/***************************************************************************** - * vorbis.c Vorbis audio packetizer - ***************************************************************************** - * Copyright (C) 2001, 2002 VideoLAN - * $Id: vorbis.c,v 1.1 2003/06/23 23:51:31 gbazin Exp $ - * - * Authors: Gildas Bazin - * - * 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 - * GNU General Public License for more details. - * - * 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. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include -#include -#include -#include -#include - -#include /* malloc(), free() */ -#include /* strdup() */ -#include "codecs.h" /* WAVEFORMATEX BITMAPINFOHEADER */ - -#include -#include - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -typedef struct packetizer_s -{ - /* - * Input properties - */ - decoder_fifo_t *p_fifo; /* stores the PES stream data */ - pes_packet_t *p_pes; /* current PES we are decoding */ - - /* Output properties */ - sout_packetizer_input_t *p_sout_input; - sout_format_t output_format; - - /* - * Vorbis properties - */ - vorbis_info vi; /* struct that stores all the static vorbis bitstream - settings */ - vorbis_comment vc; /* struct that stores all the bitstream user - * comments */ - vorbis_dsp_state vd; /* central working state for the packet->PCM - * decoder */ - vorbis_block vb; /* local working space for packet->PCM decode */ - - uint64_t i_samplescount; - - mtime_t i_interpolated_pts; - int i_last_block_size; - -} packetizer_t; - -static int Open ( vlc_object_t * ); -static int Run ( decoder_fifo_t * ); - -static int InitThread ( packetizer_t * ); -static void PacketizeThread ( packetizer_t * ); -static void EndThread ( packetizer_t * ); - -static int GetOggPacket( packetizer_t *, ogg_packet *, mtime_t * ); -static int SendOggPacket( packetizer_t *, ogg_packet *, mtime_t, int ); - -#define FREE( p ) if( p ) free( p ); p = NULL - -/***************************************************************************** - * Module descriptor - *****************************************************************************/ -vlc_module_begin(); - set_description( _("Vorbis audio packetizer") ); - set_capability( "packetizer", 50 ); - set_callbacks( Open, NULL ); -vlc_module_end(); - -/***************************************************************************** - * OpenDecoder: probe the packetizer and return score - *****************************************************************************/ -static int Open( vlc_object_t *p_this ) -{ - decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this; - - if( p_fifo->i_fourcc != VLC_FOURCC( 'v', 'o', 'r', 'b') ) - { - return VLC_EGENERIC; - } - - p_fifo->pf_run = Run; - return VLC_SUCCESS; -} - -/***************************************************************************** - * RunDecoder: this function is called just after the thread is created - *****************************************************************************/ -static int Run( decoder_fifo_t *p_fifo ) -{ - packetizer_t *p_pack; - int b_error; - - msg_Info( p_fifo, "Running vorbis packetizer" ); - if( !( p_pack = malloc( sizeof( packetizer_t ) ) ) ) - { - msg_Err( p_fifo, "out of memory" ); - DecoderError( p_fifo ); - return -1; - } - memset( p_pack, 0, sizeof( packetizer_t ) ); - - p_pack->p_fifo = p_fifo; - - if( InitThread( p_pack ) != 0 ) - { - DecoderError( p_fifo ); - return -1; - } - - while( ( !p_pack->p_fifo->b_die )&&( !p_pack->p_fifo->b_error ) ) - { - PacketizeThread( p_pack ); - } - - - if( ( b_error = p_pack->p_fifo->b_error ) ) - { - DecoderError( p_pack->p_fifo ); - } - - EndThread( p_pack ); - - FREE( p_pack ); - - if( b_error ) - { - return -1; - } - - return 0; -} - -/***************************************************************************** - * InitThread: initialize data before entering main loop - *****************************************************************************/ -static int InitThread( packetizer_t *p_pack ) -{ - mtime_t i_pts; - ogg_packet oggpacket; - - p_pack->output_format.i_cat = AUDIO_ES; - p_pack->output_format.i_fourcc = p_pack->p_fifo->i_fourcc; - p_pack->output_format.i_sample_rate = 0; - p_pack->output_format.i_channels = 0; - p_pack->output_format.i_block_align = 0; - p_pack->output_format.i_bitrate = 0; - p_pack->output_format.i_extra_data = 0; - p_pack->output_format.p_extra_data = NULL; - - - p_pack->p_sout_input = NULL; - - p_pack->i_samplescount = 0; - p_pack->i_interpolated_pts = 0; - - p_pack->p_pes = NULL; - - /* Take care of vorbis init */ - vorbis_info_init( &p_pack->vi ); - vorbis_comment_init( &p_pack->vc ); - - /* Take care of the initial Vorbis headers */ - if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; - - oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */ - if( vorbis_synthesis_headerin( &p_pack->vi, &p_pack->vc, &oggpacket ) < 0 ) - { - msg_Err( p_pack->p_fifo, "This bitstream does not contain Vorbis " - "audio data"); - goto error; - } - - /* add a input for the stream ouput */ - p_pack->output_format.i_sample_rate = p_pack->vi.rate; - p_pack->output_format.i_channels = p_pack->vi.channels; - p_pack->output_format.i_block_align = 1; - p_pack->output_format.i_bitrate = p_pack->vi.bitrate_nominal; - - p_pack->p_sout_input = - sout_InputNew( p_pack->p_fifo, &p_pack->output_format ); - - if( !p_pack->p_sout_input ) - { - msg_Err( p_pack->p_fifo, "cannot add a new stream" ); - p_pack->p_fifo->b_error = 1; - goto error; - } - msg_Dbg( p_pack->p_fifo, "channels:%d samplerate:%d bitrate:%d", - p_pack->vi.channels, p_pack->vi.rate, p_pack->vi.bitrate_nominal); - - if( SendOggPacket( p_pack, &oggpacket, 0, 0 ) != VLC_SUCCESS ) - goto error; - - /* The next two packets in order are the comment and codebook headers. - We need to watch out that these packets are not missing as a - missing or corrupted header is fatal. */ - if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; - - if( vorbis_synthesis_headerin( &p_pack->vi, &p_pack->vc, &oggpacket ) < 0 ) - { - msg_Err( p_pack->p_fifo, "2nd Vorbis header is corrupted" ); - goto error; - } - - if( SendOggPacket( p_pack, &oggpacket, 0, 0 ) != VLC_SUCCESS ) - goto error; - - if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; - - if( vorbis_synthesis_headerin( &p_pack->vi, &p_pack->vc, &oggpacket ) < 0 ) - { - msg_Err( p_pack->p_fifo, "3rd Vorbis header is corrupted" ); - goto error; - } - - if( SendOggPacket( p_pack, &oggpacket, 0, 0 ) != VLC_SUCCESS ) - goto error; - - /* Initialize the Vorbis packet->PCM decoder */ - vorbis_synthesis_init( &p_pack->vd, &p_pack->vi ); - vorbis_block_init( &p_pack->vd, &p_pack->vb ); - - return 0; - - error: - EndThread( p_pack ); - return -1; -} - -/***************************************************************************** - * PacketizeThread: packetize an unit (here copy a complete ogg packet) - *****************************************************************************/ -static void PacketizeThread( packetizer_t *p_pack ) -{ - mtime_t i_pts; - int i_samples, i_block_size; - ogg_packet oggpacket; - - /* Timestamp all the packets */ - if( GetOggPacket( p_pack, &oggpacket, &i_pts ) != VLC_SUCCESS ) - goto error; - - if( i_pts <= 0 && p_pack->i_interpolated_pts <= 0 ) - { - msg_Dbg( p_pack->p_fifo, "need a starting pts" ); - return; - } - - if( i_pts > 0 ) p_pack->i_interpolated_pts = i_pts; - - i_block_size = vorbis_packet_blocksize( &p_pack->vi, &oggpacket ); - if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */ - i_samples = ( p_pack->i_last_block_size + i_block_size ) >> 2; - p_pack->i_last_block_size = i_block_size; - - if( SendOggPacket( p_pack, &oggpacket, p_pack->i_interpolated_pts, - i_samples ) != VLC_SUCCESS ) - goto error; - - p_pack->i_interpolated_pts += 1000000 * (uint64_t)i_samples - / p_pack->vi.rate; - - return; - - error: - p_pack->p_fifo->b_error = 1; -} - -/***************************************************************************** - * EndThread : packetizer thread destruction - *****************************************************************************/ -static void EndThread ( packetizer_t *p_pack) -{ - if( p_pack->p_pes ) - input_DeletePES( p_pack->p_fifo->p_packets_mgt, p_pack->p_pes ); - - vorbis_block_clear( &p_pack->vb ); - vorbis_dsp_clear( &p_pack->vd ); - vorbis_comment_clear( &p_pack->vc ); - vorbis_info_clear( &p_pack->vi ); /* must be called last */ - - if( p_pack->p_sout_input ) - { - sout_InputDelete( p_pack->p_sout_input ); - } -} - -/***************************************************************************** - * GetOggPacket: get the following vorbis packet from the stream and send back - * the result in an ogg packet (for easy decoding by libvorbis). - ***************************************************************************** - * Returns VLC_EGENERIC in case of eof. - *****************************************************************************/ -static int GetOggPacket( packetizer_t *p_pack, ogg_packet *p_oggpacket, - mtime_t *p_pts ) -{ - if( p_pack->p_pes ) input_DeletePES( p_pack->p_fifo->p_packets_mgt, - p_pack->p_pes ); - - input_ExtractPES( p_pack->p_fifo, &p_pack->p_pes ); - if( !p_pack->p_pes ) return VLC_EGENERIC; - - p_oggpacket->packet = p_pack->p_pes->p_first->p_payload_start; - p_oggpacket->bytes = p_pack->p_pes->i_pes_size; - p_oggpacket->granulepos = p_pack->p_pes->i_dts; - p_oggpacket->b_o_s = 0; - p_oggpacket->e_o_s = 0; - p_oggpacket->packetno = 0; - - *p_pts = p_pack->p_pes->i_pts; - - return VLC_SUCCESS; -} - -/***************************************************************************** - * SendOggPacket: send an ogg packet to the stream output. - ***************************************************************************** - * Returns VLC_EGENERIC in case of error. - *****************************************************************************/ -static int SendOggPacket( packetizer_t *p_pack, ogg_packet *p_oggpacket, - mtime_t i_pts, int i_samples ) -{ - sout_buffer_t *p_sout_buffer = - sout_BufferNew( p_pack->p_sout_input->p_sout, p_oggpacket->bytes ); - - if( !p_sout_buffer ) - { - p_pack->p_fifo->b_error = 1; - return VLC_EGENERIC; - } - - p_pack->p_fifo->p_vlc->pf_memcpy( p_sout_buffer->p_buffer, - p_oggpacket->packet, - p_oggpacket->bytes ); - - p_sout_buffer->i_bitrate = p_pack->vi.bitrate_nominal; - - p_sout_buffer->i_dts = i_pts; - p_sout_buffer->i_pts = i_pts; - - p_sout_buffer->i_length = 1000000 * (uint64_t)i_samples / p_pack->vi.rate; - - p_pack->i_samplescount += i_samples; - - sout_InputSendBuffer( p_pack->p_sout_input, p_sout_buffer ); - - return VLC_SUCCESS; -} diff --git a/src/input/input_dec.c b/src/input/input_dec.c index 8c65f5f35e..29ad1e2f07 100644 --- a/src/input/input_dec.c +++ b/src/input/input_dec.c @@ -2,7 +2,7 @@ * input_dec.c: Functions for the management of decoders ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: input_dec.c,v 1.61 2003/07/23 01:13:48 gbazin Exp $ + * $Id: input_dec.c,v 1.62 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Christophe Massiot * @@ -29,14 +29,15 @@ #include +#include "vlc_block.h" #include "stream_control.h" #include "input_ext-dec.h" #include "input_ext-intf.h" #include "input_ext-plugins.h" -static decoder_fifo_t * CreateDecoderFifo( input_thread_t *, - es_descriptor_t * ); -static void DeleteDecoderFifo( decoder_fifo_t * ); +static decoder_t * CreateDecoder( input_thread_t *, es_descriptor_t * ); +static int DecoderThread( decoder_t * ); +static void DeleteDecoder( decoder_t * ); /***************************************************************************** * input_RunDecoder: spawns a new decoder thread @@ -45,19 +46,18 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input, es_descriptor_t * p_es ) { vlc_value_t val; - decoder_fifo_t *p_fifo; - int i_priority; + decoder_t *p_dec; + int i_priority; /* Create the decoder configuration structure */ - p_fifo = CreateDecoderFifo( p_input, p_es ); - - if( p_fifo == NULL ) + p_dec = CreateDecoder( p_input, p_es ); + if( p_dec == NULL ) { - msg_Err( p_input, "could not create decoder fifo" ); + msg_Err( p_input, "could not create decoder" ); return NULL; } - p_fifo->p_module = NULL; + p_dec->p_module = NULL; /* If we are in sout mode, search for packetizer module */ var_Get( p_input, "sout", &val ); @@ -77,24 +77,26 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input, if( val.b_bool ) { - p_fifo->p_module = - module_Need( p_fifo, "packetizer", "$packetizer" ); + p_dec->p_module = + module_Need( p_dec, "packetizer", "$packetizer" ); } } else { /* default Get a suitable decoder module */ - p_fifo->p_module = module_Need( p_fifo, "decoder", "$codec" ); + p_dec->p_module = module_Need( p_dec, "decoder", "$codec" ); if( val.psz_string ) free( val.psz_string ); } - if( p_fifo->p_module == NULL ) + if( p_dec->p_module == NULL ) { - msg_Err( p_fifo, "no suitable decoder module for fourcc `%4.4s'.\nVLC probably does not support this sound or video format.", - (char*)&p_fifo->i_fourcc ); - DeleteDecoderFifo( p_fifo ); - vlc_object_destroy( p_fifo ); + msg_Err( p_dec, "no suitable decoder module for fourcc `%4.4s'.\n" + "VLC probably does not support this sound or video format.", + (char*)&p_dec->p_fifo->i_fourcc ); + + DeleteDecoder( p_dec ); + vlc_object_destroy( p_dec ); return NULL; } @@ -108,27 +110,29 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input, } /* Spawn the decoder thread */ - if( vlc_thread_create( p_fifo, "decoder", p_fifo->pf_run, + if( vlc_thread_create( p_dec, "decoder", DecoderThread, i_priority, VLC_FALSE ) ) { - msg_Err( p_fifo, "cannot spawn decoder thread \"%s\"", - p_fifo->p_module->psz_object_name ); - module_Unneed( p_fifo, p_fifo->p_module ); + msg_Err( p_dec, "cannot spawn decoder thread \"%s\"", + p_dec->p_module->psz_object_name ); + module_Unneed( p_dec, p_dec->p_module ); + DeleteDecoder( p_dec ); + vlc_object_destroy( p_dec ); return NULL; } p_input->stream.b_changed = 1; - return p_fifo; + return p_dec->p_fifo; } - /***************************************************************************** * input_EndDecoder: kills a decoder thread and waits until it's finished *****************************************************************************/ void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es ) { int i_dummy; + decoder_t *p_dec = p_es->p_decoder_fifo->p_dec; p_es->p_decoder_fifo->b_die = 1; @@ -148,17 +152,17 @@ void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es ) /* I thought that unlocking was better since thread join can be long * but it actually creates late pictures and freezes --stef */ /* vlc_mutex_unlock( &p_input->stream.stream_lock ); */ - vlc_thread_join( p_es->p_decoder_fifo ); + vlc_thread_join( p_dec ); /* vlc_mutex_lock( &p_input->stream.stream_lock ); */ - /* Delete decoder configuration */ - DeleteDecoderFifo( p_es->p_decoder_fifo ); - /* Unneed module */ - module_Unneed( p_es->p_decoder_fifo, p_es->p_decoder_fifo->p_module ); + module_Unneed( p_dec, p_dec->p_module ); - /* Delete the fifo */ - vlc_object_destroy( p_es->p_decoder_fifo ); + /* Delete decoder configuration */ + DeleteDecoder( p_dec ); + + /* Delete the decoder */ + vlc_object_destroy( p_dec ); /* Tell the input there is no more decoder */ p_es->p_decoder_fifo = NULL; @@ -275,65 +279,161 @@ void input_EscapeAudioDiscontinuity( input_thread_t * p_input ) /***************************************************************************** * CreateDecoderFifo: create a decoder_fifo_t *****************************************************************************/ -static decoder_fifo_t * CreateDecoderFifo( input_thread_t * p_input, - es_descriptor_t * p_es ) +static decoder_t * CreateDecoder( input_thread_t * p_input, + es_descriptor_t * p_es ) { - decoder_fifo_t * p_fifo; + decoder_t * p_dec; - /* Decoder FIFO */ - p_fifo = vlc_object_create( p_input, VLC_OBJECT_DECODER ); - if( p_fifo == NULL ) + p_dec = vlc_object_create( p_input, VLC_OBJECT_DECODER ); + if( p_dec == NULL ) { msg_Err( p_input, "out of memory" ); return NULL; } + p_dec->pf_init = 0; + p_dec->pf_decode = 0; + p_dec->pf_end = 0; + p_dec->pf_run = 0; + /* Select a new ES */ INSERT_ELEM( p_input->stream.pp_selected_es, p_input->stream.i_selected_es_number, p_input->stream.i_selected_es_number, p_es ); + /* Allocate the memory needed to store the decoder's fifo */ + //p_dec->p_fifo = (decoder_fifo_t *)malloc(sizeof(decoder_fifo_t)); + p_dec->p_fifo = vlc_object_create( p_input, VLC_OBJECT_DECODER_FIFO ); + if( p_dec->p_fifo == NULL ) + { + msg_Err( p_input, "out of memory" ); + return NULL; + } + + /* Initialize the decoder fifo */ + //memset( p_dec->p_fifo, 0, sizeof(decoder_fifo_t) ); + p_dec->p_module = NULL; + /* Initialize the p_fifo structure */ - vlc_mutex_init( p_input, &p_fifo->data_lock ); - vlc_cond_init( p_input, &p_fifo->data_wait ); - p_es->p_decoder_fifo = p_fifo; - - p_fifo->i_id = p_es->i_id; - p_fifo->i_fourcc = p_es->i_fourcc; - p_fifo->p_demux_data = p_es->p_demux_data; - p_fifo->p_waveformatex = p_es->p_waveformatex; - p_fifo->p_bitmapinfoheader = p_es->p_bitmapinfoheader; - p_fifo->p_stream_ctrl = &p_input->stream.control; - p_fifo->p_sout = p_input->stream.p_sout; - - p_fifo->p_first = NULL; - p_fifo->pp_last = &p_fifo->p_first; - p_fifo->i_depth = 0; - p_fifo->b_die = p_fifo->b_error = 0; - p_fifo->p_packets_mgt = p_input->p_method_data; - - vlc_object_attach( p_fifo, p_input ); - - return p_fifo; + vlc_mutex_init( p_input, &p_dec->p_fifo->data_lock ); + vlc_cond_init( p_input, &p_dec->p_fifo->data_wait ); + p_es->p_decoder_fifo = p_dec->p_fifo; + + p_dec->p_fifo->i_id = p_es->i_id; + p_dec->p_fifo->i_fourcc = p_es->i_fourcc; + p_dec->p_fifo->p_demux_data = p_es->p_demux_data; + p_dec->p_fifo->p_waveformatex = p_es->p_waveformatex; + p_dec->p_fifo->p_bitmapinfoheader = p_es->p_bitmapinfoheader; + p_dec->p_fifo->p_stream_ctrl = &p_input->stream.control; + p_dec->p_fifo->p_sout = p_input->stream.p_sout; + + p_dec->p_fifo->p_first = NULL; + p_dec->p_fifo->pp_last = &p_dec->p_fifo->p_first; + p_dec->p_fifo->i_depth = 0; + p_dec->p_fifo->b_die = p_dec->p_fifo->b_error = 0; + p_dec->p_fifo->p_packets_mgt = p_input->p_method_data; + + p_dec->p_fifo->p_dec = p_dec; + + vlc_object_attach( p_dec->p_fifo, p_input ); + vlc_object_attach( p_dec, p_input ); + + return p_dec; +} + +/***************************************************************************** + * DecoderThread: the decoding main loop + *****************************************************************************/ +static int DecoderThread( decoder_t * p_dec ) +{ + pes_packet_t *p_pes; + data_packet_t *p_data; + block_t *p_block; + + /* Temporary wrapper to keep old decoder api functional */ + if( p_dec->pf_run ) + { + p_dec->pf_run( p_dec->p_fifo ); + return 0; + } + + + /* Initialize the decoder */ + p_dec->p_fifo->b_error = p_dec->pf_init( p_dec ); + + /* The decoder's main loop */ + while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error ) + { + int i_size; + + input_ExtractPES( p_dec->p_fifo, &p_pes ); + if( !p_pes ) + { + p_dec->p_fifo->b_error = 1; + break; + } + + for( i_size = 0, p_data = p_pes->p_first; + p_data != NULL; p_data = p_data->p_next ) + { + i_size += p_data->p_payload_end - p_data->p_payload_start; + } + p_block = block_New( p_dec, i_size ); + for( i_size = 0, p_data = p_pes->p_first; + p_data != NULL; p_data = p_data->p_next ) + { + memcpy( p_block->p_buffer + i_size, p_data->p_payload_start, + p_data->p_payload_end - p_data->p_payload_start ); + i_size += p_data->p_payload_end - p_data->p_payload_start; + } + + p_block->i_pts = p_pes->i_pts; + p_block->i_dts = p_pes->i_dts; + p_dec->p_fifo->b_error = p_dec->pf_decode( p_dec, p_block ); + + input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes ); + } + + /* If b_error is set, the decoder thread enters the error loop */ + if( p_dec->p_fifo->b_error ) + { + /* Wait until a `die' order is sent */ + while( !p_dec->p_fifo->b_die ) + { + /* Trash all received PES packets */ + input_ExtractPES( p_dec->p_fifo, NULL ); + } + } + + /* End of the decoder */ + p_dec->pf_end( p_dec ); + + return 0; } /***************************************************************************** * DeleteDecoderFifo: destroy a decoder_fifo_t *****************************************************************************/ -static void DeleteDecoderFifo( decoder_fifo_t * p_fifo ) +static void DeleteDecoder( decoder_t * p_dec ) { - vlc_object_detach( p_fifo ); + vlc_object_detach( p_dec ); + vlc_object_detach( p_dec->p_fifo ); - msg_Dbg( p_fifo, "killing decoder for 0x%x, fourcc `%4.4s', %d PES in FIFO", - p_fifo->i_id, (char*)&p_fifo->i_fourcc, p_fifo->i_depth ); + msg_Dbg( p_dec, + "killing decoder for 0x%x, fourcc `%4.4s', %d PES in FIFO", + p_dec->p_fifo->i_id, (char*)&p_dec->p_fifo->i_fourcc, + p_dec->p_fifo->i_depth ); /* Free all packets still in the decoder fifo. */ - input_DeletePES( p_fifo->p_packets_mgt, - p_fifo->p_first ); + input_DeletePES( p_dec->p_fifo->p_packets_mgt, + p_dec->p_fifo->p_first ); /* Destroy the lock and cond */ - vlc_cond_destroy( &p_fifo->data_wait ); - vlc_mutex_destroy( &p_fifo->data_lock ); -} + vlc_cond_destroy( &p_dec->p_fifo->data_wait ); + vlc_mutex_destroy( &p_dec->p_fifo->data_lock ); + /* Free fifo */ + vlc_object_destroy( p_dec->p_fifo ); + //free( p_dec->p_fifo ); +} diff --git a/src/misc/block.c b/src/misc/block.c index 2e7db1dce3..cd686c49a6 100644 --- a/src/misc/block.c +++ b/src/misc/block.c @@ -1,8 +1,8 @@ /***************************************************************************** - * block.c + * block.c: Data blocks management functions ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: block.c,v 1.1 2003/08/23 22:49:50 fenrir Exp $ + * $Id: block.c,v 1.2 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Laurent Aimar * @@ -38,8 +38,9 @@ struct block_sys_t uint8_t *p_allocated_buffer; int i_allocated_buffer; - vlc_bool_t b_modify; /* has it be put in modify state */ - int i_duplicated; /* how many times it has been duplicated (only content) */ + vlc_bool_t b_modify; /* has it been put in modified state */ + int i_duplicated; /* how many times has the content been + * duplicated */ }; @@ -104,6 +105,7 @@ static block_t *BlockModify( block_t *p_block, vlc_bool_t b_will_modify ) return p_mod; } + static block_t *BlockDuplicate( block_t *p_block ) { block_t *p_dup; @@ -128,15 +130,16 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body ) { vlc_mutex_lock( &p_block->p_sys->lock ); - if( i_prebody < 0 || - ( p_block->p_buffer - i_prebody > p_block->p_sys->p_allocated_buffer ) ) + if( i_prebody < 0 || p_block->p_buffer - i_prebody > + p_block->p_sys->p_allocated_buffer ) { p_block->p_buffer -= i_prebody; p_block->i_buffer += i_prebody; i_prebody = 0; } if( i_body < 0 || - ( p_block->p_buffer + i_body < p_block->p_sys->p_allocated_buffer + p_block->p_sys->i_allocated_buffer ) ) + p_block->p_buffer + i_body < p_block->p_sys->p_allocated_buffer + + p_block->p_sys->i_allocated_buffer ) { p_block->i_buffer = i_body; i_body = 0; @@ -147,7 +150,8 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body ) { block_t *p_rea = block_New( p_block->p_manager, i_prebody + i_body ); - memcpy( &p_rea->p_buffer[i_prebody], p_block->p_buffer, p_block->i_buffer ); + memcpy( &p_rea->p_buffer[i_prebody], p_block->p_buffer, + p_block->i_buffer ); return p_rea; } @@ -160,7 +164,9 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body ) i_start = p_rea->p_buffer - p_rea->p_sys->p_allocated_buffer; p_rea->p_sys->i_allocated_buffer += i_body - p_rea->i_buffer; - p_rea->p_sys->p_allocated_buffer = realloc( p_rea->p_sys->p_allocated_buffer, p_rea->p_sys->i_allocated_buffer ); + p_rea->p_sys->p_allocated_buffer = + realloc( p_rea->p_sys->p_allocated_buffer, + p_rea->p_sys->i_allocated_buffer ); p_rea->p_buffer = &p_rea->p_sys->p_allocated_buffer[i_start]; p_rea->i_buffer = i_body; @@ -170,6 +176,7 @@ static block_t *BlockRealloc( block_t *p_block, int i_prebody, int i_body ) return p_block; } + /***************************************************************************** * Standard block management * @@ -203,7 +210,6 @@ block_t *__block_New( vlc_object_t *p_obj, int i_size ) block_t *p_block; block_sys_t *p_sys; - p_block = block_NewEmpty(); p_block->i_buffer = i_size; @@ -218,7 +224,7 @@ block_t *__block_New( vlc_object_t *p_obj, int i_size ) p_block->pf_realloc = BlockRealloc; /* that should be ok (no comunication between multiple p_vlc) */ - p_block->p_manager = p_obj->p_vlc; + p_block->p_manager = VLC_OBJECT( p_obj->p_vlc ); p_block->p_sys = p_sys = malloc( sizeof( block_sys_t ) ); vlc_mutex_init( p_obj, &p_sys->lock ); @@ -230,7 +236,7 @@ block_t *__block_New( vlc_object_t *p_obj, int i_size ) return p_block; } -void block_ChainAppend( block_t **pp_list, block_t *p_block ) +void block_ChainAppend( block_t **pp_list, block_t *p_block ) { if( *pp_list == NULL ) @@ -249,7 +255,7 @@ void block_ChainAppend( block_t **pp_list, block_t *p_block ) } } -void block_ChainRelease( block_t *p_block ) +void block_ChainRelease( block_t *p_block ) { while( p_block ) { @@ -320,7 +326,7 @@ block_t *block_ChainGather( block_t *p_list ) /***************************************************************************** * block_fifo_t managment *****************************************************************************/ -block_fifo_t * __block_FifoNew ( vlc_object_t *p_obj ) +block_fifo_t *__block_FifoNew( vlc_object_t *p_obj ) { block_fifo_t *p_fifo; @@ -334,7 +340,7 @@ block_fifo_t * __block_FifoNew ( vlc_object_t *p_obj ) return p_fifo; } -void block_FifoRelease( block_fifo_t *p_fifo ) +void block_FifoRelease( block_fifo_t *p_fifo ) { block_FifoEmpty( p_fifo ); vlc_cond_destroy( &p_fifo->wait ); @@ -342,7 +348,7 @@ void block_FifoRelease( block_fifo_t *p_fifo ) free( p_fifo ); } -void block_FifoEmpty( block_fifo_t *p_fifo ) +void block_FifoEmpty( block_fifo_t *p_fifo ) { block_t *b; @@ -362,7 +368,7 @@ void block_FifoEmpty( block_fifo_t *p_fifo ) vlc_mutex_unlock( &p_fifo->lock ); } -int block_FifoPut ( block_fifo_t *p_fifo, block_t *p_block ) +int block_FifoPut( block_fifo_t *p_fifo, block_t *p_block ) { int i_size = 0; vlc_mutex_lock( &p_fifo->lock ); @@ -379,14 +385,14 @@ int block_FifoPut ( block_fifo_t *p_fifo, block_t *p_block ) } while( p_block ); - /* warm there is data in this fifo */ + /* warn there is data in this fifo */ vlc_cond_signal( &p_fifo->wait ); vlc_mutex_unlock( &p_fifo->lock ); return i_size; } -block_t * block_FifoGet ( block_fifo_t *p_fifo ) +block_t *block_FifoGet( block_fifo_t *p_fifo ) { block_t *b; @@ -413,7 +419,7 @@ block_t * block_FifoGet ( block_fifo_t *p_fifo ) return( b ); } -block_t * block_FifoShow ( block_fifo_t *p_fifo ) +block_t *block_FifoShow( block_fifo_t *p_fifo ) { block_t *b; @@ -432,7 +438,7 @@ block_t * block_FifoShow ( block_fifo_t *p_fifo ) } -block_t * block_FifoGetFrame( block_fifo_t *p_fifo ) +block_t *block_FifoGetFrame( block_fifo_t *p_fifo ) { block_t *b = NULL; @@ -449,5 +455,3 @@ block_t * block_FifoGetFrame( block_fifo_t *p_fifo ) return b; } - - diff --git a/src/misc/objects.c b/src/misc/objects.c index 333fbe147b..6ff8076759 100644 --- a/src/misc/objects.c +++ b/src/misc/objects.c @@ -2,7 +2,7 @@ * objects.c: vlc_object_t handling ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: objects.c,v 1.37 2003/06/26 12:19:59 sam Exp $ + * $Id: objects.c,v 1.38 2003/09/02 20:19:26 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -109,6 +109,10 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type ) psz_type = "input"; break; case VLC_OBJECT_DECODER: + i_size = sizeof(decoder_t); + psz_type = "decoder"; + break; + case VLC_OBJECT_DECODER_FIFO: /* tmp for backward compat */ i_size = sizeof(decoder_fifo_t); psz_type = "decoder"; break; -- 2.39.2