From: Stéphane Borel Date: Sun, 11 Nov 2001 01:32:03 +0000 (+0000) Subject: -Merged DVD netlist with input netlist to remove duplicated code. X-Git-Tag: 0.2.91~19 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=81cfe15f7a54ebbc32b0a7fe8d33fa6c0ba5246b;p=vlc -Merged DVD netlist with input netlist to remove duplicated code. Basically, this adds the ability for the netlist to handle transport packets that carry more than one data_packet. --- diff --git a/include/input_ext-plugins.h b/include/input_ext-plugins.h index b01bd0ae44..ff806fdcb1 100644 --- a/include/input_ext-plugins.h +++ b/include/input_ext-plugins.h @@ -3,7 +3,7 @@ * but exported to plug-ins ***************************************************************************** * Copyright (C) 1999, 2000, 2001 VideoLAN - * $Id: input_ext-plugins.h,v 1.2 2001/07/18 14:21:00 massiot Exp $ + * $Id: input_ext-plugins.h,v 1.3 2001/11/11 01:32:03 stef Exp $ * * Authors: Christophe Massiot * @@ -156,13 +156,18 @@ typedef struct netlist_s struct iovec * p_free_iovec; /* FIFO size */ + unsigned int i_nb_iovec; unsigned int i_nb_pes; unsigned int i_nb_data; /* Index */ + unsigned int i_iovec_start, i_iovec_end; unsigned int i_data_start, i_data_end; unsigned int i_pes_start, i_pes_end; + /* Reference counters for iovec */ + unsigned int * pi_refcount; + /* Number of blocs read once by readv */ unsigned int i_read_once; } netlist_t; @@ -171,17 +176,23 @@ typedef struct netlist_s * Prototypes *****************************************************************************/ int input_NetlistInit( struct input_thread_s *, - int i_nb_data, int i_nb_pes, + int i_nb_iovec, + int i_nb_data, + int i_nb_pes, size_t i_buffer_size, int i_read_once ); -struct iovec * input_NetlistGetiovec( void * p_method_data ); -void input_NetlistMviovec( void * , size_t, struct data_packet_s **); +struct iovec * input_NetlistGetiovec( void * p_method_data ); +void input_NetlistMviovec( void * , int, + struct data_packet_s **); +struct data_packet_s * input_NetlistNewPtr( void * ); struct data_packet_s * input_NetlistNewPacket( void *, size_t ); struct pes_packet_s * input_NetlistNewPES( void * ); -void input_NetlistDeletePacket( void *, struct data_packet_s * ); -void input_NetlistDeletePES( void *, struct pes_packet_s * ); -void input_NetlistEnd( struct input_thread_s * ); +void input_NetlistDeletePacket( void *, + struct data_packet_s * ); +void input_NetlistDeletePES( void *, + struct pes_packet_s * ); +void input_NetlistEnd( struct input_thread_s * ); /* diff --git a/include/modules_export.h b/include/modules_export.h index a695099b8a..e4b4951d45 100644 --- a/include/modules_export.h +++ b/include/modules_export.h @@ -121,11 +121,12 @@ typedef struct module_symbols_s mtime_t ); int ( * input_NetlistInit ) ( struct input_thread_s *, - int, int, size_t, int ); + int, int, int, size_t, int ); struct iovec * ( * input_NetlistGetiovec ) ( void * p_method_data ); - void ( * input_NetlistMviovec ) ( void * , size_t, + void ( * input_NetlistMviovec ) ( void * , int, struct data_packet_s **); struct data_packet_s * ( * input_NetlistNewPacket ) ( void *, size_t ); + struct data_packet_s * ( * input_NetlistNewPtr ) ( void * ); struct pes_packet_s * ( * input_NetlistNewPES ) ( void * ); void ( * input_NetlistDeletePacket ) ( void *, struct data_packet_s * ); void ( * input_NetlistDeletePES ) ( void *, struct pes_packet_s * ); @@ -192,6 +193,7 @@ typedef struct module_symbols_s (p_symbols)->input_NetlistGetiovec = input_NetlistGetiovec; \ (p_symbols)->input_NetlistMviovec = input_NetlistMviovec; \ (p_symbols)->input_NetlistNewPacket = input_NetlistNewPacket; \ + (p_symbols)->input_NetlistNewPtr = input_NetlistNewPtr; \ (p_symbols)->input_NetlistNewPES = input_NetlistNewPES; \ (p_symbols)->input_NetlistDeletePacket = input_NetlistDeletePacket; \ (p_symbols)->input_NetlistDeletePES = input_NetlistDeletePES; \ diff --git a/plugins/dvd/Makefile b/plugins/dvd/Makefile index 45c551f2b5..7fc59f1aab 100644 --- a/plugins/dvd/Makefile +++ b/plugins/dvd/Makefile @@ -7,7 +7,7 @@ # Objects # -PLUGIN_DVD = dvd.o input_dvd.o dvd_netlist.o dvd_ifo.o dvd_udf.o dvd_summary.o $(OBJ_DVD) +PLUGIN_DVD = dvd.o input_dvd.o dvd_ifo.o dvd_udf.o dvd_summary.o $(OBJ_DVD) BUILTIN_DVD = $(PLUGIN_DVD:%.o=BUILTIN_%.o) ALL_OBJ = $(PLUGIN_DVD) $(BUILTIN_DVD) diff --git a/plugins/dvd/dvd_netlist.c b/plugins/dvd/dvd_netlist.c deleted file mode 100644 index 5789598911..0000000000 --- a/plugins/dvd/dvd_netlist.c +++ /dev/null @@ -1,598 +0,0 @@ -/***************************************************************************** - * dvd_netlist.c: Specific netlist for DVD packets - ***************************************************************************** - * The original is in src/input. - * There is only one major change from input_netlist.c : data is now a - * pointer to an offset in iovec ; and iovec has a reference counter. It - * will only be given back to netlist when refcount is zero. - ***************************************************************************** - * Copyright (C) 1998, 1999, 2000, 2001 VideoLAN - * $Id: dvd_netlist.c,v 1.14 2001/08/09 20:16:17 jlj Exp $ - * - * Authors: Henri Fallon - * Stéphane Borel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include "defs.h" - -#include -#include /* memcpy(), memset() */ -#include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#if defined( WIN32 ) -# include /* read() */ -#else -# include /* struct iovec */ -#endif - -#include "config.h" -#include "common.h" -#include "threads.h" /* mutex */ -#include "mtime.h" -#include "intf_msg.h" /* intf_*Msg */ - -#if defined( WIN32 ) -# include "input_iovec.h" -#endif - -#include "stream_control.h" -#include "input_ext-intf.h" -#include "input_ext-dec.h" -#include "input_ext-plugins.h" - -#include "dvd_netlist.h" - -#include "modules.h" -#include "modules_export.h" - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ - -/***************************************************************************** - * DVDNetlistInit: allocates netlist buffers and init indexes - * --- - * Changes from input_NetList: we have to give the length of the buffer which - * is different from i_nb_data now, since we may have several data pointers - * in one iovec. Thus we can only delete an iovec when its refcount is 0. - * We only received a buffer with a GetIovec whereas NewPacket gives a pointer. - * - * Warning: i_nb_iovec, i_nb_data, i_nb_pes have to be 2^x - *****************************************************************************/ -dvd_netlist_t * DVDNetlistInit( int i_nb_iovec, int i_nb_data, int i_nb_pes, - size_t i_buffer_size, int i_read_once ) -{ - unsigned int i_loop; - dvd_netlist_t * p_netlist; - - /* First we allocate and initialise our netlist struct */ - p_netlist = malloc( sizeof(dvd_netlist_t) ); - if ( p_netlist == NULL ) - { - intf_ErrMsg("Unable to malloc the DVD netlist struct"); - free( p_netlist ); - return NULL; - } - - /* Nb of packets read once by input */ - p_netlist->i_read_once = i_read_once; - - /* allocate the buffers */ - p_netlist->p_buffers = malloc( i_nb_iovec *i_buffer_size ); - if ( p_netlist->p_buffers == NULL ) - { - intf_ErrMsg ("Unable to malloc in DVD netlist initialization (1)"); - free( p_netlist->p_buffers ); - free( p_netlist ); - return NULL; - } - - /* table of pointers to data packets */ - p_netlist->p_data = malloc( i_nb_data *sizeof(data_packet_t) ); - if ( p_netlist->p_data == NULL ) - { - intf_ErrMsg ("Unable to malloc in DVD netlist initialization (2)"); - free( p_netlist->p_buffers ); - free( p_netlist->p_data ); - free( p_netlist ); - return NULL; - } - - /* table of pointer to PES packets */ - p_netlist->p_pes = malloc( i_nb_pes *sizeof(pes_packet_t) ); - if ( p_netlist->p_pes == NULL ) - { - intf_ErrMsg ("Unable to malloc in DVD netlist initialization (3)"); - free( p_netlist->p_buffers ); - free( p_netlist->p_data ); - free( p_netlist->p_pes ); - free( p_netlist ); - return NULL; - } - - /* allocate the FIFOs : tables of free pointers */ - p_netlist->pp_free_data = - malloc( i_nb_data *sizeof(data_packet_t *) ); - if ( p_netlist->pp_free_data == NULL ) - { - intf_ErrMsg ("Unable to malloc in DVD netlist initialization (4)"); - free( p_netlist->p_buffers ); - free( p_netlist->p_data ); - free( p_netlist->p_pes ); - free( p_netlist->pp_free_data ); - free( p_netlist ); - return NULL; - } - p_netlist->pp_free_pes = - malloc( i_nb_pes *sizeof(pes_packet_t *) ); - if ( p_netlist->pp_free_pes == NULL ) - { - intf_ErrMsg ("Unable to malloc in DVD netlist initialization (5)"); - free( p_netlist->p_buffers ); - free( p_netlist->p_data ); - free( p_netlist->p_pes ); - free( p_netlist->pp_free_data ); - free( p_netlist->pp_free_pes ); - free( p_netlist ); - return NULL; - } - - p_netlist->p_free_iovec = - malloc( (i_nb_iovec + p_netlist->i_read_once) * sizeof(struct iovec) ); - if ( p_netlist->p_free_iovec == NULL ) - { - intf_ErrMsg ("Unable to malloc in DVD netlist initialization (6)"); - free( p_netlist->p_buffers ); - free( p_netlist->p_data ); - free( p_netlist->p_pes ); - free( p_netlist->pp_free_data ); - free( p_netlist->pp_free_pes ); - free( p_netlist->p_free_iovec ); - free( p_netlist ); - return NULL; - } - - /* table for reference counter of iovecs */ - p_netlist->pi_refcount = malloc( i_nb_iovec *sizeof(int) ); - if ( p_netlist->pi_refcount == NULL ) - { - intf_ErrMsg ("Unable to malloc in DVD netlist initialization (7)"); - free( p_netlist->p_buffers ); - free( p_netlist->p_data ); - free( p_netlist->p_pes ); - free( p_netlist->pp_free_data ); - free( p_netlist->pp_free_pes ); - free( p_netlist->p_free_iovec ); - free( p_netlist->pi_refcount ); - free( p_netlist ); - return NULL; - } - - /* Fill the data FIFO */ - for ( i_loop = 0; i_loop < i_nb_data; i_loop++ ) - { - p_netlist->pp_free_data[i_loop] = - p_netlist->p_data + i_loop; - } - - /* Fill the PES FIFO */ - for ( i_loop = 0; i_loop < i_nb_pes ; i_loop++ ) - { - p_netlist->pp_free_pes[i_loop] = - p_netlist->p_pes + i_loop; - } - - /* Deal with the iovec */ - for ( i_loop = 0; i_loop < i_nb_iovec; i_loop++ ) - { - p_netlist->p_free_iovec[i_loop].iov_base = - p_netlist->p_buffers + i_loop * i_buffer_size; - - p_netlist->p_free_iovec[i_loop].iov_len = i_buffer_size; - } - - /* initialize reference counters */ - memset( p_netlist->pi_refcount, 0, i_nb_iovec *sizeof(int) ); - - /* vlc_mutex_init */ - vlc_mutex_init (&p_netlist->lock); - - /* initialize indexes */ - p_netlist->i_iovec_start = 0; - p_netlist->i_iovec_end = i_nb_iovec - 1; - - p_netlist->i_data_start = 0; - p_netlist->i_data_end = i_nb_data - 1; - - p_netlist->i_pes_start = 0; - p_netlist->i_pes_end = i_nb_pes - 1; - - /* we give (nb - 1) to use & instead of % - * if you really need nb you have to add 1 */ - p_netlist->i_nb_iovec = i_nb_iovec - 1; - p_netlist->i_nb_data = i_nb_data - 1; - p_netlist->i_nb_pes = i_nb_pes - 1; - p_netlist->i_buffer_size = i_buffer_size; - - return p_netlist; /* Everything went all right */ -} - -/***************************************************************************** - * DVDGetiovec: returns an iovec pointer for a readv() operation - ***************************************************************************** - * We return an iovec vector, so that readv can read many packets at a time. - * pp_data will be set to direct to the fifo pointer in DVDMviovec, which - * will allow us to get the corresponding data_packet. - *****************************************************************************/ -struct iovec * DVDGetiovec( void * p_method_data ) -{ - dvd_netlist_t * p_netlist; - - /* cast */ - p_netlist = (dvd_netlist_t *)p_method_data; - - /* check that we have enough free iovec */ - if( ( - (p_netlist->i_iovec_end - p_netlist->i_iovec_start) - & p_netlist->i_nb_iovec ) < p_netlist->i_read_once ) - { - intf_WarnMsg( 12, "input info: waiting for free iovec" ); - msleep( INPUT_IDLE_SLEEP ); - - while( ( - (p_netlist->i_iovec_end - p_netlist->i_iovec_start) - & p_netlist->i_nb_iovec ) < p_netlist->i_read_once ) - { - msleep( INPUT_IDLE_SLEEP ); - } - - intf_WarnMsg( 12, "input info: found free iovec" ); - } - - if( ( - (p_netlist->i_data_end - p_netlist->i_data_start) - & p_netlist->i_nb_data ) < p_netlist->i_read_once ) - { - intf_WarnMsg( 12, "input info: waiting for free data packet" ); - msleep( INPUT_IDLE_SLEEP ); - - while( ( - (p_netlist->i_data_end - p_netlist->i_data_start) - & p_netlist->i_nb_data ) < p_netlist->i_read_once ) - { - msleep( INPUT_IDLE_SLEEP ); - } - - intf_WarnMsg( 12, "input info: found free data packet" ); - } - - /* readv only takes contiguous buffers - * so, as a solution, we chose to have a FIFO a bit longer - * than i_nb_data, and copy the begining of the FIFO to its end - * if the readv needs to go after the end */ - if( p_netlist->i_nb_iovec - p_netlist->i_iovec_start + 1 < - p_netlist->i_read_once ) - { - memcpy( &p_netlist->p_free_iovec[p_netlist->i_nb_iovec + 1], - p_netlist->p_free_iovec, - (p_netlist->i_read_once - - (p_netlist->i_nb_iovec + 1 - p_netlist->i_iovec_start)) - * sizeof(struct iovec) - ); - - } - - return p_netlist->p_free_iovec + p_netlist->i_iovec_start; - -} - -/***************************************************************************** - * DVDMviovec: move the iovec pointer by one after a readv() operation and - * gives a data_packet corresponding to iovec in p_data - *****************************************************************************/ -void DVDMviovec( void * p_method_data, int i_nb_iovec, - struct data_packet_s ** pp_data ) -{ - dvd_netlist_t * p_netlist; - unsigned int i_loop = 0; - - /* cast */ - p_netlist = (dvd_netlist_t *)p_method_data; - - /* lock */ - vlc_mutex_lock( &p_netlist->lock ); - - /* Fills a table of pointers to packets associated with the io_vec's */ - while( i_loop < i_nb_iovec ) - { - pp_data[i_loop] = p_netlist->pp_free_data[p_netlist->i_data_start]; - - pp_data[i_loop]->p_buffer = - p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base; - - pp_data[i_loop]->pi_refcount = p_netlist->pi_refcount + - p_netlist->i_iovec_start; - - p_netlist->i_iovec_start ++; - p_netlist->i_iovec_start &= p_netlist->i_nb_iovec; - - p_netlist->i_data_start ++; - p_netlist->i_data_start &= p_netlist->i_nb_data; - - i_loop ++; - } - - /* unlock */ - vlc_mutex_unlock( &p_netlist->lock ); - -} - -/***************************************************************************** - * DVDNewPtr: returns a free data_packet_t - * Gives a pointer ; its fields need to be initialized - *****************************************************************************/ -struct data_packet_s * DVDNewPtr( void * p_method_data ) -{ - dvd_netlist_t * p_netlist; - struct data_packet_s * p_return; - - /* cast */ - p_netlist = (dvd_netlist_t *)p_method_data; - - /* lock */ - vlc_mutex_lock ( &p_netlist->lock ); - - /* check */ - if ( p_netlist->i_data_start == p_netlist->i_data_end ) - { - intf_ErrMsg("Empty Data FIFO in netlist. Unable to allocate memory"); - return ( NULL ); - } - - p_return = (p_netlist->pp_free_data[p_netlist->i_data_start]); - - p_netlist->i_data_start++; - p_netlist->i_data_start &= p_netlist->i_nb_data; - - /* unlock */ - vlc_mutex_unlock (&p_netlist->lock); - - return ( p_return ); -} - -/***************************************************************************** - * DVDNewPacket: returns a free data_packet_t, and takes a corresponding - * storage iovec - *****************************************************************************/ -struct data_packet_s * DVDNewPacket( void * p_method_data, - size_t i_buffer_size ) -{ - dvd_netlist_t * p_netlist; - struct data_packet_s * p_packet; -//intf_ErrMsg( "netlist: New packet" ); - /* cast */ - p_netlist = (dvd_netlist_t *)p_method_data; - - /* lock */ - vlc_mutex_lock( &p_netlist->lock ); - - /* check */ - if ( p_netlist->i_iovec_start == p_netlist->i_iovec_end ) - { - intf_ErrMsg("Empty io_vec FIFO in netlist. Unable to allocate memory"); - return ( NULL ); - } - - if ( p_netlist->i_data_start == p_netlist->i_data_end ) - { - intf_ErrMsg("Empty Data FIFO in netlist. Unable to allocate memory"); - return ( NULL ); - } - - - /* Gives an io_vec and associated data */ - p_packet = p_netlist->pp_free_data[p_netlist->i_data_start]; - - p_packet->p_buffer = - p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base; - - p_packet->p_payload_start = p_packet->p_buffer; - - p_packet->p_payload_end = - p_packet->p_buffer + i_buffer_size; - - p_packet->p_next = NULL; - p_packet->b_discard_payload = 0; - - p_packet->pi_refcount = p_netlist->pi_refcount + p_netlist->i_iovec_start; - (*p_packet->pi_refcount)++; - - p_netlist->i_iovec_start ++; - p_netlist->i_iovec_start &= p_netlist->i_nb_iovec; - - p_netlist->i_data_start ++; - p_netlist->i_data_start &= p_netlist->i_nb_data; - - /* unlock */ - vlc_mutex_unlock( &p_netlist->lock ); - - return p_packet; -} - -/***************************************************************************** - * DVDNewPES: returns a free pes_packet_t - *****************************************************************************/ -struct pes_packet_s * DVDNewPES( void * p_method_data ) -{ - dvd_netlist_t * p_netlist; - pes_packet_t * p_return; - -//intf_ErrMsg( "netlist: New pes" ); - /* cast */ - p_netlist = (dvd_netlist_t *)p_method_data; - - /* lock */ - vlc_mutex_lock ( &p_netlist->lock ); - - /* check */ - if ( p_netlist->i_pes_start == p_netlist->i_pes_end ) - { - intf_ErrMsg("Empty PES FIFO in netlist - Unable to allocate memory"); - return ( NULL ); - } - - /* allocate */ - p_return = p_netlist->pp_free_pes[p_netlist->i_pes_start]; - p_netlist->i_pes_start++; - p_netlist->i_pes_start &= p_netlist->i_nb_pes; - - /* unlock */ - vlc_mutex_unlock (&p_netlist->lock); - - /* initialize PES */ - p_return->b_data_alignment = 0; - p_return->b_discontinuity = 0; - p_return->i_pts = 0; - p_return->i_dts = 0; - p_return->i_pes_size = 0; - p_return->p_first = NULL; - - return ( p_return ); -} - -/***************************************************************************** - * DVDDeletePacket: puts a data_packet_t back into the netlist - *****************************************************************************/ -void DVDDeletePacket( void * p_method_data, data_packet_t * p_data ) -{ - dvd_netlist_t * p_netlist; - - /* cast */ - p_netlist = (dvd_netlist_t *) p_method_data; - - /* lock */ - vlc_mutex_lock ( &p_netlist->lock ); - - - /* Delete data_packet */ - p_netlist->i_data_end ++; - p_netlist->i_data_end &= p_netlist->i_nb_data; - - p_netlist->pp_free_data[p_netlist->i_data_end] = p_data; - - p_data->p_next = NULL; - p_data->b_discard_payload = 0; - - /* Update reference counter */ - (*p_data->pi_refcount)--; - - if( (*p_data->pi_refcount) == 0 ) - { - - p_netlist->i_iovec_end++; - p_netlist->i_iovec_end &= p_netlist->i_nb_iovec; - p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base = - p_data->p_buffer; - } - - /* unlock */ - vlc_mutex_unlock (&p_netlist->lock); -} - -/***************************************************************************** - * DVDDeletePES: puts a pes_packet_t back into the netlist - *****************************************************************************/ -void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes ) -{ - dvd_netlist_t * p_netlist; - data_packet_t * p_current_packet; - data_packet_t * p_next_packet; - - /* cast */ - p_netlist = (dvd_netlist_t *)p_method_data; - - /* lock */ - vlc_mutex_lock ( &p_netlist->lock ); - - /* delete free p_pes->p_first, p_next ... */ - p_current_packet = p_pes->p_first; - while ( p_current_packet != NULL ) - { - /* copy of NetListDeletePacket, duplicate code avoid many locks */ - - p_netlist->i_data_end ++; - p_netlist->i_data_end &= p_netlist->i_nb_data; - - /* re initialize */ - p_current_packet->p_payload_start = p_current_packet->p_buffer; - - p_netlist->pp_free_data[p_netlist->i_data_end] = p_current_packet; - - /* Update reference counter */ - (*p_current_packet->pi_refcount)--; - - if( (*p_current_packet->pi_refcount) <= 0 ) - { - p_netlist->i_iovec_end++; - p_netlist->i_iovec_end &= p_netlist->i_nb_iovec; - p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base = - p_current_packet->p_buffer; - } - - p_next_packet = p_current_packet->p_next; - p_current_packet->p_next = NULL; - p_current_packet->b_discard_payload = 0; - p_current_packet = p_next_packet; - } - - /* delete our current PES packet */ - p_netlist->i_pes_end ++; - p_netlist->i_pes_end &= p_netlist->i_nb_pes; - p_netlist->pp_free_pes[p_netlist->i_pes_end] = p_pes; - - /* unlock */ - vlc_mutex_unlock (&p_netlist->lock); - -} - -/***************************************************************************** - * DVDNetlistEnd: frees all allocated structures - *****************************************************************************/ -void DVDNetlistEnd( dvd_netlist_t * p_netlist ) -{ - /* destroy the mutex lock */ - vlc_mutex_destroy( &p_netlist->lock ); - - /* free the FIFO, the buffer, and the netlist structure */ - free( p_netlist->pi_refcount ); - free( p_netlist->p_free_iovec ); - free( p_netlist->pp_free_pes ); - free( p_netlist->pp_free_data ); - free( p_netlist->p_pes ); - free( p_netlist->p_data ); - free( p_netlist->p_buffers ); - - /* free the netlist */ - free( p_netlist ); -} diff --git a/plugins/dvd/dvd_netlist.h b/plugins/dvd/dvd_netlist.h deleted file mode 100644 index 9d7579c833..0000000000 --- a/plugins/dvd/dvd_netlist.h +++ /dev/null @@ -1,73 +0,0 @@ -/***************************************************************************** - * dvd_netlist.h: Specific netlist structures for DVD packets - ***************************************************************************** - * Copyright (C) 1998, 1999, 2000, 2001 VideoLAN - * $Id: dvd_netlist.h,v 1.2 2001/03/03 07:07:01 stef Exp $ - * - * Authors: Henri Fallon - * Stéphane Borel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -/***************************************************************************** - * netlist_t: structure to manage a netlist - *****************************************************************************/ -typedef struct dvd_netlist_s -{ - vlc_mutex_t lock; - - size_t i_buffer_size; - - /* Buffers */ - byte_t * p_buffers; /* Big malloc'ed area */ - data_packet_t * p_data; /* malloc'ed area */ - pes_packet_t * p_pes; /* malloc'ed area */ - - /* FIFOs of free packets */ - data_packet_t ** pp_free_data; - pes_packet_t ** pp_free_pes; - struct iovec * p_free_iovec; - - /* FIFO size */ - unsigned int i_nb_iovec; - unsigned int i_nb_pes; - unsigned int i_nb_data; - - /* Index */ - unsigned int i_iovec_start, i_iovec_end; - unsigned int i_data_start, i_data_end; - unsigned int i_pes_start, i_pes_end; - - /* Reference counters for iovec */ - unsigned int * pi_refcount; - - /* Nb of packets read once */ - unsigned int i_read_once; - -} dvd_netlist_t; - -/***************************************************************************** - * Prototypes - *****************************************************************************/ -struct dvd_netlist_s * DVDNetlistInit( int , int, int, size_t, int ); -struct iovec * DVDGetiovec( void * p_method_data ); -void DVDMviovec( void * , int, struct data_packet_s **); -struct data_packet_s * DVDNewPtr( void * ); -struct data_packet_s * DVDNewPacket( void *, size_t ); -struct pes_packet_s * DVDNewPES( void * ); -void DVDDeletePacket( void *, struct data_packet_s * ); -void DVDDeletePES( void *, struct pes_packet_s * ); -void DVDNetlistEnd( struct dvd_netlist_s * ); diff --git a/plugins/dvd/input_dvd.c b/plugins/dvd/input_dvd.c index 3874caff00..1586ecc6fa 100644 --- a/plugins/dvd/input_dvd.c +++ b/plugins/dvd/input_dvd.c @@ -10,7 +10,7 @@ * -dvd_udf to find files ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: input_dvd.c,v 1.92 2001/11/07 17:37:16 stef Exp $ + * $Id: input_dvd.c,v 1.93 2001/11/11 01:32:03 stef Exp $ * * Author: Stéphane Borel * @@ -86,7 +86,6 @@ #include "input_ext-plugins.h" #include "input_dvd.h" -#include "dvd_netlist.h" #include "dvd_ifo.h" #include "dvd_summary.h" @@ -138,10 +137,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list ) input.pf_read = DVDRead; input.pf_set_area = DVDSetArea; input.pf_demux = input_DemuxPS; - input.pf_new_packet = DVDNewPacket; - input.pf_new_pes = DVDNewPES; - input.pf_delete_packet = DVDDeletePacket; - input.pf_delete_pes = DVDDeletePES; + input.pf_new_packet = input_NetlistNewPacket; + input.pf_new_pes = input_NetlistNewPES; + input.pf_delete_packet = input_NetlistDeletePacket; + input.pf_delete_pes = input_NetlistDeletePES; input.pf_rewind = DVDRewind; input.pf_seek = DVDSeek; #undef input @@ -214,9 +213,8 @@ static void DVDInit( input_thread_t * p_input ) p_input->i_read_once = DVD_DATA_READ_ONCE; /* Reading structures initialisation */ - p_input->p_method_data = - DVDNetlistInit( DVD_NETLIST_SIZE, 2 * DVD_NETLIST_SIZE, - DVD_NETLIST_SIZE, DVD_LB_SIZE, p_dvd->i_block_once ); + input_NetlistInit( p_input, DVD_NETLIST_SIZE, 2 * DVD_NETLIST_SIZE, + DVD_NETLIST_SIZE, DVD_LB_SIZE, p_dvd->i_block_once ); intf_WarnMsg( 2, "dvd info: netlist initialized" ); /* Ifo allocation & initialisation */ @@ -370,16 +368,14 @@ static void DVDClose( struct input_thread_s *p_input ) static void DVDEnd( input_thread_t * p_input ) { thread_dvd_data_t * p_dvd; - dvd_netlist_t * p_netlist; p_dvd = (thread_dvd_data_t*)p_input->p_plugin_data; - p_netlist = (dvd_netlist_t *)p_input->p_method_data; IfoDestroy( p_dvd->p_ifo ); free( p_dvd ); - DVDNetlistEnd( p_netlist ); + input_NetlistEnd( p_input ); } /***************************************************************************** @@ -809,7 +805,7 @@ static int DVDRead( input_thread_t * p_input, data_packet_t ** pp_packets ) { thread_dvd_data_t * p_dvd; - dvd_netlist_t * p_netlist; + netlist_t * p_netlist; struct iovec * p_vec; struct data_packet_s * pp_data[DVD_DATA_READ_ONCE]; u8 * pi_cur; @@ -825,7 +821,7 @@ static int DVDRead( input_thread_t * p_input, boolean_t b_eoc; p_dvd = (thread_dvd_data_t *)p_input->p_plugin_data; - p_netlist = (dvd_netlist_t *)p_input->p_method_data; + p_netlist = (netlist_t *)p_input->p_method_data; b_eoc = 0; i_sector = p_dvd->i_title_start + p_dvd->i_sector; @@ -892,7 +888,7 @@ intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_o p_netlist->i_read_once = i_block_once; /* Get an iovec pointer */ - if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL ) + if( ( p_vec = input_NetlistGetiovec( p_netlist ) ) == NULL ) { intf_ErrMsg( "dvd error: can't get iovec" ); return -1; @@ -904,7 +900,7 @@ intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_o /* Update netlist indexes: we don't do it in DVDGetiovec since we * need know the real number of blocks read */ - DVDMviovec( p_netlist, i_read_blocks, pp_data ); + input_NetlistMviovec( p_netlist, i_read_blocks, pp_data ); /* Update global position */ p_dvd->i_sector += i_read_blocks; @@ -925,31 +921,25 @@ intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_o { /* That's the case for all packets, except pack header. */ i_packet_size = U16_AT( pi_cur + 4 ); - pp_packets[i_packet] = DVDNewPtr( p_netlist ); + pp_packets[i_packet] = input_NetlistNewPtr( p_netlist ); + (*pp_data[i_iovec]->pi_refcount)++; + pp_packets[i_packet]->pi_refcount = + pp_data[i_iovec]->pi_refcount; + pp_packets[i_packet]->p_buffer = pp_data[i_iovec]->p_buffer; } else { /* MPEG-2 Pack header. */ i_packet_size = 8; pp_packets[i_packet] = pp_data[i_iovec]; - } - (*pp_data[i_iovec]->pi_refcount)++; - - pp_packets[i_packet]->pi_refcount = pp_data[i_iovec]->pi_refcount; - - pp_packets[i_packet]->p_buffer = pp_data[i_iovec]->p_buffer; - pp_packets[i_packet]->p_payload_start = pp_packets[i_packet]->p_buffer + i_pos; pp_packets[i_packet]->p_payload_end = pp_packets[i_packet]->p_payload_start + i_packet_size + 6; - pp_packets[i_packet]->p_next = NULL; - pp_packets[i_packet]->b_discard_payload = 0; - i_packet++; i_pos += i_packet_size + 6; } diff --git a/plugins/mpeg/input_es.c b/plugins/mpeg/input_es.c index e543f60230..ae58af4b7e 100644 --- a/plugins/mpeg/input_es.c +++ b/plugins/mpeg/input_es.c @@ -2,7 +2,7 @@ * input_es.c: Elementary Stream demux and packet management ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: input_es.c,v 1.11 2001/10/02 17:04:42 massiot Exp $ + * $Id: input_es.c,v 1.12 2001/11/11 01:32:03 stef Exp $ * * Author: Christophe Massiot * @@ -145,7 +145,7 @@ static void ESInit( input_thread_t * p_input ) p_input->p_method_data = NULL; /* Initialize netlist */ - if( input_NetlistInit( p_input, NB_DATA, NB_PES, ES_PACKET_SIZE, + if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, ES_PACKET_SIZE, INPUT_READ_ONCE ) ) { intf_ErrMsg( "ES input : Could not initialize netlist" ); diff --git a/plugins/mpeg/input_ts.c b/plugins/mpeg/input_ts.c index 361a89ea8e..9516d2e7da 100644 --- a/plugins/mpeg/input_ts.c +++ b/plugins/mpeg/input_ts.c @@ -2,7 +2,7 @@ * input_ts.c: TS demux and netlist management ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: input_ts.c,v 1.35 2001/10/22 02:33:54 xav Exp $ + * $Id: input_ts.c,v 1.36 2001/11/11 01:32:03 stef Exp $ * * Authors: Henri Fallon * @@ -185,7 +185,7 @@ static void TSInit( input_thread_t * p_input ) /* Initialize netlist */ - if( input_NetlistInit( p_input, NB_DATA, NB_PES, TS_PACKET_SIZE, + if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, TS_PACKET_SIZE, INPUT_READ_ONCE ) ) { intf_ErrMsg( "TS input : Could not initialize netlist" ); diff --git a/src/input/input_netlist.c b/src/input/input_netlist.c index afcd7feb38..b4765e70f0 100644 --- a/src/input/input_netlist.c +++ b/src/input/input_netlist.c @@ -1,10 +1,15 @@ /***************************************************************************** - * input_netlist.c: netlist management + * dvd_netlist.c: netlist management v2 ***************************************************************************** - * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: input_netlist.c,v 1.42 2001/09/06 18:21:02 henri Exp $ + * There is only one major change from input_netlist.c (1) : data is now a + * pointer to an offset in iovec ; and iovec has a reference counter. It + * will only be given back to netlist when refcount is zero. + ***************************************************************************** + * Copyright (C) 1998, 1999, 2000, 2001 VideoLAN + * $Id: input_netlist.c,v 1.43 2001/11/11 01:32:03 stef Exp $ * * Authors: Henri Fallon + * Stéphane Borel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,14 +60,24 @@ #include "input_ext-dec.h" #include "input_ext-plugins.h" +/***************************************************************************** + * Local prototypes + *****************************************************************************/ + /***************************************************************************** * input_NetlistInit: allocates netlist buffers and init indexes + * --- + * Changes from input_NetList: we have to give the length of the buffer which + * is different from i_nb_data now, since we may have several data pointers + * in one iovec. Thus we can only delete an iovec when its refcount is 0. + * We only received a buffer with a GetIovec whereas NewPacket gives a pointer. *****************************************************************************/ -int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, +int input_NetlistInit( input_thread_t * p_input, + int i_nb_iovec, int i_nb_data, int i_nb_pes, size_t i_buffer_size, int i_read_once ) { - unsigned int i_loop; - netlist_t * p_netlist; + unsigned int i_loop; + netlist_t * p_netlist; /* First we allocate and initialise our netlist struct */ p_input->p_method_data = malloc(sizeof(netlist_t)); @@ -71,15 +86,16 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, intf_ErrMsg("Unable to malloc the netlist struct"); return (-1); } - + p_netlist = (netlist_t *) p_input->p_method_data; - + + /* Nb of packets read once by input */ p_netlist->i_read_once = i_read_once; /* In order to optimize netlist, we are taking i_nb_data a 2^i * so that modulo is an "&". * This is not changing i_nb data outside this function except in - * the netlist_t struct */ + * the netlist_t struct */ /* As i_loop is unsigned int, and i_ns_data int, this shouldn't be a * problem */ for( i_loop = 1; i_loop < i_nb_data; i_loop *= 2 ) @@ -91,75 +107,127 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, i_nb_data = i_loop; /* Same thing for i_nb_pes */ - for( i_loop = 1; i_loop < i_nb_data; i_loop *= 2 ) + for( i_loop = 1; i_loop < i_nb_pes; i_loop *= 2 ) { ; } - intf_DbgMsg( "Netlist : Required %i byte, got %u",i_nb_data,i_loop ); - i_nb_data = i_loop; - + intf_DbgMsg( "Netlist : Required %i byte, got %u",i_nb_pes,i_loop ); + i_nb_pes = i_loop; + + /* Same thing for i_nb_iovec */ + for( i_loop = 1; i_loop < i_nb_iovec; i_loop *= 2 ) + { + ; + } + + intf_DbgMsg( "Netlist : Required %i byte, got %u",i_nb_iovec,i_loop ); + i_nb_iovec = i_loop; + /* allocate the buffers */ - p_netlist->p_buffers = - (byte_t *) malloc(i_buffer_size* i_nb_data ); + p_netlist->p_buffers = malloc( i_nb_iovec *i_buffer_size ); if ( p_netlist->p_buffers == NULL ) { intf_ErrMsg ("Unable to malloc in netlist initialization (1)"); - return (-1); + free( p_netlist ); + return -1; } - p_netlist->p_data = - (data_packet_t *) malloc(sizeof(data_packet_t)*(i_nb_data)); + /* table of pointers to data packets */ + p_netlist->p_data = malloc( i_nb_data *sizeof(data_packet_t) ); if ( p_netlist->p_data == NULL ) { intf_ErrMsg ("Unable to malloc in netlist initialization (2)"); - return (-1); + free( p_netlist->p_buffers ); + free( p_netlist ); + return -1; } - p_netlist->p_pes = - (pes_packet_t *) malloc(sizeof(pes_packet_t)*(i_nb_pes)); + /* table of pointer to PES packets */ + p_netlist->p_pes = malloc( i_nb_pes *sizeof(pes_packet_t) ); if ( p_netlist->p_pes == NULL ) { intf_ErrMsg ("Unable to malloc in netlist initialization (3)"); - return (-1); + free( p_netlist->p_buffers ); + free( p_netlist->p_data ); + free( p_netlist ); + return -1; } - /* allocate the FIFOs */ + /* allocate the FIFOs : tables of free pointers */ p_netlist->pp_free_data = - (data_packet_t **) malloc (i_nb_data * sizeof(data_packet_t *) ); + malloc( i_nb_data *sizeof(data_packet_t *) ); if ( p_netlist->pp_free_data == NULL ) { intf_ErrMsg ("Unable to malloc in netlist initialization (4)"); + free( p_netlist->p_buffers ); + free( p_netlist->p_data ); + free( p_netlist->p_pes ); + free( p_netlist ); + return -1; } p_netlist->pp_free_pes = - (pes_packet_t **) malloc (i_nb_pes * sizeof(pes_packet_t *) ); + malloc( i_nb_pes *sizeof(pes_packet_t *) ); if ( p_netlist->pp_free_pes == NULL ) { intf_ErrMsg ("Unable to malloc in netlist initialization (5)"); + free( p_netlist->p_buffers ); + free( p_netlist->p_data ); + free( p_netlist->p_pes ); + free( p_netlist->pp_free_data ); + free( p_netlist ); + return -1; } - p_netlist->p_free_iovec = ( struct iovec * ) - malloc( (i_nb_data + p_netlist->i_read_once) * sizeof(struct iovec) ); + p_netlist->p_free_iovec = + malloc( (i_nb_iovec + p_netlist->i_read_once) * sizeof(struct iovec) ); if ( p_netlist->p_free_iovec == NULL ) { - intf_ErrMsg ("Unable to malloc in netlist initialization (6)"); + intf_ErrMsg ("Unable to malloc in DVD netlist initialization (6)"); + free( p_netlist->p_buffers ); + free( p_netlist->p_data ); + free( p_netlist->p_pes ); + free( p_netlist->pp_free_data ); + free( p_netlist->pp_free_pes ); + free( p_netlist ); + return -1; } - + + /* table for reference counter of iovecs */ + p_netlist->pi_refcount = malloc( i_nb_iovec *sizeof(int) ); + if ( p_netlist->pi_refcount == NULL ) + { + intf_ErrMsg ("Unable to malloc in DVD netlist initialization (7)"); + free( p_netlist->p_buffers ); + free( p_netlist->p_data ); + free( p_netlist->p_pes ); + free( p_netlist->pp_free_data ); + free( p_netlist->pp_free_pes ); + free( p_netlist->p_free_iovec ); + free( p_netlist ); + return -1; + } + /* Fill the data FIFO */ for ( i_loop = 0; i_loop < i_nb_data; i_loop++ ) { p_netlist->pp_free_data[i_loop] = p_netlist->p_data + i_loop; - p_netlist->pp_free_data[i_loop]->p_buffer = - p_netlist->p_buffers + i_loop * i_buffer_size; - - p_netlist->pp_free_data[i_loop]->p_payload_start = - p_netlist->pp_free_data[i_loop]->p_buffer; - - p_netlist->pp_free_data[i_loop]->p_payload_end = - p_netlist->pp_free_data[i_loop]->p_buffer + i_buffer_size; + /* by default, one data packet for one buffer */ + if( i_nb_data == i_nb_iovec ) + { + p_netlist->pp_free_data[i_loop]->p_buffer = + p_netlist->p_buffers + i_loop * i_buffer_size; + + p_netlist->pp_free_data[i_loop]->p_payload_start = + p_netlist->pp_free_data[i_loop]->p_buffer; + + p_netlist->pp_free_data[i_loop]->p_payload_end = + p_netlist->pp_free_data[i_loop]->p_buffer + i_buffer_size; + } } + /* Fill the PES FIFO */ for ( i_loop = 0; i_loop < i_nb_pes ; i_loop++ ) { @@ -168,125 +236,196 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, } /* Deal with the iovec */ - for ( i_loop = 0; i_loop < i_nb_data; i_loop++ ) + for ( i_loop = 0; i_loop < i_nb_iovec; i_loop++ ) { p_netlist->p_free_iovec[i_loop].iov_base = p_netlist->p_buffers + i_loop * i_buffer_size; p_netlist->p_free_iovec[i_loop].iov_len = i_buffer_size; } + + /* initialize reference counters */ + memset( p_netlist->pi_refcount, 0, i_nb_iovec *sizeof(int) ); /* vlc_mutex_init */ vlc_mutex_init (&p_netlist->lock); /* initialize indexes */ + p_netlist->i_iovec_start = 0; + p_netlist->i_iovec_end = i_nb_iovec - 1; + p_netlist->i_data_start = 0; p_netlist->i_data_end = i_nb_data - 1; p_netlist->i_pes_start = 0; p_netlist->i_pes_end = i_nb_pes - 1; - p_netlist->i_nb_data = i_nb_data; - p_netlist->i_nb_pes = i_nb_pes; + /* we give (nb - 1) to use & instead of % + * if you really need nb you have to add 1 */ + p_netlist->i_nb_iovec = i_nb_iovec - 1; + p_netlist->i_nb_data = i_nb_data - 1; + p_netlist->i_nb_pes = i_nb_pes - 1; p_netlist->i_buffer_size = i_buffer_size; - return (0); /* Everything went all right */ + return 0; /* Everything went all right */ } /***************************************************************************** * input_NetlistGetiovec: returns an iovec pointer for a readv() operation ***************************************************************************** - * We return an iovec vector, so that readv can read many packets at a time, - * and we set pp_data to direct to the fifo pointer, which will allow us - * to get the corresponding data_packet. + * We return an iovec vector, so that readv can read many packets at a time. + * pp_data will be set to direct to the fifo pointer in DVDMviovec, which + * will allow us to get the corresponding data_packet. *****************************************************************************/ struct iovec * input_NetlistGetiovec( void * p_method_data ) { - netlist_t * p_netlist; + netlist_t * p_netlist; /* cast */ - p_netlist = ( netlist_t * ) p_method_data; + p_netlist = (netlist_t *)p_method_data; - /* check */ - if( - ( (p_netlist->i_data_end - p_netlist->i_data_start + p_netlist->i_nb_data) - & ( p_netlist->i_nb_data -1 ) ) < p_netlist->i_read_once ) + /* check that we have enough free iovec */ + if( ( + (p_netlist->i_iovec_end - p_netlist->i_iovec_start) + & p_netlist->i_nb_iovec ) < p_netlist->i_read_once ) { - intf_ErrMsg("Empty iovec FIFO."); - return (NULL); + intf_WarnMsg( 12, "input info: waiting for free iovec" ); + msleep( INPUT_IDLE_SLEEP ); + + while( ( + (p_netlist->i_iovec_end - p_netlist->i_iovec_start) + & p_netlist->i_nb_iovec ) < p_netlist->i_read_once ) + { + msleep( INPUT_IDLE_SLEEP ); + } + + intf_WarnMsg( 12, "input info: found free iovec" ); + } + + if( ( + (p_netlist->i_data_end - p_netlist->i_data_start) + & p_netlist->i_nb_data ) < p_netlist->i_read_once ) + { + intf_WarnMsg( 12, "input info: waiting for free data packet" ); + msleep( INPUT_IDLE_SLEEP ); + + while( ( + (p_netlist->i_data_end - p_netlist->i_data_start) + & p_netlist->i_nb_data ) < p_netlist->i_read_once ) + { + msleep( INPUT_IDLE_SLEEP ); + } + + intf_WarnMsg( 12, "input info: found free data packet" ); } /* readv only takes contiguous buffers * so, as a solution, we chose to have a FIFO a bit longer * than i_nb_data, and copy the begining of the FIFO to its end * if the readv needs to go after the end */ - if( p_netlist->i_nb_data - p_netlist->i_data_start < + if( p_netlist->i_nb_iovec - p_netlist->i_iovec_start + 1 < p_netlist->i_read_once ) { - memcpy( &p_netlist->p_free_iovec[p_netlist->i_nb_data], + memcpy( &p_netlist->p_free_iovec[p_netlist->i_nb_iovec + 1], p_netlist->p_free_iovec, - (p_netlist->i_read_once- - (p_netlist->i_nb_data-p_netlist->i_data_start)) + (p_netlist->i_read_once - + (p_netlist->i_nb_iovec + 1 - p_netlist->i_iovec_start)) * sizeof(struct iovec) ); } - - return &p_netlist->p_free_iovec[p_netlist->i_data_start]; + + return p_netlist->p_free_iovec + p_netlist->i_iovec_start; } /***************************************************************************** - * input_NetlistMviovec: move the iovec pointer after a readv() operation + * input_NetlistMviovec: move the iovec pointer by one after a readv() + * operation and gives a data_packet corresponding to iovec in p_data *****************************************************************************/ -void input_NetlistMviovec( void * p_method_data, size_t i_nb_iovec, - struct data_packet_s * pp_packets[INPUT_READ_ONCE] ) +void input_NetlistMviovec( void * p_method_data, int i_nb_iovec, + struct data_packet_s ** pp_data ) { - netlist_t * p_netlist; - unsigned int i_loop = 0; - unsigned int i_current; + netlist_t * p_netlist; + unsigned int i_loop = 0; /* cast */ - p_netlist = (netlist_t *) p_method_data; + p_netlist = (netlist_t *)p_method_data; /* lock */ - vlc_mutex_lock ( &p_netlist->lock ); - - i_current = p_netlist->i_data_start; - + vlc_mutex_lock( &p_netlist->lock ); /* Fills a table of pointers to packets associated with the io_vec's */ - while (i_loop < i_nb_iovec ) + while( i_loop < i_nb_iovec ) { - if( i_current >= p_netlist->i_nb_data ) - i_current-=p_netlist->i_nb_data; + pp_data[i_loop] = p_netlist->pp_free_data[p_netlist->i_data_start]; + + pp_data[i_loop]->p_buffer = + p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base; - pp_packets[i_loop] = p_netlist->pp_free_data[i_current]; - pp_packets[i_loop]->b_discard_payload = 0; + pp_data[i_loop]->pi_refcount = p_netlist->pi_refcount + + p_netlist->i_iovec_start; + (*pp_data[i_loop]->pi_refcount)++; + + p_netlist->i_iovec_start ++; + p_netlist->i_iovec_start &= p_netlist->i_nb_iovec; + + p_netlist->i_data_start ++; + p_netlist->i_data_start &= p_netlist->i_nb_data; i_loop ++; - i_current ++; } - p_netlist->i_data_start += i_nb_iovec; - p_netlist->i_data_start &= ( p_netlist->i_nb_data - 1 ); + /* unlock */ + vlc_mutex_unlock( &p_netlist->lock ); + +} + +/***************************************************************************** + * input_NetlistNewPtr: returns a free data_packet_t + * Gives a pointer ; its fields need to be initialized + *****************************************************************************/ +struct data_packet_s * input_NetlistNewPtr( void * p_method_data ) +{ + netlist_t * p_netlist; + struct data_packet_s * p_return; + + /* cast */ + p_netlist = (netlist_t *)p_method_data; + + /* lock */ + vlc_mutex_lock ( &p_netlist->lock ); + + /* check */ + if ( p_netlist->i_data_start == p_netlist->i_data_end ) + { + intf_ErrMsg("Empty Data FIFO in netlist. Unable to allocate memory"); + return ( NULL ); + } + + p_return = (p_netlist->pp_free_data[p_netlist->i_data_start]); + + p_netlist->i_data_start++; + p_netlist->i_data_start &= p_netlist->i_nb_data; /* unlock */ vlc_mutex_unlock (&p_netlist->lock); - + + return ( p_return ); } /***************************************************************************** - * input_NetlistNewPacket: returns a free data_packet_t + * input_NetlistNewPacket: returns a free data_packet_t, and takes + * a corresponding storage iovec. *****************************************************************************/ struct data_packet_s * input_NetlistNewPacket( void * p_method_data, size_t i_buffer_size ) -{ - netlist_t * p_netlist; - struct data_packet_s * p_return; - +{ + netlist_t * p_netlist; + struct data_packet_s * p_packet; + /* cast */ - p_netlist = ( netlist_t * ) p_method_data; + p_netlist = (netlist_t *)p_method_data; #ifdef DEBUG if( i_buffer_size > p_netlist->i_buffer_size ) @@ -296,33 +435,51 @@ struct data_packet_s * input_NetlistNewPacket( void * p_method_data, return NULL; } #endif - + /* lock */ - vlc_mutex_lock ( &p_netlist->lock ); - - /* check */ + vlc_mutex_lock( &p_netlist->lock ); + + /* check */ + if ( p_netlist->i_iovec_start == p_netlist->i_iovec_end ) + { + intf_ErrMsg("Empty io_vec FIFO in netlist. Unable to allocate memory"); + return ( NULL ); + } + if ( p_netlist->i_data_start == p_netlist->i_data_end ) { - intf_ErrMsg("Empty Data FIFO in netlist."); + intf_ErrMsg("Empty Data FIFO in netlist. Unable to allocate memory"); return ( NULL ); } - - p_return = p_netlist->pp_free_data[p_netlist->i_data_start]; - p_netlist->i_data_start++; - p_netlist->i_data_start &= ( p_netlist->i_nb_data - 1 ); + + + /* Gives an io_vec and associated data */ + p_packet = p_netlist->pp_free_data[p_netlist->i_data_start]; + + p_packet->p_buffer = + p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base; + + p_packet->p_payload_start = p_packet->p_buffer; + + p_packet->p_payload_end = + p_packet->p_buffer + i_buffer_size; + + p_packet->p_next = NULL; + p_packet->b_discard_payload = 0; + + p_packet->pi_refcount = p_netlist->pi_refcount + p_netlist->i_iovec_start; + (*p_packet->pi_refcount)++; + + p_netlist->i_iovec_start ++; + p_netlist->i_iovec_start &= p_netlist->i_nb_iovec; + + p_netlist->i_data_start ++; + p_netlist->i_data_start &= p_netlist->i_nb_data; /* unlock */ - vlc_mutex_unlock (&p_netlist->lock); + vlc_mutex_unlock( &p_netlist->lock ); - - /* initialize data */ - p_return->p_next = NULL; - p_return->b_discard_payload = 0; - - p_return->p_payload_start = p_return->p_buffer; - p_return->p_payload_end = p_return->p_payload_start + i_buffer_size; - - return ( p_return ); + return p_packet; } /***************************************************************************** @@ -330,11 +487,11 @@ struct data_packet_s * input_NetlistNewPacket( void * p_method_data, *****************************************************************************/ struct pes_packet_s * input_NetlistNewPES( void * p_method_data ) { - netlist_t * p_netlist; - pes_packet_t * p_return; + netlist_t * p_netlist; + pes_packet_t * p_return; /* cast */ - p_netlist = (netlist_t *) p_method_data; + p_netlist = (netlist_t *)p_method_data; /* lock */ vlc_mutex_lock ( &p_netlist->lock ); @@ -342,25 +499,26 @@ struct pes_packet_s * input_NetlistNewPES( void * p_method_data ) /* check */ if ( p_netlist->i_pes_start == p_netlist->i_pes_end ) { - intf_ErrMsg("Empty PES FIFO in netlist"); + intf_ErrMsg("Empty PES FIFO in netlist - Unable to allocate memory"); return ( NULL ); } /* allocate */ p_return = p_netlist->pp_free_pes[p_netlist->i_pes_start]; p_netlist->i_pes_start++; - p_netlist->i_pes_start &= ( p_netlist->i_nb_pes - 1 ); + p_netlist->i_pes_start &= p_netlist->i_nb_pes; /* unlock */ vlc_mutex_unlock (&p_netlist->lock); /* initialize PES */ - p_return->b_data_alignment = - p_return->b_discontinuity = - p_return->i_pts = p_return->i_dts = 0; + p_return->b_data_alignment = 0; + p_return->b_discontinuity = 0; + p_return->i_pts = 0; + p_return->i_dts = 0; p_return->i_pes_size = 0; p_return->p_first = NULL; - + return ( p_return ); } @@ -377,20 +535,32 @@ void input_NetlistDeletePacket( void * p_method_data, data_packet_t * p_data ) /* lock */ vlc_mutex_lock ( &p_netlist->lock ); - /* Delete data_packet */ p_netlist->i_data_end ++; - p_netlist->i_data_end &= ( p_netlist->i_nb_data - 1 ); + p_netlist->i_data_end &= p_netlist->i_nb_data; + p_data->p_payload_start = p_data->p_buffer; + p_data->p_payload_end = p_data->p_buffer + p_netlist->i_buffer_size; + p_netlist->pp_free_data[p_netlist->i_data_end] = p_data; - p_netlist->p_free_iovec[p_netlist->i_data_end].iov_base = p_data->p_buffer; - /* re initialize for next time */ - p_data->p_payload_start = p_data->p_buffer; p_data->p_next = NULL; + p_data->b_discard_payload = 0; + + /* Update reference counter */ + (*p_data->pi_refcount)--; + + if( (*p_data->pi_refcount) <= 0 ) + { + + p_netlist->i_iovec_end++; + p_netlist->i_iovec_end &= p_netlist->i_nb_iovec; + p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base = + p_data->p_buffer; + } /* unlock */ - vlc_mutex_unlock( &p_netlist->lock ); + vlc_mutex_unlock (&p_netlist->lock); } /***************************************************************************** @@ -398,8 +568,9 @@ void input_NetlistDeletePacket( void * p_method_data, data_packet_t * p_data ) *****************************************************************************/ void input_NetlistDeletePES( void * p_method_data, pes_packet_t * p_pes ) { - netlist_t * p_netlist; - data_packet_t * p_current_packet,* p_next_packet; + netlist_t * p_netlist; + data_packet_t * p_current_packet; + data_packet_t * p_next_packet; /* cast */ p_netlist = (netlist_t *)p_method_data; @@ -414,47 +585,61 @@ void input_NetlistDeletePES( void * p_method_data, pes_packet_t * p_pes ) /* copy of NetListDeletePacket, duplicate code avoid many locks */ p_netlist->i_data_end ++; - p_netlist->i_data_end &= ( p_netlist->i_nb_data - 1 ); + p_netlist->i_data_end &= p_netlist->i_nb_data; - /* re initialize*/ + /* re initialize */ p_current_packet->p_payload_start = p_current_packet->p_buffer; + p_current_packet->p_payload_end = p_current_packet->p_buffer + + p_netlist->i_buffer_size; p_netlist->pp_free_data[p_netlist->i_data_end] = p_current_packet; - p_netlist->p_free_iovec[p_netlist->i_data_end].iov_base - = p_current_packet->p_buffer; + /* Update reference counter */ + (*p_current_packet->pi_refcount)--; + + if( (*p_current_packet->pi_refcount) <= 0 ) + { + (*p_current_packet->pi_refcount) = 0; + p_netlist->i_iovec_end++; + p_netlist->i_iovec_end &= p_netlist->i_nb_iovec; + p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base = + p_current_packet->p_buffer; + } p_next_packet = p_current_packet->p_next; p_current_packet->p_next = NULL; + p_current_packet->b_discard_payload = 0; p_current_packet = p_next_packet; } /* delete our current PES packet */ p_netlist->i_pes_end ++; - p_netlist->i_pes_end &= ( p_netlist->i_nb_pes - 1 ); + p_netlist->i_pes_end &= p_netlist->i_nb_pes; p_netlist->pp_free_pes[p_netlist->i_pes_end] = p_pes; /* unlock */ - vlc_mutex_unlock( &p_netlist->lock ); + vlc_mutex_unlock (&p_netlist->lock); } /***************************************************************************** * input_NetlistEnd: frees all allocated structures *****************************************************************************/ -void input_NetlistEnd( input_thread_t * p_input) +void input_NetlistEnd( input_thread_t * p_input ) { netlist_t * p_netlist; /* cast */ p_netlist = ( netlist_t * ) p_input->p_method_data; - + /* destroy the mutex lock */ - vlc_mutex_destroy (&p_netlist->lock); + vlc_mutex_destroy( &p_netlist->lock ); /* free the FIFO, the buffer, and the netlist structure */ - free( p_netlist->pp_free_data ); + free( p_netlist->pi_refcount ); + free( p_netlist->p_free_iovec ); free( p_netlist->pp_free_pes ); + free( p_netlist->pp_free_data ); free( p_netlist->p_pes ); free( p_netlist->p_data ); free( p_netlist->p_buffers ); @@ -462,4 +647,3 @@ void input_NetlistEnd( input_thread_t * p_input) /* free the netlist */ free( p_netlist ); } -