Commit 9679481f authored by Henri Fallon's avatar Henri Fallon

Added netlist support.

Warning : it has not been tested. It just make no error at build time.
parent b754a016
...@@ -189,6 +189,7 @@ INPUT = src/input/input_ps.o \ ...@@ -189,6 +189,7 @@ INPUT = src/input/input_ps.o \
src/input/mpeg_system.o \ src/input/mpeg_system.o \
src/input/input_ext-dec.o \ src/input/input_ext-dec.o \
src/input/input_programs.o \ src/input/input_programs.o \
src/input/input_netlist.o \
src/input/input.o src/input/input.o
AUDIO_OUTPUT = src/audio_output/audio_output.o AUDIO_OUTPUT = src/audio_output/audio_output.o
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "defs.h" #include "defs.h"
#include <stdlib.h> #include <stdlib.h>
#include <sys/uio.h> /* struct iovec */
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
...@@ -51,12 +52,10 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, ...@@ -51,12 +52,10 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes,
size_t i_buffer_size ) size_t i_buffer_size )
{ {
unsigned int i_loop; unsigned int i_loop;
netlist_t * p_netlist; /* for a cast */ netlist_t * p_netlist;
/* First we allocate and initialise our netlist struct */ /* First we allocate and initialise our netlist struct */
p_input->p_method_data = malloc(sizeof(netlist_t)); p_input->p_method_data = malloc(sizeof(netlist_t));
if ( p_input->p_method_data == NULL ) if ( p_input->p_method_data == NULL )
{ {
intf_ErrMsg("Unable to malloc the netlist struct\n"); intf_ErrMsg("Unable to malloc the netlist struct\n");
...@@ -65,72 +64,83 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, ...@@ -65,72 +64,83 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes,
p_netlist = (netlist_t *) p_input->p_method_data; p_netlist = (netlist_t *) p_input->p_method_data;
//On a besoin de p_buffers pour p_data. Il faut faire l'initialisation /* allocate the buffers */
//p_data->p_buffer = p_buffers + i * i_buffer_size p_netlist->p_buffers =
//p_data->p_payload_start = p_data->p_buffer (byte_t *) malloc(i_buffer_size* i_nb_data );
//p_data->p_payload_end = p_data->p_buffer + i_buffer_size
/* For the time being, I only handle pes and data. iovec is to come soon
*
p_netlist->p_buffers = malloc(i_buffer_size*i_nb_data)
if ( p_netlist->p_buffers == NULL ) if ( p_netlist->p_buffers == NULL )
{ {
intf_ErrMsg ("Unable to malloc in netlist initialization (1)\n"); intf_ErrMsg ("Unable to malloc in netlist initialization (1)\n");
return (-1); return (-1);
} }
*/
//Hum. Remplacer i_buffer_size par sizeof(data_packet_t) et rajouter
//un cast en (data_packet_t *) (c'est un buffer de data_packet_t, quand
//mme.
//D'autre part le INPUT_READ_ONCE n'est l quand dans l'initialisation
//des iovec => virer partout ailleurs.
p_netlist->p_data = p_netlist->p_data =
malloc(i_buffer_size*(i_nb_data + INPUT_READ_ONCE)); (data_packet_t *) malloc(sizeof(data_packet_t)*(i_nb_data));
if ( p_netlist->p_data == NULL ) if ( p_netlist->p_data == NULL )
{ {
intf_ErrMsg ("Unable to malloc in netlist initialization (2)\n"); intf_ErrMsg ("Unable to malloc in netlist initialization (2)\n");
return (-1); return (-1);
} }
//Pareil.
p_netlist->p_pes = p_netlist->p_pes =
malloc(i_buffer_size*(i_nb_pes + INPUT_READ_ONCE)); (pes_packet_t *) malloc(sizeof(pes_packet_t)*(i_nb_pes));
if ( p_netlist->p_pes == NULL ) if ( p_netlist->p_pes == NULL )
{ {
intf_ErrMsg ("Unable to malloc in netlist initialization (3)\n"); intf_ErrMsg ("Unable to malloc in netlist initialization (3)\n");
return (-1); return (-1);
} }
//Il faut toujours caster la sortie du malloc (a renvoie void * par
//dfaut) /* allocate the FIFOs */
p_netlist->pp_free_data = p_netlist->pp_free_data =
malloc (i_nb_data * sizeof(data_packet_t *) ); (data_packet_t **) malloc (i_nb_data * sizeof(data_packet_t *) );
if ( p_netlist->pp_free_data == NULL ) if ( p_netlist->pp_free_data == NULL )
{ {
intf_ErrMsg ("Unable to malloc in netlist initialization (4)\n"); intf_ErrMsg ("Unable to malloc in netlist initialization (4)\n");
} }
//i_nb_pes peut-tre ?
p_netlist->pp_free_pes = p_netlist->pp_free_pes =
malloc (i_nb_data * sizeof(pes_packet_t *) ); (pes_packet_t **) malloc (i_nb_pes * sizeof(pes_packet_t *) );
if ( p_netlist->pp_free_pes == NULL ) if ( p_netlist->pp_free_pes == NULL )
{ {
intf_ErrMsg ("Unable to malloc in netlist initialization (5)\n"); intf_ErrMsg ("Unable to malloc in netlist initialization (5)\n");
} }
//p_free_iovec = malloc( (i_nb_data + INPUT_READ_ONCE) * sizeof(...) )
p_netlist->p_free_iovec = ( struct iovec * )
malloc( (i_nb_data + INPUT_READ_ONCE) * sizeof(struct iovec) );
if ( p_netlist->p_free_iovec == NULL )
{
intf_ErrMsg ("Unable to malloc in netlist initialization (6)\n");
}
/* Fill the data FIFO */ /* Fill the data FIFO */
for ( i_loop = 0; i_loop < i_nb_data; i_loop++ ) for ( i_loop = 0; i_loop < i_nb_data; i_loop++ )
{ {
p_netlist->pp_free_data[i_loop] = p_netlist->pp_free_data[i_loop] =
p_netlist->p_data + i_loop; p_netlist->p_data + i_loop;
//manque l'initialisation de l'intrieur de p_data (cf. supra)
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 */ /* Fill the PES FIFO */
for ( i_loop = 0; i_loop < i_nb_pes + INPUT_READ_ONCE; i_loop++ ) for ( i_loop = 0; i_loop < i_nb_pes ; i_loop++ )
{ {
p_netlist->pp_free_pes[i_loop] = p_netlist->pp_free_pes[i_loop] =
p_netlist->p_pes + i_loop; p_netlist->p_pes + i_loop;
} }
//p_free_iovec[i_loop].iov_base = p_buffers + i_loop * i_buffer_size
//p_free_iovec[i_loop].iov_len = i_buffer_size /* Deal with the iovec */
for ( i_loop = 0; i_loop < i_nb_data; 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;
}
/* vlc_mutex_init */ /* vlc_mutex_init */
vlc_mutex_init (&p_netlist->lock); vlc_mutex_init (&p_netlist->lock);
...@@ -141,9 +151,8 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, ...@@ -141,9 +151,8 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes,
p_netlist->i_pes_start = 0; p_netlist->i_pes_start = 0;
p_netlist->i_pes_end = i_nb_pes + INPUT_READ_ONCE - 1; p_netlist->i_pes_end = i_nb_pes + INPUT_READ_ONCE - 1;
// p_netlist->i_iovec_start = 0; p_netlist->i_iovec_start = 0;
// p_netlist->i_iovec_end = /* ?? */ p_netlist->i_iovec_end = i_nb_data - 1;
//i_nb_data - 1
p_netlist->i_nb_data = i_nb_data; p_netlist->i_nb_data = i_nb_data;
p_netlist->i_nb_pes = i_nb_pes; p_netlist->i_nb_pes = i_nb_pes;
...@@ -155,40 +164,60 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes, ...@@ -155,40 +164,60 @@ int input_NetlistInit( input_thread_t * p_input, int i_nb_data, int i_nb_pes,
/***************************************************************************** /*****************************************************************************
* input_NetlistGetiovec: returns an iovec pointer for a readv() operation * input_NetlistGetiovec: returns an iovec pointer for a readv() operation
*****************************************************************************/ *****************************************************************************/
struct iovec * input_NetlistGetiovec( void * p_netlist ) struct iovec * input_NetlistGetiovec( void * p_method_data )
{ {
/* fonction la plus difficile, terminer par celle-la netlist_t * p_netlist;
* je la ferai plus tard :p */
//vrifier i_iovec_end - i_iovec_start > INPUT_READ_ONCE /* cast */
//la grosse astuce : p_netlist = ( netlist_t * ) p_method_data;
//if( i_nb_data - i_iovec_start < INPUT_READ_ONCE )
// memcpy( &p_free_iovec[i_nb_data], p_free_iovec, INPUT_READ_ONCE*... ) /* check */
//return &p_free_iovec[i_iovec_start]; if (
return ( NULL ); /* nothing yet */ (p_netlist->i_iovec_end - p_netlist->i_iovec_start)%p_netlist->i_nb_data
< INPUT_READ_ONCE )
{
intf_ErrMsg("Empty iovec FIFO. Unable to allocate memory\n");
return (NULL);
}
/* readv only takes contiguous buffers */
if( p_netlist->i_nb_data - p_netlist->i_iovec_start < INPUT_READ_ONCE )
memcpy( &p_netlist->p_free_iovec[p_netlist->i_nb_data],
p_netlist->p_free_iovec,
INPUT_READ_ONCE-(p_netlist->i_nb_data-p_netlist->i_iovec_start)
);
p_netlist->i_iovec_start += INPUT_READ_ONCE;
p_netlist->i_iovec_start %= p_netlist->i_nb_data;
return &p_netlist->p_free_iovec[p_netlist->i_iovec_start];
} }
//je rajoute celle-l
/***************************************************************************** /*****************************************************************************
* input_NetlistMviovec: move the iovec pointer after a readv() operation * input_NetlistMviovec: move the iovec pointer after a readv() operation
*****************************************************************************/ *****************************************************************************/
void input_NetlistMviovec( void * p_netlist, size_t i_nb_iovec ) void input_NetlistMviovec( void * p_method_data, size_t i_nb_iovec )
{ {
//i_iovec_start += i_nb_iovec netlist_t * p_netlist;
//i_iovec_start %= i_nb_data //oui j'ai bien dit i_nb_data
/* cast */
p_netlist = (netlist_t *) p_method_data;
p_netlist->i_iovec_start += i_nb_iovec;
p_netlist->i_iovec_start %= p_netlist->i_nb_data;
} }
/***************************************************************************** /*****************************************************************************
* input_NetlistNewPacket: returns a free data_packet_t * input_NetlistNewPacket: returns a free data_packet_t
*****************************************************************************/ *****************************************************************************/
struct data_packet_s * input_NetlistNewPacket( void * p_netlist, struct data_packet_s * input_NetlistNewPacket( void * p_method_data,
size_t i_buffer_size ) size_t i_buffer_size )
{ {
unsigned int i_return; netlist_t * p_netlist;
netlist_t * pt_netlist; /* for a cast */ struct data_packet_s * p_return;
//pas beau, pt_netlist, j'aurais prfr void * p_method_data et
//netlist_t * p_netlist /* cast */
pt_netlist = ( netlist_t * ) p_netlist; p_netlist = ( netlist_t * ) p_method_data;
/* cast p_netlist -> netlist_t */
#ifdef DEBUG #ifdef DEBUG
if( i_buffer_size > p_netlist->i_buffer_size ) if( i_buffer_size > p_netlist->i_buffer_size )
...@@ -200,127 +229,144 @@ struct data_packet_s * input_NetlistNewPacket( void * p_netlist, ...@@ -200,127 +229,144 @@ struct data_packet_s * input_NetlistNewPacket( void * p_netlist,
#endif #endif
/* lock */ /* lock */
vlc_mutex_lock ( &pt_netlist->lock ); vlc_mutex_lock ( &p_netlist->lock );
/* check */ /* check */
if ( pt_netlist->i_data_start == pt_netlist->i_data_end ) if ( p_netlist->i_data_start == p_netlist->i_data_end )
{ {
//empty peut-tre ? intf_ErrMsg("Empty Data FIFO in netlist. Unable to allocate memory\n");
intf_ErrMsg("Full Data FIFO in netlist - Unable to allocate memory\n");
return ( NULL ); return ( NULL );
} }
i_return = (pt_netlist->i_data_start)++; p_return = (p_netlist->pp_free_data[p_netlist->i_data_start]);
pt_netlist->i_data_start %= pt_netlist->i_nb_data; p_netlist->i_data_start++;
//i_iovec_start++; i_iovec_start %= i_nb_data //oui j'ai bien dit i_nb_data p_netlist->i_data_start %= p_netlist->i_nb_data;
p_netlist->i_iovec_start++;
p_netlist->i_iovec_start %= p_netlist->i_nb_data;
/* unlock */ /* unlock */
vlc_mutex_unlock (&pt_netlist->lock); vlc_mutex_unlock (&p_netlist->lock);
if (i_buffer_size < p_netlist->i_buffer_size)
{
p_return->p_payload_end = p_return->p_payload_start + i_buffer_size;
}
//if (i_buffer_size < p_pes->i_buffer_size) => diminuer p_payload_end /* initialize data */
p_return->p_next = NULL;
p_return->b_discard_payload = 0;
//risque de race condition : que se passe-t-il si aprs avoir rendu return ( p_return );
//le lock un autre thread rend un paquet et crase
//pp_free_data[i_return] ?
return ( pt_netlist->pp_free_data[i_return] );
//il faudrait aussi initialiser p_payload_start et p_payload_end
} }
/***************************************************************************** /*****************************************************************************
* input_NetlistNewPES: returns a free pes_packet_t * input_NetlistNewPES: returns a free pes_packet_t
*****************************************************************************/ *****************************************************************************/
struct pes_packet_s * input_NetlistNewPES( void * p_netlist ) struct pes_packet_s * input_NetlistNewPES( void * p_method_data )
{ {
unsigned int i_return; netlist_t * p_netlist;
netlist_t * pt_netlist; /* for a cast */ pes_packet_t * p_return;
//tout pareil qu'au-dessus /* cast */
pt_netlist = (netlist_t *)p_netlist; p_netlist = (netlist_t *) p_method_data;
/* lock */ /* lock */
vlc_mutex_lock ( &pt_netlist->lock ); vlc_mutex_lock ( &p_netlist->lock );
/* check */ /* check */
if ( pt_netlist->i_pes_start == pt_netlist->i_pes_end ) if ( p_netlist->i_pes_start == p_netlist->i_pes_end )
{ {
intf_ErrMsg("Full PES FIFO in netlist - Unable to allocate memory\n"); intf_ErrMsg("Empty PES FIFO in netlist - Unable to allocate memory\n");
return ( NULL ); return ( NULL );
} }
i_return = (pt_netlist->i_pes_start)++; /* allocate */
pt_netlist->i_pes_start %= pt_netlist->i_nb_pes; 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 */ /* unlock */
vlc_mutex_unlock (&pt_netlist->lock); vlc_mutex_unlock (&p_netlist->lock);
/* initialize PES */
p_return->b_messed_up =
p_return->b_data_alignment =
p_return->b_discontinuity =
p_return->b_has_pts = 0;
p_return->i_pes_size = 0;
p_return->p_first = NULL;
return ( pt_netlist->pp_free_pes[i_return] ); return ( p_return );
//il faudrait initialiser le pes :
//b_messed_up = b_data_alignment = b_discontinuity = b_has_pts = 0
//i_pes_size = 0
//p_first = NULL
} }
/***************************************************************************** /*****************************************************************************
* input_NetlistDeletePacket: puts a data_packet_t back into the netlist * input_NetlistDeletePacket: puts a data_packet_t back into the netlist
*****************************************************************************/ *****************************************************************************/
void input_NetlistDeletePacket( void * p_netlist, data_packet_t * p_data ) void input_NetlistDeletePacket( void * p_method_data, data_packet_t * p_data )
{ {
netlist_t * pt_netlist; /* for a cast */ netlist_t * p_netlist;
pt_netlist = (netlist_t *) p_netlist; /* cast */
p_netlist = (netlist_t *) p_method_data;
/* lock */ /* lock */
vlc_mutex_lock ( &pt_netlist->lock ); vlc_mutex_lock ( &p_netlist->lock );
pt_netlist->i_data_end ++; /* Delete data_packet */
pt_netlist->i_data_end %= pt_netlist->i_nb_data; p_netlist->i_data_end ++;
//i_iovec_end++; i_iovec_end %= i_nb_data //oui j'ai bien dit i_nb_data p_netlist->i_data_end %= p_netlist->i_nb_data;
//p_free_iovec[i_iovec_end].iov_base = p_data->p_buffer p_netlist->pp_free_data[p_netlist->i_data_end] = p_data;
pt_netlist->pp_free_data[pt_netlist->i_data_end] = p_data; /* Delete the corresponding iovec */
p_netlist->i_iovec_end++;
p_netlist->i_iovec_end %= p_netlist->i_nb_data;
p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base =
p_data->p_buffer;
/* unlock */ /* unlock */
vlc_mutex_unlock (&pt_netlist->lock); vlc_mutex_unlock (&p_netlist->lock);
} }
/***************************************************************************** /*****************************************************************************
* input_NetlistDeletePES: puts a pes_packet_t back into the netlist * input_NetlistDeletePES: puts a pes_packet_t back into the netlist
*****************************************************************************/ *****************************************************************************/
void input_NetlistDeletePES( void * p_netlist, pes_packet_t * p_pes ) void input_NetlistDeletePES( void * p_method_data, pes_packet_t * p_pes )
{ {
/* idem, plus detruire tous les data_packet_t dans p_pes->p_first, netlist_t * p_netlist;
* p_pes->p_first->p_next, etc. */
netlist_t * pt_netlist; /* for a cast */
data_packet_t * p_current_packet; data_packet_t * p_current_packet;
pt_netlist = (netlist_t *)p_netlist; /* cast */
p_netlist = (netlist_t *)p_method_data;
/* lock */ /* lock */
vlc_mutex_lock ( &pt_netlist->lock ); vlc_mutex_lock ( &p_netlist->lock );
/* free p_pes->p_first, p_next ... */ /* delete free p_pes->p_first, p_next ... */
p_current_packet = p_pes->p_first; p_current_packet = p_pes->p_first;
while ( p_current_packet != NULL ) while ( p_current_packet != NULL )
{ {
/* copy of NetListDeletePacket /* copy of NetListDeletePacket, duplicate code avoid many locks */
* Duplicate code avoid many locks */
pt_netlist->i_data_end ++;
pt_netlist->i_data_end %= pt_netlist->i_nb_data;
//i_iovec_end++; i_iovec_end %= i_nb_data //oui j'ai bien dit i_nb_data
//p_free_iovec[i_iovec_end].iov_base = p_data->p_buffer
pt_netlist->pp_free_data[pt_netlist->i_data_end] = p_current_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_current_packet;
p_netlist->i_iovec_end++;
p_netlist->i_iovec_end %= p_netlist->i_nb_data;
p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base =
p_netlist->p_data->p_buffer;
p_current_packet = p_current_packet->p_next; p_current_packet = p_current_packet->p_next;
} }
pt_netlist->i_pes_end ++; /* delete our current PES packet */
pt_netlist->i_pes_end %= pt_netlist->i_nb_pes; p_netlist->i_pes_end ++;
p_netlist->i_pes_end %= p_netlist->i_nb_pes;
pt_netlist->pp_free_pes[pt_netlist->i_pes_end] = p_pes; p_netlist->pp_free_pes[p_netlist->i_pes_end] = p_pes;
/* unlock */ /* unlock */
vlc_mutex_unlock (&pt_netlist->lock); vlc_mutex_unlock (&p_netlist->lock);
} }
/***************************************************************************** /*****************************************************************************
...@@ -328,8 +374,9 @@ void input_NetlistDeletePES( void * p_netlist, pes_packet_t * p_pes ) ...@@ -328,8 +374,9 @@ void input_NetlistDeletePES( void * p_netlist, pes_packet_t * p_pes )
*****************************************************************************/ *****************************************************************************/
void input_NetlistEnd( input_thread_t * p_input) void input_NetlistEnd( input_thread_t * p_input)
{ {
netlist_t * p_netlist; /* for a cast */ netlist_t * p_netlist;
/* cast */
p_netlist = ( netlist_t * ) p_input->p_method_data; p_netlist = ( netlist_t * ) p_input->p_method_data;
/* free the FIFO, the buffer, and the netlist structure */ /* free the FIFO, the buffer, and the netlist structure */
...@@ -338,6 +385,6 @@ void input_NetlistEnd( input_thread_t * p_input) ...@@ -338,6 +385,6 @@ void input_NetlistEnd( input_thread_t * p_input)
free (p_netlist->p_pes); free (p_netlist->p_pes);
free (p_netlist->p_data); free (p_netlist->p_data);
/* free the netlist */
free (p_netlist); free (p_netlist);
} }
//sinon c'est bien (c)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment