Commit 91bc3eb7 authored by Christophe Massiot's avatar Christophe Massiot

* New decoder spawning API input_dec.c ;

* Moved p_input->pp_es -> p_input->stream.pp_es and clean up of
  input_programs.c & co ;
* Fixed memory leaks.
parent 423a3bcf
......@@ -189,6 +189,7 @@ INPUT = src/input/input_ps.o \
src/input/input_ts.o \
src/input/mpeg_system.o \
src/input/input_ext-dec.o \
src/input/input_dec.o \
src/input/input_programs.o \
src/input/input_netlist.o \
src/input/input.o
......
/*****************************************************************************
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.4 2000/12/21 19:24:26 massiot Exp $
*
* Authors:
*
* 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.
*****************************************************************************/
/* Structures exported to the decoders */
/*****************************************************************************
......@@ -496,7 +519,7 @@ typedef struct decoder_capabilities_s
int i_weight; /* for a given stream type, the decoder
* with higher weight will be spawned */
vlc_thread_t (* pf_create_thread)( struct decoder_config_s * );
vlc_thread_t (* pf_create_thread)( void * );
} decoder_capabilities_t;
/* Decoder types */
......
......@@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.7 2000/12/21 15:01:08 massiot Exp $
* $Id: input_ext-intf.h,v 1.8 2000/12/21 19:24:26 massiot Exp $
*
* Authors:
*
......@@ -153,10 +153,16 @@ typedef struct stream_descriptor_s
/* Demultiplexer data */
void * p_demux_data;
/* Programs description */
/* Programs descriptions */
int i_pgrm_number; /* size of the following array */
pgrm_descriptor_t ** pp_programs; /* array of pointers to pgrm */
/* ES descriptions */
int i_es_number;
es_descriptor_t ** pp_es; /* carried elementary streams */
int i_selected_es_number;
es_descriptor_t ** pp_selected_es; /* ES with a decoder */
/* Stream control */
stream_ctrl_t control;
} stream_descriptor_t;
......@@ -211,12 +217,6 @@ typedef struct input_thread_s
/* General stream description */
stream_descriptor_t stream; /* PAT tables */
es_descriptor_t ** pp_es; /* carried elementary streams */
int i_es_number;
/* List of streams to demux */
es_descriptor_t ** pp_selected_es;
int i_selected_es_number;
/* For auto-launch of decoders */
struct aout_thread_s * p_default_aout;
......
......@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input.c,v 1.62 2000/12/21 14:18:15 massiot Exp $
* $Id: input.c,v 1.63 2000/12/21 19:24:26 massiot Exp $
*
* Authors:
*
......@@ -95,10 +95,8 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status )
p_input->p_config = p_config;
/* Initialize stream description */
p_input->pp_es = NULL;
p_input->pp_selected_es = NULL;
p_input->i_es_number = 0;
p_input->i_selected_es_number = 0;
p_input->stream.i_es_number = 0;
p_input->stream.i_selected_es_number = 0;
p_input->stream.i_pgrm_number = 0;
/* Initialize stream control properties. */
......@@ -296,7 +294,6 @@ static void ErrorThread( input_thread_t *p_input )
static void EndThread( input_thread_t * p_input )
{
int * pi_status; /* thread status */
int i_es_loop; /* es index */
/* Store status */
pi_status = p_input->pi_status;
......@@ -312,41 +309,14 @@ static void EndThread( input_thread_t * p_input )
}
#endif
/* Destroy all decoder threads */
for( i_es_loop = 0; i_es_loop < p_input->i_selected_es_number;
i_es_loop++ )
{
decoder_fifo_t * p_decoder_fifo;
p_decoder_fifo = p_input->pp_selected_es[i_es_loop]->p_decoder_fifo;
p_decoder_fifo->b_die = 1;
/* Make sure the thread leaves the NextDataPacket() function */
vlc_mutex_lock( &p_decoder_fifo->data_lock);
vlc_cond_signal( &p_decoder_fifo->data_wait );
vlc_mutex_unlock( &p_decoder_fifo->data_lock );
/* Waiting for the thread to exit */
vlc_thread_join( p_input->pp_selected_es[i_es_loop]->thread_id );
/* Freeing all packets still in the decoder fifo. */
while( !DECODER_FIFO_ISEMPTY( *p_decoder_fifo ) )
{
p_decoder_fifo->pf_delete_pes( p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_decoder_fifo );
}
free( p_input->pp_selected_es[i_es_loop]->p_decoder_fifo );
}
/* Free all ES and destroy all decoder threads */
input_EndStream( p_input );
/* Free demultiplexer's data */
p_input->p_plugin->pf_end( p_input );
free( p_input->p_plugin );
/* Free input structures */
input_EndStream( p_input );
free( p_input->pp_es );
free( p_input->pp_selected_es );
/* Free input structure */
free( p_input );
/* Update status */
......
......@@ -2,7 +2,7 @@
* input.h: structures of the input not exported to other modules
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input.h,v 1.5 2000/12/21 14:18:15 massiot Exp $
* $Id: input.h,v 1.6 2000/12/21 19:24:27 massiot Exp $
*
* Authors:
*
......@@ -78,13 +78,15 @@ void NextDataPacket ( struct bit_stream_s * );
*****************************************************************************/
void input_InitStream( struct input_thread_s *, size_t );
void input_EndStream( struct input_thread_s * );
struct pgrm_descriptor_s * input_FindProgram( struct input_thread_s *, u16 );
struct pgrm_descriptor_s * input_AddProgram( struct input_thread_s *,
u16, size_t );
void input_DelProgram( struct input_thread_s *, u16 );
void input_DelProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
void input_DumpStream( struct input_thread_s * );
struct es_descriptor_s * input_FindES( struct input_thread_s *, u16 );
struct es_descriptor_s * input_AddES( struct input_thread_s *,
struct pgrm_descriptor_s *, u16,
size_t );
void input_DelES( struct input_thread_s *, u16 );
void input_DelES( struct input_thread_s *, struct es_descriptor_s * );
int input_SelectES( struct input_thread_s *, struct es_descriptor_s * );
/*****************************************************************************
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_dec.c,v 1.1 2000/12/21 19:24:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* 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
*****************************************************************************/
/* FIXME: we shouldn't be obliged to include these */
#include "defs.h"
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
/*****************************************************************************
* input_RunDecoder: spawns a new decoder thread
*****************************************************************************/
vlc_thread_t input_RunDecoder( decoder_capabilities_t * p_decoder,
void * p_data )
{
return( p_decoder->pf_create_thread( p_data ) );
}
/*****************************************************************************
* input_EndDecoder: kills a decoder thread and waits until it's finished
*****************************************************************************/
void input_EndDecoder( decoder_fifo_t * p_decoder_fifo, vlc_thread_t thread_id )
{
p_decoder_fifo->b_die = 1;
/* Make sure the thread leaves the NextDataPacket() function */
vlc_mutex_lock( &p_decoder_fifo->data_lock);
vlc_cond_signal( &p_decoder_fifo->data_wait );
vlc_mutex_unlock( &p_decoder_fifo->data_lock );
/* Waiting for the thread to exit */
vlc_thread_join( thread_id );
/* Freeing all packets still in the decoder fifo. */
while( !DECODER_FIFO_ISEMPTY( *p_decoder_fifo ) )
{
p_decoder_fifo->pf_delete_pes( p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_decoder_fifo );
}
}
/*****************************************************************************
* input_dec.h: prototypes needed by an application to use a VideoLAN
* decoder
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_dec.h,v 1.1 2000/12/21 19:24:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
//decoder_capabilities_s * input_ProbeDecoder( void );
vlc_thread_t input_RunDecoder( struct decoder_capabilities_s *, void * );
void input_EndDecoder( struct decoder_fifo_s *, vlc_thread_t );
......@@ -3,7 +3,7 @@
* FIXME : check the return value of realloc() and malloc() !
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_programs.c,v 1.12 2000/12/21 14:18:15 massiot Exp $
* $Id: input_programs.c,v 1.13 2000/12/21 19:24:27 massiot Exp $
*
* Authors:
*
......@@ -41,6 +41,7 @@
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input.h"
#include "input_dec.h"
#include "main.h" /* --noaudio --novideo */
......@@ -55,7 +56,8 @@
void input_InitStream( input_thread_t * p_input, size_t i_data_len )
{
p_input->stream.i_stream_id = 0;
p_input->stream.i_pgrm_number = 0;
p_input->stream.pp_es = NULL;
p_input->stream.pp_selected_es = NULL;
p_input->stream.pp_programs = NULL;
if( i_data_len )
......@@ -70,25 +72,41 @@ void input_InitStream( input_thread_t * p_input, size_t i_data_len )
*****************************************************************************/
void input_EndStream( input_thread_t * p_input )
{
int i, j;
int i;
/* Free all programs and associated ES, and associated decoders. */
for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
{
for( j = 0; j < p_input->stream.pp_programs[i]->i_es_number; j++ )
{
if( p_input->stream.pp_programs[i]->pp_es[j]->p_demux_data != NULL )
{
free( p_input->stream.pp_programs[i]->pp_es[j]->p_demux_data );
}
free( p_input->stream.pp_programs[i]->pp_es[j] );
}
/* Don't put i instead of 0 !! */
input_DelProgram( p_input, p_input->stream.pp_programs[0] );
}
free( p_input->stream.pp_programs );
if( p_input->stream.pp_programs[i]->p_demux_data != NULL )
/* Free standalone ES */
for( i = 0; i < p_input->stream.i_es_number; i++ )
{
input_DelES( p_input, p_input->stream.pp_es[0] );
}
free( p_input->stream.pp_es );
free( p_input->stream.pp_selected_es );
}
/*****************************************************************************
* input_FindProgram: returns a pointer to a program described by its ID
*****************************************************************************/
pgrm_descriptor_t * input_FindProgram( input_thread_t * p_input, u16 i_pgrm_id )
{
int i;
for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
{
if( p_input->stream.pp_programs[i]->i_number == i_pgrm_id )
{
free( p_input->stream.pp_programs[i]->p_demux_data );
return p_input->stream.pp_programs[i];
}
free( p_input->stream.pp_programs[i] );
}
return( NULL );
}
/*****************************************************************************
......@@ -151,32 +169,18 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
*****************************************************************************
* All ES descriptions referenced in the descriptor will be deleted.
*****************************************************************************/
void input_DelProgram( input_thread_t * p_input, u16 i_pgrm_id )
void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
{
int i_index, i_pgrm_index = -1;
pgrm_descriptor_t * p_pgrm = NULL;
int i_index, i_pgrm_index;
intf_DbgMsg("Deleting description for pgrm %d", i_pgrm_id);
ASSERT( p_pgrm );
/* Find where this program is described */
for( i_index = 0; i_index < p_input->stream.i_pgrm_number; i_index++ )
{
if( p_input->stream.pp_programs[i_index]->i_number == i_pgrm_id )
{
i_pgrm_index = i_index;
p_pgrm = p_input->stream.pp_programs[ i_pgrm_index ];
break;
}
}
/* Make sure that the pgrm exists */
ASSERT(i_pgrm_index >= 0);
ASSERT(p_pgrm);
intf_DbgMsg("Deleting description for pgrm %d", p_pgrm->i_stream_id);
/* Free the structures that describe the es that belongs to that program */
for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
{
input_DelES( p_input, p_pgrm->pp_es[i_index]->i_id );
input_DelES( p_input, p_pgrm->pp_es[i_index] );
}
/* Free the table of es descriptors */
......@@ -188,8 +192,13 @@ void input_DelProgram( input_thread_t * p_input, u16 i_pgrm_id )
free( p_pgrm->p_demux_data );
}
/* Free the description of this stream */
free( p_pgrm );
/* Find the program in the programs table */
for( i_pgrm_index = 0; i_pgrm_index < p_input->stream.i_pgrm_number;
i_pgrm_index++ )
{
if( p_input->stream.pp_programs[i_pgrm_index] == p_pgrm )
break;
}
/* Remove this program from the stream's list of programs */
p_input->stream.i_pgrm_number--;
......@@ -198,6 +207,27 @@ void input_DelProgram( input_thread_t * p_input, u16 i_pgrm_id )
p_input->stream.pp_programs = realloc( p_input->stream.pp_programs,
p_input->stream.i_pgrm_number
* sizeof(pgrm_descriptor_t *) );
/* Free the description of this program */
free( p_pgrm );
}
/*****************************************************************************
* input_FindES: returns a pointer to an ES described by its ID
*****************************************************************************/
es_descriptor_t * input_FindES( input_thread_t * p_input, u16 i_es_id )
{
int i;
for( i = 0; i < p_input->stream.i_es_number; i++ )
{
if( p_input->stream.pp_es[i]->i_id == i_es_id )
{
return p_input->stream.pp_es[i];
}
}
return( NULL );
}
/*****************************************************************************
......@@ -216,10 +246,11 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
intf_DbgMsg("Adding description for ES %d", i_es_id);
p_es = (es_descriptor_t *)malloc( sizeof(es_descriptor_t) );
p_input->i_es_number++;
p_input->pp_es = realloc( p_input->pp_es, p_input->i_es_number
* sizeof(es_descriptor_t *) );
p_input->pp_es[p_input->i_es_number - 1] = p_es;
p_input->stream.i_es_number++;
p_input->stream.pp_es = realloc( p_input->stream.pp_es,
p_input->stream.i_es_number
* sizeof(es_descriptor_t *) );
p_input->stream.pp_es[p_input->stream.i_es_number - 1] = p_es;
p_es->i_id = i_es_id;
/* Init its values */
......@@ -254,32 +285,28 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
/*****************************************************************************
* input_DelES:
*****************************************************************************/
void input_DelES( input_thread_t * p_input, u16 i_id )
void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
{
int i_index, i_es;
pgrm_descriptor_t * p_pgrm = NULL;
es_descriptor_t * p_es = NULL;
int i_index, i_es_index;
pgrm_descriptor_t * p_pgrm;
/* Look for the description of the ES */
for( i_es = 0; i_es < p_input->i_es_number; i_es++ )
ASSERT( p_es );
p_pgrm = p_es->p_pgrm;
/* Kill associated decoder, if any. */
if( p_es->p_decoder_fifo != NULL )
{
if( p_input->pp_es[i_es]->i_id == i_id )
{
p_es = p_input->pp_es[i_es];
p_pgrm = p_input->pp_es[i_es]->p_pgrm;
break;
}
input_EndDecoder( p_es->p_decoder_fifo, p_es->thread_id );
free( p_es->p_decoder_fifo );
}
ASSERT( p_es );
/* Remove this ES from the description of the program if it is associated to
* one */
if( p_pgrm )
{
for( i_index = 0; ; i_index++ )
for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
{
if( p_pgrm->pp_es[i_index]->i_id == i_id )
if( p_pgrm->pp_es[i_index] == p_es )
{
p_pgrm->i_es_number--;
p_pgrm->pp_es[i_index] = p_pgrm->pp_es[p_pgrm->i_es_number];
......@@ -297,12 +324,22 @@ void input_DelES( input_thread_t * p_input, u16 i_id )
free( p_es->p_demux_data );
}
/* Find the ES in the ES table */
for( i_es_index = 0; i_es_index < p_input->stream.i_es_number;
i_es_index++ )
{
if( p_input->stream.pp_es[i_es_index] == p_es )
break;
}
/* Free the ES */
free( p_es );
p_input->i_es_number--;
p_input->pp_es[i_es] = p_input->pp_es[p_input->i_es_number];
p_input->pp_es = realloc( p_input->pp_es, p_input->i_es_number
* sizeof(es_descriptor_t *));
p_input->stream.i_es_number--;
p_input->stream.pp_es[i_es_index] =
p_input->stream.pp_es[p_input->stream.i_es_number];
p_input->stream.pp_es = realloc( p_input->stream.pp_es,
p_input->stream.i_es_number
* sizeof(es_descriptor_t *));
}
#ifdef STATS
......@@ -417,9 +454,16 @@ static adec_config_t * GetAdecConfig( input_thread_t * p_input,
/*****************************************************************************
* input_SelectES: selects an ES and spawns the associated decoder
*****************************************************************************/
/* FIXME */
vlc_thread_t adec_CreateThread( void * );
vlc_thread_t ac3dec_CreateThread( void * );
vlc_thread_t vpar_CreateThread( void * );
vlc_thread_t spudec_CreateThread( void * );
int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
{
int i;
/* FIXME ! */
decoder_capabilities_t decoder;
#ifdef DEBUG_INPUT
intf_DbgMsg( "Selecting ES %d", p_es->i_id );
......@@ -437,8 +481,9 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
case MPEG2_AUDIO_ES:
if( p_main->b_audio )
{
p_es->thread_id = adec_CreateThread( GetAdecConfig( p_input,
p_es ) );
decoder.pf_create_thread = adec_CreateThread;
p_es->thread_id = input_RunDecoder( &decoder,
(void *)GetAdecConfig( p_input, p_es ) );
}
break;
......@@ -446,24 +491,27 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
case MPEG2_VIDEO_ES:
if( p_main->b_video )
{
p_es->thread_id = vpar_CreateThread( GetVdecConfig( p_input,
p_es ) );
decoder.pf_create_thread = vpar_CreateThread;
p_es->thread_id = input_RunDecoder( &decoder,
(void *)GetVdecConfig( p_input, p_es ) );
}
break;
case AC3_AUDIO_ES:
if( p_main->b_audio )
{
p_es->thread_id = ac3dec_CreateThread( GetAdecConfig( p_input,
p_es ) );
decoder.pf_create_thread = ac3dec_CreateThread;
p_es->thread_id = input_RunDecoder( &decoder,
(void *)GetAdecConfig( p_input, p_es ) );
}
break;
case DVD_SPU_ES:
if( p_main->b_video )
{
p_es->thread_id = spudec_CreateThread( GetVdecConfig( p_input,
p_es ) );
decoder.pf_create_thread = spudec_CreateThread;
p_es->thread_id = input_RunDecoder( &decoder,
(void *)GetVdecConfig( p_input, p_es ) );
}
break;
......@@ -475,11 +523,13 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
if( p_es->p_decoder_fifo != NULL )
{
p_input->i_selected_es_number++;
p_input->pp_selected_es = realloc( p_input->pp_selected_es,
p_input->i_selected_es_number
p_input->stream.i_selected_es_number++;
p_input->stream.pp_selected_es = realloc(
p_input->stream.pp_selected_es,
p_input->stream.i_selected_es_number
* sizeof(es_descriptor_t *) );
p_input->pp_selected_es[p_input->i_selected_es_number - 1] = p_es;
p_input->stream.pp_selected_es[p_input->stream.i_selected_es_number - 1]
= p_es;
}
return( 0 );
}
......@@ -2,7 +2,7 @@
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: mpeg_system.c,v 1.13 2000/12/21 13:54:15 massiot Exp $
* $Id: mpeg_system.c,v 1.14 2000/12/21 19:24:27 massiot Exp $
*
* Authors:
*
......@@ -673,11 +673,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
stream_ps_data_t * p_demux =
(stream_ps_data_t *)p_input->stream.p_demux_data;
intf_Msg("input info: Your stream contains Program Stream Map information");
intf_Msg("input info: Please send a mail to <massiot@via.ecp.fr>");
#if 0
if( !p_demux->b_is_PSM_complete )
{
byte_t * p_byte;
byte_t * p_end;
int i_es = 0;
intf_DbgMsg( "Building PSM" );
if( p_data->p_payload_start + 10 > p_data->p_payload_end )
......@@ -710,34 +713,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
/* 4 == minimum useful size of a section */
while( p_byte + 4 <= p_end )
{
#if 0
p_input->p_es[i_es].i_id
= p_input->p_es[i_es].i_stream_id
= p_byte[1];
p_input->p_es[i_es].i_type = p_byte[0];
p_input->p_es[i_es].p_pgrm = p_input->stream.pp_programs[0];
p_input->p_es[i_es].p_pes = NULL;
p_byte += 4 + U16_AT(&p_byte[2]);
#ifdef AUTO_SPAWN
switch( p_input->p_es[i_es].i_type )
{
case MPEG1_AUDIO_ES: