X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=include%2Finput_ext-plugins.h;h=f83e04376cda787e00f3429effe6a738009e72c4;hb=4f6c862b021281a7e44a93aa5c774e6bb07a6a78;hp=9727a4a4a7bea442e972e3a47d652b6f42519805;hpb=48cbd8f3607519da4171671b8451b14f98244077;p=vlc diff --git a/include/input_ext-plugins.h b/include/input_ext-plugins.h index 9727a4a4a7..f83e04376c 100644 --- a/include/input_ext-plugins.h +++ b/include/input_ext-plugins.h @@ -2,8 +2,8 @@ * input_ext-plugins.h: structures of the input not exported to other modules, * but exported to plug-ins ***************************************************************************** - * Copyright (C) 1999-2001 VideoLAN - * $Id: input_ext-plugins.h,v 1.17 2002/02/15 13:32:52 sam Exp $ + * Copyright (C) 1999-2002 VideoLAN + * $Id: input_ext-plugins.h,v 1.21 2002/03/04 23:56:37 massiot Exp $ * * Authors: Christophe Massiot * @@ -31,6 +31,8 @@ * of data loss (this should be < 188). */ #define PADDING_PACKET_NUMBER 10 /* Number of padding packets top insert to * escape a decoder. */ +#define INPUT_DEFAULT_BUFSIZE 65536 /* Default buffer size to use when none + * is natural. */ #define NO_SEEK -1 /***************************************************************************** @@ -72,6 +74,7 @@ int input_UnselectES( struct input_thread_s *, struct es_descriptor_s * ); * Prototypes from input_dec.c *****************************************************************************/ #ifndef PLUGIN +//decoder_capabilities_s * input_ProbeDecoder( void ); vlc_thread_t input_RunDecoder( struct input_thread_s *, struct es_descriptor_s * ); void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * ); @@ -98,6 +101,44 @@ mtime_t input_ClockGetTS( struct input_thread_s *, # define input_ClockManageControl p_symbols->input_ClockManageControl #endif +/***************************************************************************** + * Prototypes from input_ext-plugins.h (buffers management) + *****************************************************************************/ +#ifndef PLUGIN +void * input_BuffersInit( void ); +void input_BuffersEnd( struct input_buffers_s * ); +struct data_buffer_s * input_NewBuffer( struct input_buffers_s *, size_t ); +void input_ReleaseBuffer( struct input_buffers_s *, struct data_buffer_s * ); +struct data_packet_s * input_ShareBuffer( struct input_buffers_s *, + struct data_buffer_s * ); +struct data_packet_s * input_NewPacket( struct input_buffers_s *, size_t ); +void input_DeletePacket( struct input_buffers_s *, struct data_packet_s * ); +struct pes_packet_s * input_NewPES( struct input_buffers_s * ); +void input_DeletePES( struct input_buffers_s *, struct pes_packet_s * ); +ssize_t input_FillBuffer( struct input_thread_s * ); +ssize_t input_Peek( struct input_thread_s *, byte_t **, size_t ); +ssize_t input_SplitBuffer( struct input_thread_s *, data_packet_t **, size_t ); +int input_AccessInit( struct input_thread_s * ); +void input_AccessReinit( struct input_thread_s * ); +void input_AccessEnd( struct input_thread_s * ); +#else +# define input_BuffersInit p_symbols->input_BuffersInit +# define input_BuffersEnd p_symbols->input_BuffersEnd +# define input_NewBuffer p_symbols->input_NewBuffer +# define input_ReleaseBuffer p_symbols->input_ReleaseBuffer +# define input_ShareBuffer p_symbols->input_ShareBuffer +# define input_NewPacket p_symbols->input_NewPacket +# define input_DeletePacket p_symbols->input_DeletePacket +# define input_NewPES p_symbols->input_NewPES +# define input_DeletePES p_symbols->input_DeletePES +# define input_FillBuffer p_symbols->input_FillBuffer +# define input_Peek p_symbols->input_Peek +# define input_SplitBuffer p_symbols->input_SplitBuffer +# define input_AccessInit p_symbols->input_AccessInit +# define input_AccessReinit p_symbols->input_AccessReinit +# define input_AccessEnd p_symbols->input_AccessEnd +#endif + /***************************************************************************** * Create a NULL packet for padding in case of a data loss *****************************************************************************/ @@ -107,11 +148,10 @@ static __inline__ void input_NullPacket( input_thread_t * p_input, data_packet_t * p_pad_data; pes_packet_t * p_pes; - if( (p_pad_data = p_input->pf_new_packet( - p_input->p_method_data, + if( (p_pad_data = input_NewPacket( p_input->p_method_data, PADDING_PACKET_SIZE )) == NULL ) { - intf_ErrMsg("Out of memory"); + intf_ErrMsg("input error: no new packet"); p_input->b_error = 1; return; } @@ -129,9 +169,9 @@ static __inline__ void input_NullPacket( input_thread_t * p_input, } else { - if( (p_pes = p_input->pf_new_pes( p_input->p_method_data )) == NULL ) + if( (p_pes = input_NewPES( p_input->p_method_data )) == NULL ) { - intf_ErrMsg("Out of memory"); + intf_ErrMsg("input error: no PES packet"); p_input->b_error = 1; return; } @@ -145,683 +185,6 @@ static __inline__ void input_NullPacket( input_thread_t * p_input, } -/* - * Optional Next Generation buffer manager - * - * Either buffers can only be used in one data packet (PS case), or buffers - * contain several data packets (DVD case). In the first case, buffers are - * embedded into data packets, otherwise they are allocated separately and - * shared with a refcount. --Meuuh - */ - -/* Number of buffers for the calculation of the mean */ -#define INPUT_BRESENHAM_NB 50 - -/* Flags */ -#define BUFFERS_NOFLAGS 0 -#define BUFFERS_UNIQUE_SIZE 1 /* Only with NB_LIFO == 1 */ - -/***************************************************************************** - * _input_buffers_t: defines a LIFO per data type to keep - *****************************************************************************/ -#define PACKETS_LIFO( TYPE, NAME ) \ -struct \ -{ \ - TYPE * p_stack; \ - unsigned int i_depth; \ -} NAME; - -#define BUFFERS_LIFO( TYPE, NAME ) \ -struct \ -{ \ - TYPE * p_stack; /* First item in the LIFO */ \ - unsigned int i_depth; /* Number of items in the LIFO */ \ - unsigned int i_average_size; /* Average size of the items (Bresenham) */\ -} NAME; - -#define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ) \ -typedef struct _input_buffers_s \ -{ \ - vlc_mutex_t lock; \ - PACKETS_LIFO( pes_packet_t, pes ) \ - BUFFERS_LIFO( _data_packet_t, data[NB_LIFO] ) \ - size_t i_allocated; \ -} _input_buffers_t; - -#define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO ) \ -typedef struct _input_buffers_s \ -{ \ - vlc_mutex_t lock; \ - PACKETS_LIFO( pes_packet_t, pes ) \ - PACKETS_LIFO( _data_packet_t, data ) \ - BUFFERS_LIFO( _data_buffer_t, buffers[NB_LIFO] ) \ - size_t i_allocated; \ -} _input_buffers_t; - -/* Data buffer, used in case the buffer can be shared between several data - * packets */ -typedef struct _data_buffer_s -{ - struct _data_buffer_s * p_next; - - /* number of data packets this buffer is referenced from - when it falls - * down to 0, the buffer is freed */ - int i_refcount; - - struct /* for compatibility with _data_packet_t */ - { - /* size of the current buffer (starting right thereafter) */ - unsigned int i_size; - } _private; -} _data_buffer_t; - -/* We overload the data_packet_t type to add private members */ -typedef struct _data_packet_s -{ - struct _data_packet_s * p_next; - - DATA_PACKET - - union - { - struct _data_buffer_s * p_buffer; /* in case of shared buffers */ - /* size of the embedded buffer (starting right thereafter) */ - unsigned int i_size; - } _private; -} _data_packet_t; - - -/***************************************************************************** - * input_BuffersInit: initialize the cache structures, return a pointer to it - *****************************************************************************/ -#define DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO ) \ -static void * input_BuffersInit( void ) \ -{ \ - _input_buffers_t * p_buffers = malloc( sizeof( _input_buffers_t ) ); \ - \ - if( p_buffers == NULL ) \ - { \ - return( NULL ); \ - } \ - \ - memset( p_buffers, 0, sizeof( _input_buffers_t ) ); \ - vlc_mutex_init( &p_buffers->lock ); \ - \ - return (void *)p_buffers; \ -} - -/***************************************************************************** - * input_BuffersEnd: free all cached structures - *****************************************************************************/ -#define BUFFERS_END_STAT_BUFFERS_LOOP( STRUCT ) \ - for( i = 0; i < NB_LIFO; i++ ) \ - { \ - if( FLAGS & BUFFERS_UNIQUE_SIZE ) \ - { \ - intf_StatMsg( \ - "input buffers stats: " #STRUCT "[%d]: %d packets", \ - i, p_buffers->STRUCT[i].i_depth ); \ - } \ - else \ - { \ - intf_StatMsg( \ - "input buffers stats: " #STRUCT "[%d]: %d bytes, %d packets", \ - i, p_buffers->STRUCT[i].i_average_size, \ - p_buffers->STRUCT[i].i_depth ); \ - } \ - } - -#define BUFFERS_END_STAT( FLAGS, NB_LIFO ) \ - BUFFERS_END_STAT_BUFFERS_LOOP( data ); - -#define BUFFERS_END_STAT_SHARED( FLAGS, NB_LIFO ) \ - intf_StatMsg( "input buffers stats: data: %d packets", \ - p_buffers->data.i_depth ); \ - BUFFERS_END_STAT_BUFFERS_LOOP( buffers ); - - -#define BUFFERS_END_BUFFERS_LOOP \ - while( p_buf != NULL ) \ - { \ - p_next = p_buf->p_next; \ - p_buffers->i_allocated -= p_buf->_private.i_size; \ - free( p_buf ); \ - p_buf = p_next; \ - } - -#define BUFFERS_END_PACKETS_LOOP \ - while( p_packet != NULL ) \ - { \ - p_next = p_packet->p_next; \ - free( p_packet ); \ - p_packet = p_next; \ - } - -#define BUFFERS_END_LOOP( FLAGS, NB_LIFO ) \ - for( i = 0; i < NB_LIFO; i++ ) \ - { \ - _data_packet_t * p_next; \ - _data_packet_t * p_buf = p_buffers->data[i].p_stack; \ - BUFFERS_END_BUFFERS_LOOP; \ - } \ - -#define BUFFERS_END_LOOP_SHARED( FLAGS, NB_LIFO ) \ - { \ - /* Free data packets */ \ - _data_packet_t * p_next; \ - _data_packet_t * p_packet = p_buffers->data.p_stack; \ - BUFFERS_END_PACKETS_LOOP; \ - } \ - \ - for( i = 0; i < NB_LIFO; i++ ) \ - { \ - _data_buffer_t * p_next; \ - _data_buffer_t * p_buf = p_buffers->buffers[i].p_stack; \ - BUFFERS_END_BUFFERS_LOOP; \ - } \ - -#define BUFFERS_END( FLAGS, NB_LIFO, STAT_LOOP, LOOP ) \ -static void input_BuffersEnd( void * _p_buffers ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - \ - if( _p_buffers != NULL ) \ - { \ - int i; \ - \ - if( p_main->b_stats ) \ - { \ - int i; \ - intf_StatMsg( "input buffers stats: pes: %d packets", \ - p_buffers->pes.i_depth ); \ - STAT_LOOP( FLAGS, NB_LIFO ); \ - } \ - \ - { \ - /* Free PES */ \ - pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack; \ - BUFFERS_END_PACKETS_LOOP; \ - } \ - \ - LOOP( FLAGS, NB_LIFO ); \ - \ - if( p_buffers->i_allocated ) \ - { \ - intf_ErrMsg( "input buffers error: %d bytes have not been" \ - " freed, expect memory leak", \ - p_buffers->i_allocated ); \ - } \ - \ - vlc_mutex_destroy( &p_buffers->lock ); \ - free( _p_buffers ); \ - } \ -} - -#define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \ - BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT, BUFFERS_END_LOOP ); - -#define DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO ) \ - BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT_SHARED, \ - BUFFERS_END_LOOP_SHARED ); - -/***************************************************************************** - * input_NewPacket: return a pointer to a data packet of the appropriate size - *****************************************************************************/ -#define BUFFERS_NEWPACKET_EXTRA_DECLARATION( FLAGS, NB_LIFO ) \ - _data_packet_t ** pp_data = &p_buf; - -#define BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED( FLAGS, NB_LIFO ) \ - _data_packet_t * p_data; \ - _data_packet_t ** pp_data = &p_data; - -#define BUFFERS_NEWPACKET_EXTRA( FLAGS, NB_LIFO ) - -#define BUFFERS_NEWPACKET_EXTRA_SHARED( FLAGS, NB_LIFO ) \ - /* Find a data packet */ \ - if( p_buffers->data.p_stack != NULL ) \ - { \ - p_data = p_buffers->data.p_stack; \ - p_buffers->data.p_stack = p_data->p_next; \ - p_buffers->data.i_depth--; \ - } \ - else \ - { \ - p_data = malloc( sizeof( _data_packet_t ) ); \ - if( p_data == NULL ) \ - { \ - intf_ErrMsg( "Out of memory" ); \ - vlc_mutex_unlock( &p_buffers->lock ); \ - return( NULL ); \ - } \ - } \ - \ - if( i_size == 0 ) \ - { \ - /* Warning : in that case, the data packet is left partly \ - * uninitialized ; theorically only input_ShareBuffer may call \ - * this. */ \ - p_data->p_next = NULL; \ - p_data->b_discard_payload = 0; \ - return( (data_packet_t *)p_data ); \ - } - -#define BUFFERS_NEWPACKET_END( FLAGS, NB_LIFO, TYPE ) \ - (*pp_data)->p_demux_start = (byte_t *)*pp_data + sizeof( TYPE ); - -#define BUFFERS_NEWPACKET_END_SHARED( FLAGS, NB_LIFO, TYPE ) \ - (*pp_data)->_private.p_buffer = p_buf; \ - (*pp_data)->p_demux_start = (byte_t *)(*pp_data)->_private.p_buffer \ - + sizeof( TYPE ); \ - /* Initialize refcount */ \ - p_buf->i_refcount = 1; - -#define BUFFERS_NEWPACKET( FLAGS, NB_LIFO, TYPE, NAME, EXTRA_DECLARATION, \ - EXTRA, END ) \ -/* This one doesn't take p_buffers->lock. */ \ -static __inline__ data_packet_t * _input_NewPacket( void * _p_buffers, \ - size_t i_size ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - int i_select; \ - TYPE * p_buf; \ - EXTRA_DECLARATION( FLAGS, NB_LIFO ); \ - \ - /* Safety check */ \ - if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \ - { \ - intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \ - p_buffers->i_allocated ); \ - return NULL; \ - } \ - \ - EXTRA( FLAGS, NB_LIFO ); \ - \ - for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \ - { \ - if( i_size <= (2 * p_buffers->NAME[i_select].i_average_size \ - + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \ - { \ - break; \ - } \ - } \ - \ - if( p_buffers->NAME[i_select].p_stack != NULL ) \ - { \ - /* Take the packet from the cache */ \ - p_buf = p_buffers->NAME[i_select].p_stack; \ - p_buffers->NAME[i_select].p_stack = p_buf->p_next; \ - p_buffers->NAME[i_select].i_depth--; \ - \ - /* Reallocate the packet if it is too small or too large */ \ - if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && \ - (p_buf->_private.i_size < i_size \ - || p_buf->_private.i_size > 3 * i_size) ) \ - { \ - p_buffers->i_allocated -= p_buf->_private.i_size; \ - p_buf = realloc( p_buf, sizeof( TYPE ) + i_size ); \ - if( p_buf == NULL ) \ - { \ - intf_ErrMsg( "Out of memory" ); \ - return NULL; \ - } \ - p_buf->_private.i_size = i_size; \ - p_buffers->i_allocated += i_size; \ - } \ - } \ - else \ - { \ - /* Allocate a new packet */ \ - p_buf = malloc( sizeof( TYPE ) + i_size ); \ - if( p_buf == NULL ) \ - { \ - intf_ErrMsg( "Out of memory" ); \ - return NULL; \ - } \ - p_buf->_private.i_size = i_size; \ - p_buffers->i_allocated += i_size; \ - } \ - \ - /* Initialize data */ \ - END( FLAGS, NB_LIFO, TYPE ); \ - (*pp_data)->p_next = NULL; \ - (*pp_data)->b_discard_payload = 0; \ - (*pp_data)->p_payload_start = (*pp_data)->p_demux_start; \ - (*pp_data)->p_payload_end = (*pp_data)->p_payload_start + i_size; \ - \ - return( (data_packet_t *)*pp_data ); \ -} \ - \ -static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - data_packet_t * p_data; \ - \ - /* Safety check */ \ - if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && i_size > INPUT_MAX_PACKET_SIZE ) \ - { \ - intf_ErrMsg( "Packet too big (%d)", i_size ); \ - return NULL; \ - } \ - \ - vlc_mutex_lock( &p_buffers->lock ); \ - p_data = _input_NewPacket( _p_buffers, i_size ); \ - vlc_mutex_unlock( &p_buffers->lock ); \ - return( p_data ); \ -} - -#define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ) \ - BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_packet_t, data, \ - BUFFERS_NEWPACKET_EXTRA_DECLARATION, BUFFERS_NEWPACKET_EXTRA, \ - BUFFERS_NEWPACKET_END ) - -#define DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO ) \ - BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_buffer_t, buffers, \ - BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED, \ - BUFFERS_NEWPACKET_EXTRA_SHARED, BUFFERS_NEWPACKET_END_SHARED ) - -/***************************************************************************** - * input_DeletePacket: put a packet back into the cache - *****************************************************************************/ -#define BUFFERS_DELETEPACKET_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \ - _data_packet_t * p_buf = p_data; - -#define BUFFERS_DELETEPACKET_EXTRA_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE )\ - _data_buffer_t * p_buf = (_data_buffer_t *)p_data->_private.p_buffer; \ - \ - /* Get rid of the data packet */ \ - if( p_buffers->data.i_depth < DATA_CACHE_SIZE ) \ - { \ - /* Cache not full : store the packet in it */ \ - p_data->p_next = p_buffers->data.p_stack; \ - p_buffers->data.p_stack = p_data; \ - p_buffers->data.i_depth++; \ - } \ - else \ - { \ - free( p_data ); \ - } \ - \ - /* Decrement refcount */ \ - p_buf->i_refcount--; \ - if( p_buf->i_refcount > 0 ) \ - { \ - return; \ - } - -#define BUFFERS_DELETEPACKETSTACK_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - _data_packet_t * p_first = (_data_packet_t *)_p_first; \ - _data_packet_t ** pp_last = (_data_packet_t **)_pp_last; \ - \ - /* Small hopeless optimization */ \ - if( (FLAGS & BUFFERS_UNIQUE_SIZE) \ - && p_buffers->data[0].i_depth < DATA_CACHE_SIZE ) \ - { \ - p_buffers->data[0].i_depth += i_nb; \ - *pp_last = p_buffers->data[0].p_stack; \ - p_buffers->data[0].p_stack = p_first; \ - } \ - else /* No semicolon after this or you will die */ - -#define BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED( FLAGS, NB_LIFO, \ - DATA_CACHE_SIZE ) - -#define BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, TYPE, \ - NAME, EXTRA, EXTRA_STACK ) \ -/* This one doesn't take p_buffers->lock. */ \ -static __inline__ void _input_DeletePacket( void * _p_buffers, \ - data_packet_t * _p_data ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - _data_packet_t * p_data = (_data_packet_t *)_p_data; \ - int i_select; \ - \ - while( p_data != NULL ) \ - { \ - _data_packet_t * p_next = p_data->p_next; \ - \ - EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ); \ - \ - for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \ - { \ - if( p_buf->_private.i_size <= \ - (2 * p_buffers->NAME[i_select].i_average_size \ - + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \ - { \ - break; \ - } \ - } \ - \ - if( p_buffers->NAME[i_select].i_depth < DATA_CACHE_SIZE ) \ - { \ - /* Cache not full : store the packet in it */ \ - p_buf->p_next = p_buffers->NAME[i_select].p_stack; \ - p_buffers->NAME[i_select].p_stack = p_buf; \ - p_buffers->NAME[i_select].i_depth++; \ - \ - if( !(FLAGS & BUFFERS_UNIQUE_SIZE) ) \ - { \ - /* Update Bresenham mean (very approximative) */ \ - p_buffers->NAME[i_select].i_average_size = \ - ( p_buf->_private.i_size \ - + p_buffers->NAME[i_select].i_average_size \ - * (INPUT_BRESENHAM_NB - 1) ) \ - / INPUT_BRESENHAM_NB; \ - } \ - } \ - else \ - { \ - p_buffers->i_allocated -= p_buf->_private.i_size; \ - free( p_buf ); \ - } \ - \ - p_data = p_next; \ - } \ -} \ - \ -static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - \ - vlc_mutex_lock( &p_buffers->lock ); \ - _input_DeletePacket( _p_buffers, p_data ); \ - vlc_mutex_unlock( &p_buffers->lock ); \ -} \ - \ -/* Delete a chained list of i_nb data packets. -- needed by DeletePES */ \ -static __inline__ void _input_DeletePacketStack( void * _p_buffers, \ - data_packet_t * _p_first, \ - data_packet_t ** _pp_last, \ - unsigned int i_nb ) \ -{ \ - /* Do not add code before, EXTRA_STACK makes its own declarations. */ \ - EXTRA_STACK( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \ - /* No semicolon - PLEASE */ \ - { \ - _input_DeletePacket( _p_buffers, _p_first ); \ - } \ -} - -#define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \ - BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_packet_t, \ - data, BUFFERS_DELETEPACKET_EXTRA, \ - BUFFERS_DELETEPACKETSTACK_EXTRA ) - -#define DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, \ - DATA_CACHE_SIZE ) \ - BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_buffer_t, \ - buffers, BUFFERS_DELETEPACKET_EXTRA_SHARED, \ - BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED ) - -/***************************************************************************** - * input_DeletePacketStack: optimize deleting of a stack of packets when - * knowing much information - *****************************************************************************/ -/* AFAIK, this isn't used by anyone - it is here for completion. - * _input_DeletePacketStack is declared in DeletePacket because it is needed - * by DeletePES. */ -#define DECLARE_BUFFERS_DELETEPACKETSTACK( FLAGS, NB_LIFO ) \ -static void input_DeletePacketStack( void * _p_buffers, \ - data_packet_t * p_first, \ - data_packet_t ** pp_last, \ - unsigned int i_nb ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - \ - vlc_mutex_lock( &p_buffers->lock ); \ - _input_DeletePacketStack( _p_buffers, p_first, pp_last, i_nb ); \ - vlc_mutex_unlock( &p_buffers->lock ); \ -} - -/***************************************************************************** - * input_NewPES: return a pointer to a new PES packet - *****************************************************************************/ -#define DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO ) \ -static pes_packet_t * input_NewPES( void * _p_buffers ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - pes_packet_t * p_pes; \ - \ - vlc_mutex_lock( &p_buffers->lock ); \ - \ - if( p_buffers->pes.p_stack != NULL ) \ - { \ - p_pes = p_buffers->pes.p_stack; \ - p_buffers->pes.p_stack = p_pes->p_next; \ - p_buffers->pes.i_depth--; \ - } \ - else \ - { \ - p_pes = malloc( sizeof( pes_packet_t ) ); \ - if( p_pes == NULL ) \ - { \ - intf_ErrMsg( "Out of memory" ); \ - vlc_mutex_unlock( &p_buffers->lock ); \ - return( NULL ); \ - } \ - } \ - \ - vlc_mutex_unlock( &p_buffers->lock ); \ - \ - /* Initialize data */ \ - p_pes->p_next = NULL; \ - p_pes->b_data_alignment = p_pes->b_discontinuity = \ - p_pes->i_pts = p_pes->i_dts = 0; \ - p_pes->i_pes_size = 0; \ - p_pes->p_first = p_pes->p_last = NULL; \ - p_pes->i_nb_data = 0; \ - \ - return( p_pes ); \ -} - -/***************************************************************************** - * input_DeletePES: put a pes and all data packets back into the cache - *****************************************************************************/ -#define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE ) \ -static void input_DeletePES( void * _p_buffers, pes_packet_t * p_pes ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - \ - vlc_mutex_lock( &p_buffers->lock ); \ - \ - while( p_pes != NULL ) \ - { \ - pes_packet_t * p_next = p_pes->p_next; \ - \ - /* Delete all data packets */ \ - if( p_pes->p_first != NULL ) \ - { \ - _input_DeletePacketStack( _p_buffers, p_pes->p_first, \ - &p_pes->p_last->p_next, \ - p_pes->i_nb_data ); \ - } \ - \ - if( p_buffers->pes.i_depth < PES_CACHE_SIZE ) \ - { \ - /* Cache not full : store the packet in it */ \ - p_pes->p_next = p_buffers->pes.p_stack; \ - p_buffers->pes.p_stack = p_pes; \ - p_buffers->pes.i_depth++; \ - } \ - else \ - { \ - free( p_pes ); \ - } \ - \ - p_pes = p_next; \ - } \ - \ - vlc_mutex_unlock( &p_buffers->lock ); \ -} - -/***************************************************************************** - * input_BuffersToIO: return an IO vector (only with BUFFERS_UNIQUE_SIZE) - *****************************************************************************/ -#define DECLARE_BUFFERS_TOIO( FLAGS, BUFFER_SIZE ) \ -static data_packet_t * input_BuffersToIO( void * _p_buffers, \ - struct iovec * p_iovec, int i_nb )\ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - data_packet_t * p_data = NULL; \ - int i; \ - \ - vlc_mutex_lock( &p_buffers->lock ); \ - \ - for( i = i_nb - 1; i >= 0; i-- ) \ - { \ - data_packet_t * p_next = _input_NewPacket( _p_buffers, \ - BUFFER_SIZE /* UNIQUE_SIZE */ ); \ - if( p_next == NULL ) \ - { \ - _input_DeletePacket( _p_buffers, p_data ); \ - return( NULL ); \ - } \ - \ - p_iovec[i].iov_base = p_next->p_demux_start; \ - p_iovec[i].iov_len = BUFFER_SIZE; \ - p_next->p_next = p_data; \ - p_data = p_next; \ - } \ - \ - vlc_mutex_unlock( &p_buffers->lock ); \ - \ - return( p_data ); \ -} - -/***************************************************************************** - * input_ShareBuffer: return a new data_packet to the same buffer - *****************************************************************************/ -#define DECLARE_BUFFERS_SHAREBUFFER( FLAGS ) \ -static data_packet_t * input_ShareBuffer( void * _p_buffers, \ - data_packet_t * _p_shared_data ) \ -{ \ - _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \ - _data_packet_t * p_shared_data = (_data_packet_t *)_p_shared_data; \ - _data_packet_t * p_data; \ - _data_buffer_t * p_buf = p_shared_data->_private.p_buffer; \ - \ - vlc_mutex_lock( &p_buffers->lock ); \ - \ - /* Get new data_packet_t, without a buffer through a special backdoor \ - * in _input_NewPacket. */ \ - p_data = (_data_packet_t *)_input_NewPacket( _p_buffers, 0 ); \ - \ - /* Finish initialization of p_data */ \ - p_data->_private.p_buffer = p_shared_data->_private.p_buffer; \ - p_data->p_demux_start = p_data->p_payload_start \ - = (byte_t *)p_shared_data->_private.p_buffer \ - + sizeof( _data_buffer_t ); \ - p_data->p_payload_end = p_data->p_demux_start + p_buf->_private.i_size; \ - \ - /* Update refcount */ \ - p_buf->i_refcount++; \ - \ - vlc_mutex_unlock( &p_buffers->lock ); \ - \ - return( (data_packet_t *)p_data ); \ -} - - /* * Optional MPEG demultiplexing */ @@ -830,6 +193,7 @@ static data_packet_t * input_ShareBuffer( void * _p_buffers, \ * Constants *****************************************************************************/ #define TS_PACKET_SIZE 188 /* Size of a TS packet */ +#define TS_SYNC_CODE 0x47 /* First byte of a TS packet */ #define PSI_SECTION_SIZE 4096 /* Maximum size of a PSI section */ #define PAT_UNINITIALIZED (1 << 6) @@ -923,8 +287,10 @@ typedef struct stream_ps_data_s void input_ParsePES ( struct input_thread_s *, struct es_descriptor_s * ); void input_GatherPES ( struct input_thread_s *, struct data_packet_s *, struct es_descriptor_s *, boolean_t, boolean_t ); +ssize_t input_ReadPS ( struct input_thread_s *, struct data_packet_s ** ); es_descriptor_t * input_ParsePS( struct input_thread_s *, struct data_packet_s * ); +ssize_t input_ReadTS ( struct input_thread_s *, struct data_packet_s ** ); void input_DemuxPS ( struct input_thread_s *, struct data_packet_s * ); void input_DemuxTS ( struct input_thread_s *, struct data_packet_s * ); void input_DemuxPSI ( struct input_thread_s *, struct data_packet_s *, @@ -932,9 +298,40 @@ void input_DemuxPSI ( struct input_thread_s *, struct data_packet_s *, #else # define input_ParsePES p_symbols->input_ParsePES # define input_GatherPES p_symbols->input_GatherPES +# define input_ReadPS p_symbols->input_ReadPS # define input_ParsePS p_symbols->input_ParsePS # define input_DemuxPS p_symbols->input_DemuxPS +# define input_ReadTS p_symbols->input_ReadTS # define input_DemuxTS p_symbols->input_DemuxTS # define input_DemuxPSI p_symbols->input_DemuxPSI #endif + +/* + * Optional standard file descriptor operations (input_ext-plugins.h) + */ + +/***************************************************************************** + * input_socket_t: private access plug-in data + *****************************************************************************/ +typedef struct input_socket_s +{ + /* Unbuffered file descriptor */ + int i_handle; +} input_socket_t; + +/***************************************************************************** + * Prototypes + *****************************************************************************/ +#ifndef PLUGIN +void input_FDClose( struct input_thread_s * ); +ssize_t input_FDRead( input_thread_t *, byte_t *, size_t ); +ssize_t input_FDNetworkRead( input_thread_t *, byte_t *, size_t ); +void input_FDSeek( struct input_thread_s *, off_t ); +#else +# define input_FDClose p_symbols->input_FDClose +# define input_FDRead p_symbols->input_FDRead +# define input_FDNetworkRead p_symbols->input_FDNetworkRead +# define input_FDSeek p_symbols->input_FDSeek +#endif +