Commit 6d6601ea authored by Gildas Bazin's avatar Gildas Bazin

* ALL: removed GetPES and NextPES, we now use input_ExtractPES everywhere instead
   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().
parent cdf8646f
......@@ -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.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>
......@@ -167,7 +167,9 @@ struct bit_stream_t
/*
* 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;
......@@ -207,19 +209,16 @@ struct bit_stream_t
/*****************************************************************************
* 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
......
......@@ -3,7 +3,7 @@
* 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>
*
......@@ -58,6 +58,8 @@ VLC_EXPORT( int, input_UnselectES,( input_thread_t *, es_descriptor_t * ) );
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 * );
......
......@@ -2,7 +2,7 @@
* 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: Stphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -130,8 +130,14 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
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 )
......@@ -252,6 +258,7 @@ static void EndThread( dec_thread_t * p_dec )
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
CloseBitstream( &p_dec->bit_stream );
free( p_dec );
}
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -330,10 +330,8 @@ static int InitThread( a52dec_t * p_a52dec )
/*
* 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 ) );
}
/*****************************************************************************
......@@ -377,6 +375,7 @@ static void EndThread (a52dec_t * p_a52dec)
/* Free what's left of the decoder */
free( p_a52dec->imdct_orig );
CloseBitstream( p_a52dec->bit_stream );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -315,7 +315,8 @@ static void DecodeThread( adec_thread_t *p_adec )
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;
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -162,12 +162,24 @@ static inline void __GetFrame( videodec_thread_t *p_vdec )
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 )
......@@ -185,18 +197,19 @@ static inline void __GetFrame( videodec_thread_t *p_vdec )
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,
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -99,7 +99,14 @@ static int RunDecoder ( decoder_fifo_t *p_fifo )
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 );
......@@ -260,6 +267,7 @@ static int RunDecoder ( decoder_fifo_t *p_fifo )
}
free( p_buffer );
CloseBitstream( bit_stream );
if( p_fifo->b_error )
{
......@@ -303,4 +311,3 @@ static pes_packet_t *GetFirstPES( decoder_fifo_t *p_fifo )
return p_pes;
}
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -154,7 +154,13 @@ static inline void __GetFrame( adec_thread_t *p_adec )
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;
......@@ -162,7 +168,13 @@ static inline void __GetFrame( adec_thread_t *p_adec )
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 )
......@@ -194,11 +206,13 @@ static inline void __GetFrame( adec_thread_t *p_adec )
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 );
}
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -795,7 +795,7 @@ static void DecodeThread( videodec_thread_t *p_vdec )
/* 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
......@@ -808,7 +808,7 @@ static void DecodeThread( videodec_thread_t *p_vdec )
/* 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
......@@ -823,7 +823,8 @@ static void DecodeThread( videodec_thread_t *p_vdec )
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;
......@@ -842,7 +843,7 @@ static void DecodeThread( videodec_thread_t *p_vdec )
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 );
......
......@@ -2,7 +2,7 @@
* 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>
......@@ -121,8 +121,14 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
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 */
......@@ -140,6 +146,7 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
{
msg_Err( p_dec->p_fifo, "failed to create aout fifo" );
p_dec->p_fifo->b_error = 1;
EndThread( p_dec );
return( -1 );
}
......@@ -220,5 +227,6 @@ static void EndThread( dec_thread_t * p_dec )
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
CloseBitstream( &p_dec->bit_stream );
free( p_dec );
}
......@@ -136,8 +136,6 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
*****************************************************************************/
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;
......@@ -165,21 +163,7 @@ static int InitThread( mad_adec_thread_t * p_dec )
* 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 );
}
/*****************************************************************************
......@@ -196,6 +180,6 @@ static void EndThread (mad_adec_thread_t * p_dec)
/* 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 );
}
......@@ -42,7 +42,7 @@ typedef struct mad_adec_thread_s
* 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;
......
......@@ -81,7 +81,7 @@ enum mad_flow libmad_input( void *p_data, struct mad_stream *p_stream )
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
{
......@@ -89,27 +89,28 @@ enum mad_flow libmad_input( void *p_data, struct mad_stream *p_stream )
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 )
......@@ -354,7 +355,7 @@ enum mad_flow libmad_error( void *data, struct mad_stream *p_libmad_stream,
/****************************************************************************
* 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)
{
......
......@@ -2,7 +2,7 @@
* 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>
......@@ -109,7 +109,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
/*
* 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 */
......@@ -242,6 +248,8 @@ static void EndThread ( adec_thread_t *p_dec )
}
CloseBitstream( &p_dec->bit_stream );
/* Destroy descriptor */
free( p_dec );
}
......
......@@ -2,7 +2,7 @@
* 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>
......@@ -231,8 +231,14 @@ static int InitThread( vpar_thread_t *p_vpar )
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;
......@@ -383,6 +389,7 @@ static void EndThread( vpar_thread_t *p_vpar )
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 );
}
......@@ -399,9 +406,9 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
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;
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -166,10 +166,8 @@ static int InitThread( spudec_thread_t *p_spudec )
}
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 );
}
/*****************************************************************************
......@@ -201,6 +199,7 @@ static void EndThread( spudec_thread_t *p_spudec )
vlc_object_release( p_spudec->p_vout );
}
CloseBitstream( &p_spudec->bit_stream );
free( p_spudec );
}
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -61,7 +61,8 @@ typedef struct dec_thread_t
/*
* 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
......@@ -81,7 +82,7 @@ static int RunDecoder ( decoder_fifo_t * );
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 );
......@@ -129,12 +130,13 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
/* 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 :) */
......@@ -148,7 +150,7 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
/* 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 )
......@@ -157,7 +159,7 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
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 )
......@@ -235,7 +237,7 @@ static void DecodePacket( dec_thread_t *p_dec )
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;
......@@ -297,23 +299,24 @@ static void DecodePacket( dec_thread_t *p_dec )
* 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;
}
/*****************************************************************************
......@@ -345,6 +348,8 @@ static void CloseDecoder( dec_thread_t * p_dec )
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 );
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -81,7 +81,14 @@ static int Run ( decoder_fifo_t *p_fifo )
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 )
{
......@@ -107,6 +114,7 @@ static int Run ( decoder_fifo_t *p_fifo )
}
close( i_fd );
CloseBitstream( &bit_stream );
if( p_fifo->b_error )
{
......@@ -116,4 +124,3 @@ static int Run ( decoder_fifo_t *p_fifo )
return 0;
}
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -155,6 +155,76 @@ void input_DecodePES( decoder_fifo_t * p_decoder_fifo, pes_packet_t * p_pes )
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
*****************************************************************************/
......
......@@ -2,7 +2,7 @@
* 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>
*
......@@ -35,36 +35,30 @@
#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 )
......@@ -80,123 +74,44 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
* 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 )
void CloseBitstream( bit_stream_t * p_bit_stream )
{
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 )
{
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;
/* 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 )
{
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--;
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;
......@@ -206,41 +121,51 @@ static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
{
/* 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;
......@@ -259,10 +184,10 @@ static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
}
/* 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;
}
}
......@@ -524,39 +449,3 @@ void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
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 );
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment