* will only be given back to netlist when refcount is zero.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
- * $Id: dvd_netlist.c,v 1.1 2001/03/02 03:32:46 stef Exp $
+ * $Id: dvd_netlist.c,v 1.5 2001/04/06 09:15:47 sam Exp $
*
* Authors: Henri Fallon <henri@videolan.org>
* Stéphane Borel <stef@videolan.org>
#include "defs.h"
#include <stdlib.h>
+#include <string.h> /* memcpy(), memset() */
#include <sys/types.h>
#include <sys/uio.h> /* struct iovec */
#include <unistd.h>
*
* Warning: i_nb_iovec, i_nb_data, i_nb_pes have to be 2^x
*****************************************************************************/
-int DVDNetlistInit( 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 )
+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;
- netlist_t * p_netlist;
+ unsigned int i_loop;
+ dvd_netlist_t * p_netlist;
/* First we allocate and initialise our netlist struct */
- p_input->p_method_data = malloc(sizeof(netlist_t));
- if ( p_input->p_method_data == NULL )
+ p_netlist = malloc( sizeof(dvd_netlist_t) );
+ if ( p_netlist == NULL )
{
intf_ErrMsg("Unable to malloc the DVD netlist struct");
- return (-1);
+ free( p_netlist );
+ return NULL;
}
- p_netlist = (netlist_t *) p_input->p_method_data;
-
/* Nb of packets read once by input */
p_netlist->i_read_once = i_read_once;
if ( p_netlist->p_buffers == NULL )
{
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (1)");
- return (-1);
+ free( p_netlist->p_buffers );
+ free( p_netlist );
+ return NULL;
}
/* table of pointers to data packets */
if ( p_netlist->p_data == NULL )
{
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (2)");
- return (-1);
+ free( p_netlist->p_buffers );
+ free( p_netlist->p_data );
+ free( p_netlist );
+ return NULL;
}
/* table of pointer to PES packets */
if ( p_netlist->p_pes == NULL )
{
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (3)");
- return (-1);
+ 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 */
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 =
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 */
if ( p_netlist->pi_refcount == NULL )
{
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (7)");
- return (-1);
+ 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 */
p_netlist->i_nb_pes = i_nb_pes - 1;
p_netlist->i_buffer_size = i_buffer_size;
- return (0); /* Everything went all right */
+ return p_netlist; /* Everything went all right */
}
/*****************************************************************************
*****************************************************************************/
struct iovec * DVDGetiovec( void * p_method_data )
{
- netlist_t * p_netlist;
+ dvd_netlist_t * p_netlist;
/* cast */
- p_netlist = ( netlist_t * ) p_method_data;
+ p_netlist = (dvd_netlist_t *)p_method_data;
/* check */
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. Unable to allocate memory");
+ intf_ErrMsg("Empty iovec FIFO (%d:%d). Unable to allocate memory",
+ p_netlist->i_iovec_start, p_netlist->i_iovec_end );
return (NULL);
}
+ if( (
+ (p_netlist->i_data_end - p_netlist->i_data_start)
+ & p_netlist->i_nb_data ) < p_netlist->i_read_once )
+ {
+ intf_ErrMsg("Empty data FIFO (%d:%d). Unable to allocate memory",
+ p_netlist->i_data_start, p_netlist->i_data_end );
+ return (NULL);
+ }
/* 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
void DVDMviovec( void * p_method_data, int i_nb_iovec,
struct data_packet_s ** pp_data )
{
- netlist_t * p_netlist;
- unsigned int i_loop = 0;
+ dvd_netlist_t * p_netlist;
+ unsigned int i_loop = 0;
/* cast */
- p_netlist = (netlist_t *)p_method_data;
+ p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */
vlc_mutex_lock( &p_netlist->lock );
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;
*****************************************************************************/
struct data_packet_s * DVDNewPtr( void * p_method_data )
{
- netlist_t * p_netlist;
- struct data_packet_s * p_return;
+ dvd_netlist_t * p_netlist;
+ struct data_packet_s * p_return;
/* cast */
- p_netlist = ( netlist_t * ) p_method_data;
-
-#ifdef DEBUG
- if( i_buffer_size > p_netlist->i_buffer_size )
- {
- /* This should not happen */
- intf_ErrMsg( "Netlist packet too small !" );
- return NULL;
- }
-#endif
+ p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */
vlc_mutex_lock ( &p_netlist->lock );
struct data_packet_s * DVDNewPacket( void * p_method_data,
size_t i_buffer_size )
{
- netlist_t * p_netlist;
+ dvd_netlist_t * p_netlist;
struct data_packet_s * p_packet;
-
+//intf_ErrMsg( "netlist: New packet" );
/* cast */
- p_netlist = (netlist_t *)p_method_data;
+ p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */
vlc_mutex_lock( &p_netlist->lock );
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_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_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;
*****************************************************************************/
struct pes_packet_s * DVDNewPES( void * p_method_data )
{
- netlist_t * p_netlist;
- pes_packet_t * p_return;
+ dvd_netlist_t * p_netlist;
+ pes_packet_t * p_return;
+//intf_ErrMsg( "netlist: New pes" );
/* cast */
- p_netlist = (netlist_t *) p_method_data;
+ p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */
vlc_mutex_lock ( &p_netlist->lock );
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 );
}
*****************************************************************************/
void DVDDeletePacket( void * p_method_data, data_packet_t * p_data )
{
- netlist_t * p_netlist;
+ dvd_netlist_t * p_netlist;
/* cast */
- p_netlist = (netlist_t *) p_method_data;
+ p_netlist = (dvd_netlist_t *) p_method_data;
/* lock */
vlc_mutex_lock ( &p_netlist->lock );
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)--;
p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base =
p_data->p_buffer;
}
-
- /* re initialize for next time */
- p_data->p_next = NULL;
- p_data->b_discard_payload = 0;
/* unlock */
vlc_mutex_unlock (&p_netlist->lock);
*****************************************************************************/
void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes )
{
- netlist_t * p_netlist;
- data_packet_t * p_current_packet,* p_next_packet;
+ dvd_netlist_t * p_netlist;
+ data_packet_t * p_current_packet;
+ data_packet_t * p_next_packet;
/* cast */
- p_netlist = (netlist_t *)p_method_data;
+ p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */
vlc_mutex_lock ( &p_netlist->lock );
p_netlist->i_data_end ++;
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_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 )
+ if( (*p_current_packet->pi_refcount) <= 0 )
{
p_netlist->i_iovec_end++;
p_netlist->i_iovec_end &= p_netlist->i_nb_iovec;
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;
}
/*****************************************************************************
* DVDNetlistEnd: frees all allocated structures
*****************************************************************************/
-void DVDNetlistEnd( input_thread_t * p_input)
+void DVDNetlistEnd( dvd_netlist_t * p_netlist )
{
- 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->pp_free_pes);
- free (p_netlist->pi_refcount);
- free (p_netlist->p_pes);
- free (p_netlist->p_data);
- free (p_netlist->p_buffers);
+ free( p_netlist->pp_free_data );
+ free( p_netlist->pp_free_pes );
+ free( p_netlist->pi_refcount );
+ free( p_netlist->p_pes );
+ free( p_netlist->p_data );
+ free( p_netlist->p_buffers );
/* free the netlist */
- free (p_netlist);
+ free( p_netlist );
}