of these. The bitstream facility has also been changed to use input_ExtractPES
and now stores the current PES in its structure.
Introduced input_FlushPESFifo() and CloseBitstream().
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_ext-dec.h,v 1.74 2002/10/24 09:37:48 gbazin Exp $
+ * $Id: input_ext-dec.h,v 1.75 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
/*
* Byte structures
*/
- /* Current data packet (in the current PES packet of the PES stream) */
+ /* Current PES packet (extracted from the PES stream) */
+ pes_packet_t * p_pes;
+ /* Current data packet (in the current PES packet) */
data_packet_t * p_data;
/* Pointer to the next byte that is to be read (in the current packet) */
byte_t * p_byte;
/*****************************************************************************
* Prototypes from input_ext-dec.c
*****************************************************************************/
-VLC_EXPORT( void, InitBitstream, ( bit_stream_t *, decoder_fifo_t *, void ( * )( bit_stream_t *, vlc_bool_t ), void * p_callback_arg ) );
-VLC_EXPORT( vlc_bool_t, NextDataPacket, ( decoder_fifo_t *, data_packet_t ** ) );
-VLC_EXPORT( pes_packet_t *, GetPES, ( decoder_fifo_t * ) );
-VLC_EXPORT( pes_packet_t *, NextPES, ( decoder_fifo_t * ) );
+VLC_EXPORT( int, InitBitstream, ( bit_stream_t *, decoder_fifo_t *, void ( * )( bit_stream_t *, vlc_bool_t ), void * p_callback_arg ) );
+VLC_EXPORT( vlc_bool_t, NextDataPacket, ( decoder_fifo_t *, bit_stream_t * ) );
VLC_EXPORT( void, BitstreamNextDataPacket, ( bit_stream_t * ) );
VLC_EXPORT( u32, UnalignedShowBits, ( bit_stream_t *, unsigned int ) );
VLC_EXPORT( void, UnalignedRemoveBits, ( bit_stream_t * ) );
VLC_EXPORT( u32, UnalignedGetBits, ( bit_stream_t *, unsigned int ) );
+VLC_EXPORT( void, CloseBitstream, ( bit_stream_t * ) );
VLC_EXPORT( void, CurrentPTS, ( bit_stream_t *, mtime_t *, mtime_t * ) );
VLC_EXPORT( void, NextPTS, ( bit_stream_t *, mtime_t *, mtime_t * ) );
-VLC_EXPORT( int, input_ExtractPES, ( decoder_fifo_t *, pes_packet_t ** ) );
-
/*****************************************************************************
* AlignWord : fill in the bit buffer so that the byte pointer be aligned
* on a word boundary (XXX: there must be at least sizeof(WORD_TYPE) - 1
* but exported to plug-ins
*****************************************************************************
* Copyright (C) 1999-2002 VideoLAN
- * $Id: input_ext-plugins.h,v 1.35 2002/08/08 00:35:10 sam Exp $
+ * $Id: input_ext-plugins.h,v 1.36 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
decoder_fifo_t * input_RunDecoder( input_thread_t *, es_descriptor_t * );
void input_EndDecoder( input_thread_t *, es_descriptor_t * );
VLC_EXPORT( void, input_DecodePES, ( decoder_fifo_t *, pes_packet_t * ) );
+VLC_EXPORT( void, input_ExtractPES, ( decoder_fifo_t *, pes_packet_t ** ) );
+VLC_EXPORT( void, input_FlushPESFifo, ( decoder_fifo_t * ) );
void input_EscapeDiscontinuity( input_thread_t * );
void input_EscapeAudioDiscontinuity( input_thread_t * );
* a52.c: A/52 basic parser
*****************************************************************************
* Copyright (C) 2001-2002 VideoLAN
- * $Id: a52.c,v 1.15 2002/10/24 09:37:48 gbazin Exp $
+ * $Id: a52.c,v 1.16 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
DecoderError( p_fifo );
return -1;
}
-
+
/* Initialize the thread properties */
p_dec->p_aout = NULL;
p_dec->p_aout_input = NULL;
aout_DateSet( &end_date, 0 );
/* Init the bitstream */
- InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
- NULL, NULL );
+ 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;
+ }
/* decoder thread's main loop */
while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
+ CloseBitstream( &p_dec->bit_stream );
free( p_dec );
}
* a52old.c: A52 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: a52old.c,v 1.7 2002/09/26 22:40:20 massiot Exp $
+ * $Id: a52old.c,v 1.8 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
static int OpenDecoder( 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;
}
/*
* Bit stream
*/
- InitBitstream( &p_a52dec->bit_stream, p_a52dec->p_fifo,
- BitstreamCallback, (void *) p_a52dec );
-
- return( 0 );
+ return( InitBitstream( &p_a52dec->bit_stream, p_a52dec->p_fifo,
+ BitstreamCallback, (void *) p_a52dec ) );
}
/*****************************************************************************
/* Free what's left of the decoder */
free( p_a52dec->imdct_orig );
+ CloseBitstream( p_a52dec->bit_stream );
}
/*****************************************************************************
* araw.c: Pseudo audio decoder; for raw pcm data
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: araw.c,v 1.4 2002/10/24 09:37:48 gbazin Exp $
+ * $Id: araw.c,v 1.5 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
pes_packet_t *p_pes;
/* **** get samples count **** */
- if( input_ExtractPES( p_adec->p_fifo, &p_pes ) < 0 )
+ input_ExtractPES( p_adec->p_fifo, &p_pes );
+ if( !p_pes )
{
p_adec->p_fifo->b_error = 1;
return;
* cinepak.c: cinepak video decoder
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: cinepak.c,v 1.5 2002/10/24 09:37:48 gbazin Exp $
+ * $Id: cinepak.c,v 1.6 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
data_packet_t *p_data;
byte_t *p_buffer;
- p_pes = GetPES( p_vdec->p_fifo );
+ input_ExtractPES( p_vdec->p_fifo, &p_pes );
+ if( !p_pes )
+ {
+ p_vdec->p_framedata = NULL;
+ return;
+ }
+
p_vdec->i_pts = p_pes->i_pts;
while( ( !p_pes->i_nb_data )||( !p_pes->i_pes_size ) )
{
- p_pes = NextPES( p_vdec->p_fifo );
+ input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes );
+ input_ExtractPES( p_vdec->p_fifo, &p_pes );
+ if( !p_pes )
+ {
+ p_vdec->p_framedata = NULL;
+ return;
+ }
}
p_vdec->i_framesize = p_pes->i_pes_size;
if( p_pes->i_nb_data == 1 )
p_buffer += p_data->p_payload_end - p_data->p_payload_start;
p_data = p_data->p_next;
} while( p_data );
+ input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes );
}
static inline void __NextFrame( videodec_thread_t *p_vdec )
{
pes_packet_t *p_pes;
- p_pes = GetPES( p_vdec->p_fifo );
- if( p_pes->i_nb_data != 1 )
+ input_ExtractPES( p_vdec->p_fifo, &p_pes );
+ if( p_pes && (p_pes->i_nb_data != 1) )
{
free( p_vdec->p_framedata ); /* FIXME keep this buffer */
}
- NextPES( p_vdec->p_fifo );
+ input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes );
}
static int cinepak_CheckVout( vout_thread_t *p_vout,
* dv.c: a decoder for DV video
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: dv.c,v 1.2 2002/08/12 09:34:15 sam Exp $
+ * $Id: dv.c,v 1.3 2002/10/27 16:58:13 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
return -1;
}
- InitBitstream( &bit_stream, p_fifo, NULL, NULL );
+ if( InitBitstream( &bit_stream, p_fifo, NULL, NULL ) != VLC_SUCCESS )
+ {
+ msg_Err( p_fifo, "cannot initialise bitstream" );
+ free( p_buffer );
+ p_fifo->b_error = 1;
+ DecoderError( p_fifo );
+ return -1;
+ }
/* Fill the buffer */
GetChunk( &bit_stream, p_buffer, i_data );
}
free( p_buffer );
+ CloseBitstream( bit_stream );
if( p_fifo->b_error )
{
return p_pes;
}
-
* decoder.c: AAC decoder using libfaad2
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: decoder.c,v 1.7 2002/10/24 09:37:47 gbazin Exp $
+ * $Id: decoder.c,v 1.8 2002/10/27 16:58:13 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
data_packet_t *p_data;
byte_t *p_buffer;
- p_pes = GetPES( p_adec->p_fifo );
+ input_ExtractPES( p_adec->p_fifo, &p_pes );
+ if( !p_pes )
+ {
+ p_adec->p_framedata = NULL;
+ return;
+ }
+
if( p_pes->i_pts )
{
p_adec->pts = p_pes->i_pts;
while( ( !p_pes->i_nb_data )||( !p_pes->i_pes_size ) )
{
- p_pes = NextPES( p_adec->p_fifo );
+ input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
+ input_ExtractPES( p_adec->p_fifo, &p_pes );
+ if( !p_pes )
+ {
+ p_vdec->p_framedata = NULL;
+ return;
+ }
}
p_adec->i_framesize = p_pes->i_pes_size;
if( p_pes->i_nb_data == 1 )
p_buffer += p_data->p_payload_end - p_data->p_payload_start;
p_data = p_data->p_next;
} while( p_data );
+
+ input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
}
static inline void __NextFrame( adec_thread_t *p_adec )
{
- NextPES( p_adec->p_fifo );
+ input_ExtractPES( p_vdec->p_fifo, NULL );
}
* ffmpeg.c: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ffmpeg.c,v 1.10 2002/10/24 10:33:09 fenrir Exp $
+ * $Id: ffmpeg.c,v 1.11 2002/10/27 16:58:13 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
/* too much late picture, won't decode
but break picture until a new I, and for mpeg4 ...*/
p_vdec->i_frame_late--; /* needed else it will never be decrease */
- NextPES( p_vdec->p_fifo );
+ input_ExtractPES( p_vdec->p_fifo, NULL );
return;
}
#else
/* too much late picture, won't decode
but break picture until a new I, and for mpeg4 ...*/
p_vdec->i_frame_late--; /* needed else it will never be decrease */
- NextPES( p_vdec->p_fifo );
+ input_ExtractPES( p_vdec->p_fifo, NULL );
return;
}
#endif
do
{
- if( !( p_pes = GetPES( p_vdec->p_fifo ) ) )
+ input_ExtractPES( p_vdec->p_fifo, &p_pes );
+ if( !p_pes )
{
p_vdec->p_fifo->b_error = 1;
return;
GetPESData( p_vdec->p_buffer, p_vdec->i_buffer, p_pes );
}
- NextPES( p_vdec->p_fifo );
+ input_DeletePES( p_vdec->p_fifo->p_packets_mgt, p_pes );
} while( i_frame_size <= 0 );
* lpcm.c: lpcm decoder module
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm.c,v 1.5 2002/10/15 23:10:54 massiot Exp $
+ * $Id: lpcm.c,v 1.6 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
p_dec->p_fifo = p_fifo;
/* Init the bitstream */
- InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
- NULL, NULL );
+ if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
+ NULL, NULL ) != VLC_SUCCESS )
+ {
+ msg_Err( p_fifo, "cannot initialize bitstream" );
+ DecoderError( p_fifo );
+ EndThread( p_dec );
+ return -1;
+ }
/* FIXME : I suppose the number of channel and sampling rate
* are somewhere in the headers */
{
msg_Err( p_dec->p_fifo, "failed to create aout fifo" );
p_dec->p_fifo->b_error = 1;
+ EndThread( p_dec );
return( -1 );
}
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
+ CloseBitstream( &p_dec->bit_stream );
free( p_dec );
}
*****************************************************************************/
static int InitThread( mad_adec_thread_t * p_dec )
{
- decoder_fifo_t * p_fifo = p_dec->p_fifo;
-
/* Initialize the thread properties */
p_dec->p_aout = NULL;
p_dec->p_aout_input = NULL;
* Initialize the input properties
*/
- /* Get the first data packet. */
- vlc_mutex_lock( &p_fifo->data_lock );
- while ( p_fifo->p_first == NULL )
- {
- if ( p_fifo->b_die )
- {
- vlc_mutex_unlock( &p_fifo->data_lock );
- return VLC_EGENERIC;
- }
- vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
- }
- vlc_mutex_unlock( &p_fifo->data_lock );
- p_dec->p_data = p_fifo->p_first->p_first;
-
- return VLC_SUCCESS;
+ return InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, NULL, NULL );
}
/*****************************************************************************
/* mad_decoder_finish releases the memory allocated inside the struct */
mad_decoder_finish( &p_dec->libmad_decoder );
+ CloseBitstream( &p_dec->bit_stream );
free( p_dec );
}
-
* Input properties
*/
decoder_fifo_t * p_fifo; /* stores the PES stream data */
- data_packet_t * p_data;
+ bit_stream_t bit_stream; /* handle PES stream at the bit level */
/* Store i_pts for syncing audio frames */
mtime_t i_current_pts, i_next_pts;
i_wanted = MAD_BUFFER_MDLEN - i_left;
/* Store timestamp for next frame */
- p_dec->i_next_pts = p_dec->p_fifo->p_first->i_pts;
+ p_dec->i_next_pts = p_dec->bit_stream.p_pes->i_pts;
}
else
{
i_left = 0;
/* Store timestamp for this frame */
- p_dec->i_current_pts = p_dec->p_fifo->p_first->i_pts;
+ p_dec->i_current_pts = p_dec->bit_stream.p_pes->i_pts;
}
- p_dec->p_fifo->p_first->i_pts = 0;
/* Fill-in the buffer. If an error occurs print a message and leave
* the decoding loop. If the end of stream is reached we also leave
* the loop but the return status is left untouched. */
- if( i_wanted > p_dec->p_data->p_payload_end
- - p_dec->p_data->p_payload_start )
+ if( i_wanted > p_dec->bit_stream.p_data->p_payload_end
+ - p_dec->bit_stream.p_data->p_payload_start )
{
- i_wanted = p_dec->p_data->p_payload_end
- - p_dec->p_data->p_payload_start;
+ i_wanted = p_dec->bit_stream.p_data->p_payload_end
+ - p_dec->bit_stream.p_data->p_payload_start;
memcpy( p_dec->buffer + i_left,
- p_dec->p_data->p_payload_start, i_wanted );
- NextDataPacket( p_dec->p_fifo, &p_dec->p_data );
+ p_dec->bit_stream.p_data->p_payload_start, i_wanted );
+ NextDataPacket( p_dec->p_fifo, &p_dec->bit_stream );
+ /* No need to check that p_dec->bit_stream->p_data is valid
+ * since we check later on for b_die and b_error */
}
else
{
memcpy( p_dec->buffer + i_left,
- p_dec->p_data->p_payload_start, i_wanted );
- p_dec->p_data->p_payload_start += i_wanted;
+ p_dec->bit_stream.p_data->p_payload_start, i_wanted );
+ p_dec->bit_stream.p_data->p_payload_start += i_wanted;
}
if ( p_dec->p_fifo->b_die )
/****************************************************************************
- * Print human readable informations about an audio MPEG frame. *
+ * Print human readable informations about an audio MPEG frame.
****************************************************************************/
static void PrintFrameInfo(struct mad_header *Header)
{
* decoder.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: decoder.c,v 1.6 2002/10/15 23:10:54 massiot Exp $
+ * $Id: decoder.c,v 1.7 2002/10/27 16:58:13 gbazin Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
/*
* Initialize bit stream
*/
- InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, NULL, NULL );
+ if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, NULL, NULL )
+ != VLC_SUCCESS )
+ {
+ msg_Err( p_fifo, "cannot initialize bitstream" );
+ DecoderError( p_fifo );
+ return 0;
+ }
/* We do not create the audio output fifo now, but
it will be created when the first frame is received */
}
+ CloseBitstream( &p_dec->bit_stream );
+
/* Destroy descriptor */
free( p_dec );
}
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: parser.c,v 1.4 2002/08/12 09:34:15 sam Exp $
+ * $Id: parser.c,v 1.5 2002/10/27 16:58:13 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
p_vpar->pf_idct_copy = ((void**)p_vpar->p_fifo->p_private)[5];
/* Initialize input bitstream */
- InitBitstream( &p_vpar->bit_stream, p_vpar->p_fifo,
- BitstreamCallback, (void *)p_vpar );
+ if( InitBitstream( &p_vpar->bit_stream, p_vpar->p_fifo,
+ BitstreamCallback, (void *)p_vpar ) != VLC_SUCCESS )
+ {
+ msg_Err( p_vpar->p_fifo, "cannot initialize bitstream" );
+ module_Unneed( p_vpar->p_fifo, p_vpar->p_motion );
+ free( p_vpar );
+ return( -1 );
+ }
/* Initialize parsing data */
p_vpar->sequence.p_forward = NULL;
module_Unneed( p_vpar->p_fifo, p_vpar->p_idct );
module_Unneed( p_vpar->p_fifo, p_vpar->p_motion );
+ CloseBitstream( &p_vpar->bit_stream );
free( p_vpar );
}
if( b_new_pes )
{
p_vpar->sequence.i_current_rate =
- p_bit_stream->p_decoder_fifo->p_first->i_rate;
+ p_bit_stream->p_pes->i_rate;
- if( p_bit_stream->p_decoder_fifo->p_first->b_discontinuity )
+ if( p_bit_stream->p_pes->b_discontinuity )
{
/* Escape the current picture and reset the picture predictors. */
p_vpar->sequence.b_expect_discontinuity = 1;
* spudec.c : SPU decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: spudec.c,v 1.4 2002/09/14 20:50:24 stef Exp $
+ * $Id: spudec.c,v 1.5 2002/10/27 16:58:13 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
}
while( 1 );
- InitBitstream( &p_spudec->bit_stream, p_spudec->p_fifo, NULL, NULL );
-
- /* Mark thread as running and return */
- return 0;
+ return InitBitstream( &p_spudec->bit_stream, p_spudec->p_fifo,
+ NULL, NULL );
}
/*****************************************************************************
vlc_object_release( p_spudec->p_vout );
}
+ CloseBitstream( &p_spudec->bit_stream );
free( p_spudec );
}
* vorbis.c: vorbis decoder module making use of libvorbis.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: vorbis.c,v 1.1 2002/10/24 09:30:47 gbazin Exp $
+ * $Id: vorbis.c,v 1.2 2002/10/27 16:58:14 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
/*
* Input properties
*/
- decoder_fifo_t * p_fifo; /* stores the PES stream data */
+ decoder_fifo_t *p_fifo; /* stores the PES stream data */
+ pes_packet_t *p_pes; /* current PES we are decoding */
/*
* Output properties
static void CloseDecoder ( dec_thread_t * );
static void DecodePacket ( dec_thread_t * );
-static int GetOggPacket ( dec_thread_t *, ogg_packet *, mtime_t *, int );
+static int GetOggPacket ( dec_thread_t *, ogg_packet *, mtime_t * );
static void Interleave ( float *, const float **, int, int );
/* Initialize the thread properties */
p_dec->p_fifo = p_fifo;
+ p_dec->p_pes = NULL;
/* Take care of the initial Vorbis header */
vorbis_info_init( &p_dec->vi );
vorbis_comment_init( &p_dec->vc );
- if( GetOggPacket( p_dec, &oggpacket, &i_pts, 0 ) != VLC_SUCCESS )
+ if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
goto error;
oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
/* 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, 1 ) != VLC_SUCCESS )
+ if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
goto error;
if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 )
goto error;
}
- if( GetOggPacket( p_dec, &oggpacket, &i_pts, 1 ) != VLC_SUCCESS )
+ if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
goto error;
if( vorbis_synthesis_headerin( &p_dec->vi, &p_dec->vc, &oggpacket ) < 0 )
int i_samples;
mtime_t i_pts;
- if( GetOggPacket( p_dec, &oggpacket, &i_pts, 1 ) != VLC_SUCCESS )
+ if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
{
/* This should mean an eos */
return;
* Returns VLC_EGENERIC in case of eof.
*****************************************************************************/
static int GetOggPacket( dec_thread_t *p_dec, ogg_packet *p_oggpacket,
- mtime_t *p_pts, int b_next )
+ mtime_t *p_pts )
{
- pes_packet_t *p_pes;
+ if( p_dec->p_pes ) input_DeletePES( p_dec->p_fifo->p_packets_mgt,
+ p_dec->p_pes );
- if( b_next ) NextPES( p_dec->p_fifo );
- p_pes = GetPES( p_dec->p_fifo );
+ input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes );
+ if( !p_dec->p_pes ) return VLC_EGENERIC;
- p_oggpacket->packet = p_pes->p_first->p_payload_start;
- p_oggpacket->bytes = p_pes->i_pes_size;
- p_oggpacket->granulepos = p_pes->i_dts;
+ 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_pts = p_pes->i_pts;
+ *p_pts = p_dec->p_pes->i_pts;
- return p_pes ? VLC_SUCCESS : VLC_EGENERIC;
+ return VLC_SUCCESS;
}
/*****************************************************************************
if( p_dec )
{
+ 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 );
* dec_dummy.c: dummy decoder plugin for vlc.
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: decoder.c,v 1.2 2002/08/04 17:40:49 sam Exp $
+ * $Id: decoder.c,v 1.3 2002/10/27 16:58:13 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
msg_Dbg( p_fifo, "dumping stream to file `%s'", psz_file );
- InitBitstream( &bit_stream, p_fifo, NULL, NULL );
+ if( InitBitstream( &bit_stream, p_fifo, NULL, NULL ) != VLC_SUCCESS )
+ {
+ msg_Err( p_fifo, "cannot initialize bitstream" );
+ p_fifo->b_error = 1;
+ DecoderError( p_fifo );
+ close( i_fd );
+ return -1;
+ }
while( !p_fifo->b_die && !p_fifo->b_error )
{
}
close( i_fd );
+ CloseBitstream( &bit_stream );
if( p_fifo->b_error )
{
return 0;
}
-
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.47 2002/09/01 21:20:29 massiot Exp $
+ * $Id: input_dec.c,v 1.48 2002/10/27 16:58:12 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
vlc_mutex_unlock( &p_decoder_fifo->data_lock );
}
+/****************************************************************************
+ * input_ExtractPES
+ *****************************************************************************
+ * Extract a PES from the fifo. If pp_pes is NULL then the PES is just
+ * deleted, otherwise *pp_pes will point to this PES.
+ ****************************************************************************/
+void input_ExtractPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
+{
+ pes_packet_t *p_pes;
+
+ vlc_mutex_lock( &p_fifo->data_lock );
+
+ if( p_fifo->p_first == NULL )
+ {
+ if( p_fifo->b_die )
+ {
+ vlc_mutex_unlock( &p_fifo->data_lock );
+ if( pp_pes ) *pp_pes = NULL;
+ return;
+ }
+
+ /* Signal the input thread we're waiting. This is only
+ * needed in case of slave clock (ES plug-in) but it won't
+ * harm. */
+ vlc_cond_signal( &p_fifo->data_wait );
+
+ /* Wait for the input to tell us when we received a packet. */
+ vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
+ }
+
+ p_pes = p_fifo->p_first;
+ p_fifo->p_first = p_pes->p_next;
+ p_pes->p_next = NULL;
+ p_fifo->i_depth--;
+
+ if( !p_fifo->p_first )
+ {
+ /* No PES in the FIFO. p_last is no longer valid. */
+ p_fifo->pp_last = &p_fifo->p_first;
+ }
+
+ vlc_mutex_unlock( &p_fifo->data_lock );
+
+ if( pp_pes )
+ *pp_pes = p_pes;
+ else
+ input_DeletePES( p_fifo->p_packets_mgt, p_pes );
+}
+
+/****************************************************************************
+ * input_FlushPESFifo
+ *****************************************************************************
+ * Empties the PES fifo of the decoder.
+ ****************************************************************************/
+void input_FlushPESFifo( decoder_fifo_t *p_fifo )
+{
+ pes_packet_t * p_pes;
+
+ vlc_mutex_lock( &p_fifo->data_lock );
+ while( p_fifo->p_first )
+ {
+ p_pes = p_fifo->p_first;
+ p_fifo->p_first = p_fifo->p_first->p_next;
+ input_DeletePES( p_fifo->p_packets_mgt, p_pes );
+ }
+ /* No PES in the FIFO. p_last is no longer valid. */
+ p_fifo->pp_last = &p_fifo->p_first;
+ vlc_mutex_unlock( &p_fifo->data_lock );
+}
+
/*****************************************************************************
* input_EscapeDiscontinuity: send a NULL packet to the decoders
*****************************************************************************/
* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ext-dec.c,v 1.38 2002/10/24 10:33:09 fenrir Exp $
+ * $Id: input_ext-dec.c,v 1.39 2002/10/27 16:58:12 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
#include "input_ext-plugins.h"
/*****************************************************************************
- * InitBitstream: initialize a bit_stream_t structure
+ * InitBitstream: initialize a bit_stream_t structure and returns VLC_SUCCESS
+ * on success.
*****************************************************************************/
-void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
+int InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
void (* pf_bitstream_callback)( bit_stream_t *, vlc_bool_t ),
void * p_callback_arg )
{
+ /* Get the first pes packet */
+ input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
+ if( !p_bit_stream->p_pes )
+ return VLC_EGENERIC;
+
p_bit_stream->p_decoder_fifo = p_fifo;
p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
p_bit_stream->p_callback_arg = p_callback_arg;
- /* Get the first data packet. */
- vlc_mutex_lock( &p_fifo->data_lock );
- while ( p_fifo->p_first == NULL )
- {
- if ( p_fifo->b_die )
- {
- vlc_mutex_unlock( &p_fifo->data_lock );
- return;
- }
- vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
- }
- p_bit_stream->p_data = p_fifo->p_first->p_first;
+ p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
p_bit_stream->fifo.buffer = 0;
p_bit_stream->fifo.i_available = 0;
- p_bit_stream->i_pts = p_fifo->p_first->i_pts;
- p_bit_stream->i_dts = p_fifo->p_first->i_dts;
+ p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
+ p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
- vlc_mutex_unlock( &p_fifo->data_lock );
/* Call back the decoder. */
if( p_bit_stream->pf_bitstream_callback != NULL )
* sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
AlignWord( p_bit_stream );
}
-}
-
-/*****************************************************************************
- * DecoderError : an error occured, use this function to empty the fifo
- *****************************************************************************/
-void DecoderError( decoder_fifo_t * p_fifo )
-{
- /* We take the lock, because we are going to read/write the start/end
- * indexes of the decoder fifo */
- vlc_mutex_lock (&p_fifo->data_lock);
-
- /* Wait until a `die' order is sent */
- while (!p_fifo->b_die)
- {
- /* Trash all received PES packets */
- input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
- p_fifo->p_first = NULL;
- p_fifo->pp_last = &p_fifo->p_first;
-
- /* If the input is waiting for us, tell him to stop */
- vlc_cond_signal( &p_fifo->data_wait );
-
- /* Waiting for the input thread to put new PES packets in the fifo */
- vlc_cond_wait (&p_fifo->data_wait, &p_fifo->data_lock);
- }
- /* We can release the lock before leaving */
- vlc_mutex_unlock (&p_fifo->data_lock);
+ return VLC_SUCCESS;
}
/*****************************************************************************
- * GetPES: return the first PES from the fifo
+ * CloseBitstream: free the bitstream structure.
*****************************************************************************/
-static inline pes_packet_t *_GetPES( decoder_fifo_t * p_fifo )
-{
- pes_packet_t * p_pes;
-
- vlc_mutex_lock( &p_fifo->data_lock );
-
- if( p_fifo->p_first == NULL )
- {
- /* No PES in the FIFO. p_last is no longer valid. */
- p_fifo->pp_last = &p_fifo->p_first;
-
- if( p_fifo->b_die )
- {
- vlc_mutex_unlock( &p_fifo->data_lock );
- return NULL;
- }
-
- /* Signal the input thread we're waiting. This is only
- * needed in case of slave clock (ES plug-in) but it won't
- * harm. */
- vlc_cond_signal( &p_fifo->data_wait );
-
- /* Wait for the input to tell us when we receive a packet. */
- vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
- }
-
- p_pes = p_fifo->p_first;
-
- vlc_mutex_unlock( &p_fifo->data_lock );
-
- return p_pes;
-}
-
-pes_packet_t * GetPES( decoder_fifo_t * p_fifo )
+void CloseBitstream( bit_stream_t * p_bit_stream )
{
- return( _GetPES( p_fifo ) );
+ if( p_bit_stream->p_pes )
+ input_DeletePES( p_bit_stream->p_decoder_fifo->p_packets_mgt,
+ p_bit_stream->p_pes );
}
/*****************************************************************************
- * NextPES: free the current PES and return the next one
+ * DecoderError : an error occured, use this function to empty the fifo
*****************************************************************************/
-static inline pes_packet_t * _NextPES( decoder_fifo_t * p_fifo )
+void DecoderError( decoder_fifo_t * p_fifo )
{
- pes_packet_t * p_next;
-
- if( p_fifo->p_first == NULL )
- {
- if( GetPES( p_fifo ) == NULL )
- {
- return( NULL );
- }
- }
-
- vlc_mutex_lock( &p_fifo->data_lock );
-
- /* Free the previous PES packet. */
- p_next = p_fifo->p_first->p_next;
- p_fifo->p_first->p_next = NULL;
- input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
- p_fifo->p_first = p_next;
- p_fifo->i_depth--;
+ /* No need to take the lock, because input_ExtractPES already takes it
+ * and also check for p_fifo->b_die */
- if( p_fifo->p_first == NULL )
+ /* Wait until a `die' order is sent */
+ while( !p_fifo->b_die )
{
- /* No PES in the FIFO. p_last is no longer valid. */
- p_fifo->pp_last = &p_fifo->p_first;
+ /* Trash all received PES packets */
+ input_ExtractPES( p_fifo, NULL );
}
-
- vlc_mutex_unlock( &p_fifo->data_lock );
-
- return _GetPES( p_fifo );
-}
-
-pes_packet_t * NextPES( decoder_fifo_t * p_fifo )
-{
- return( _NextPES( p_fifo ) );
}
/*****************************************************************************
* NextDataPacket: go to the data packet after *pp_data, return 1 if we
- * changed PES
+ * changed PES. This function can fail in case of end of stream, you can
+ * check p_bit_stream->p_data or p_bit_stream->p_pes to know wether we did get
+ * the next data packet.
*****************************************************************************/
static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
- data_packet_t ** pp_data )
+ bit_stream_t * p_bit_stream )
{
vlc_bool_t b_new_pes;
{
/* We were reading the last data packet of this PES packet... It's
* time to jump to the next PES packet */
- if( (*pp_data)->p_next == NULL )
+ if( p_bit_stream->p_data->p_next == NULL )
{
/* The next packet could be found in the next PES packet */
- *pp_data = (_NextPES( p_fifo ))->p_first;
-
+ input_DeletePES( p_fifo->p_packets_mgt, p_bit_stream->p_pes );
+ input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
+ if( !p_bit_stream->p_pes )
+ {
+ /* Couldn't get the next PES, might be an eos */
+ p_bit_stream->p_data = NULL;
+ return 0;
+ }
+ p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
b_new_pes = 1;
}
else
{
/* Perhaps the next data packet of the current PES packet contains
* real data (ie its payload's size is greater than 0). */
- *pp_data = (*pp_data)->p_next;
+ p_bit_stream->p_data = p_bit_stream->p_data->p_next;
b_new_pes = 0;
}
- } while ( (*pp_data)->p_payload_start == (*pp_data)->p_payload_end );
+ } while ( p_bit_stream->p_data->p_payload_start ==
+ p_bit_stream->p_data->p_payload_end );
return( b_new_pes );
}
-vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo, data_packet_t ** pp_data )
+vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo,
+ bit_stream_t * p_bit_stream )
{
- return( _NextDataPacket( p_fifo, pp_data ) );
+ return( _NextDataPacket( p_fifo, p_bit_stream ) );
}
/*****************************************************************************
* BitstreamNextDataPacket: go to the next data packet, and update bitstream
- * context
+ * context. This function can fail in case of eos!
*****************************************************************************/
static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
{
decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
vlc_bool_t b_new_pes;
- b_new_pes = _NextDataPacket( p_fifo, &p_bit_stream->p_data );
+ b_new_pes = _NextDataPacket( p_fifo, p_bit_stream );
+ if( !p_bit_stream->p_pes ) return;
/* We've found a data packet which contains interesting data... */
p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
}
/* Retrieve the PTS. */
- if( b_new_pes && p_fifo->p_first->i_pts )
+ if( b_new_pes && p_bit_stream->p_pes->i_pts )
{
- p_bit_stream->i_pts = p_fifo->p_first->i_pts;
- p_bit_stream->i_dts = p_fifo->p_first->i_dts;
+ p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
+ p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
}
}
if( pi_dts != NULL) *pi_dts = 0;
}
}
-
-/****************************************************************************
- * input_ExtractPES : extract a PES from the fifo. If pp_pes is NULL then this
- * PES is deleted, else pp_pes will be set to this PES
- ****************************************************************************/
-int input_ExtractPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
-{
- pes_packet_t *p_pes;
-
- p_pes = _GetPES( p_fifo );
-
- vlc_mutex_lock( &p_fifo->data_lock );
-
- p_fifo->p_first = p_pes->p_next;
- p_pes->p_next = NULL;
- p_fifo->i_depth--;
-
- if( !p_fifo->p_first )
- {
- /* No PES in the fifo */
- /* pp_last no longer valid */
- p_fifo->pp_last = &p_fifo->p_first;
- }
-
- vlc_mutex_unlock( &p_fifo->data_lock );
-
- if( pp_pes )
- {
- *pp_pes = p_pes;
- }
- else
- {
- input_DeletePES( p_fifo->p_packets_mgt, p_pes );
- }
- return( 0 );
-}