1
mirror of https://code.videolan.org/videolan/vlc synced 2024-09-04 09:11:33 +02:00

* Fixed a few crashes due to race conditions in the decoder spawning.

* Removed unused code here and there.
This commit is contained in:
Sam Hocevar 2001-11-15 17:39:13 +00:00
parent 63eddb9ecc
commit 4a0dae0183
10 changed files with 157 additions and 169 deletions

View File

@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.38 2001/11/15 16:15:59 massiot Exp $
* $Id: input_ext-dec.h,v 1.39 2001/11/15 17:39:12 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
@ -530,11 +530,5 @@ typedef struct decoder_config_s
void (* pf_bitstream_callback)( struct bit_stream_s *,
boolean_t ),
void * );
/* Decoder thread */
vlc_thread_t thread_id;
/* Plugin/Builtin properties */
struct module_s * p_dec_module;
} decoder_config_t;

View File

@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.47 2001/11/13 12:09:17 henri Exp $
* $Id: input_ext-intf.h,v 1.48 2001/11/15 17:39:12 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
@ -76,7 +76,10 @@ typedef struct es_descriptor_s
count_t c_packets; /* total packets read */
count_t c_invalid_packets; /* invalid packets read */
struct decoder_config_s * p_dec_config;
/* Module properties */
struct module_s * p_module;
struct decoder_config_s * p_config;
} es_descriptor_t;
/* Special PID values - note that the PID is only on 13 bits, and that values

View File

@ -3,7 +3,7 @@
* but exported to plug-ins
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: input_ext-plugins.h,v 1.4 2001/11/13 12:09:17 henri Exp $
* $Id: input_ext-plugins.h,v 1.5 2001/11/15 17:39:12 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
@ -69,7 +69,8 @@ int input_UnselectES( struct input_thread_s *, struct es_descriptor_s * );
* Prototypes from input_dec.c
*****************************************************************************/
//decoder_capabilities_s * input_ProbeDecoder( void );
vlc_thread_t input_RunDecoder( void * );
vlc_thread_t input_RunDecoder( struct input_thread_s *,
struct es_descriptor_s * );
void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * );
void input_DecodePES ( struct decoder_fifo_s *, struct pes_packet_s * );
void input_EscapeDiscontinuity( struct input_thread_s *,

View File

@ -2,7 +2,7 @@
* ac3_adec.c: ac3 decoder module main file
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_adec.c,v 1.2 2001/11/13 18:10:38 sam Exp $
* $Id: ac3_adec.c,v 1.3 2001/11/15 17:39:12 sam Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
@ -133,9 +133,8 @@ static int ac3_adec_Run ( decoder_config_t * p_config )
if( p_ac3thread == NULL )
{
intf_ErrMsg ( "ac3dec error: not enough memory "
intf_ErrMsg ( "ac3_adec error: not enough memory "
"for ac3_adec_Run() to allocate p_ac3thread" );
free( p_ac3thread->p_config );
return( -1 );
}
@ -145,8 +144,7 @@ static int ac3_adec_Run ( decoder_config_t * p_config )
p_ac3thread->p_config = p_config;
if( ac3_adec_Init( p_ac3thread ) )
{
intf_ErrMsg( "ac3_adec error : could not initialize thread" );
free( p_ac3thread->p_config );
intf_ErrMsg( "ac3_adec error: could not initialize thread" );
free( p_ac3thread );
return( -1 );
}
@ -228,7 +226,6 @@ static int ac3_adec_Run ( decoder_config_t * p_config )
/* End of the ac3 decoder thread */
ac3_adec_EndThread (p_ac3thread);
free( p_ac3thread->p_config );
free( p_ac3thread );
return( 0 );
@ -244,7 +241,7 @@ static int ac3_adec_Init( ac3dec_thread_t * p_ac3thread )
* Thread properties
*/
p_ac3thread->p_fifo = p_ac3thread->p_config->p_decoder_fifo;
p_ac3thread->ac3_decoder = memalign(16, sizeof(ac3dec_t));
p_ac3thread->ac3_decoder = memalign( 16, sizeof(ac3dec_t) );
/*
* Choose the best downmix module
@ -367,8 +364,13 @@ static int ac3_adec_Init( ac3dec_thread_t * p_ac3thread )
#else
free( p_ac3thread->ac3_decoder->samples );
#endif
module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module );
module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
free( p_ac3thread->ac3_decoder->imdct );
free( p_ac3thread->ac3_decoder );
return( -1 );
}
@ -426,11 +428,7 @@ static void ac3_adec_EndThread (ac3dec_thread_t * p_ac3thread)
vlc_mutex_unlock (&(p_ac3thread->p_aout_fifo->data_lock));
}
/* Unlock the modules */
module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module );
/* Destroy descriptor */
/* Free allocated structures */
#define IMDCT p_ac3thread->ac3_decoder->imdct
free( IMDCT->w_1 );
free( IMDCT->w_64 );
@ -454,6 +452,12 @@ static void ac3_adec_EndThread (ac3dec_thread_t * p_ac3thread)
#else
free( p_ac3thread->ac3_decoder->samples );
#endif
/* Unlock the modules */
module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module );
/* Free what's left of the decoder */
free( p_ac3thread->ac3_decoder->imdct );
free( p_ac3thread->ac3_decoder );

View File

@ -2,7 +2,7 @@
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ac3_spdif.c,v 1.2 2001/11/14 03:38:11 stef Exp $
* $Id: ac3_spdif.c,v 1.3 2001/11/15 17:39:12 sam Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
@ -352,7 +352,6 @@ static void ac3_spdif_EndThread( ac3_spdif_thread_t * p_spdif )
}
/* Destroy descriptor */
free( p_spdif->p_config );
free( p_spdif->p_ac3 );
free( p_spdif );

View File

@ -2,7 +2,7 @@
* mpeg_adec.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: mpeg_adec.c,v 1.1 2001/11/13 12:09:18 henri Exp $
* $Id: mpeg_adec.c,v 1.2 2001/11/15 17:39:12 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
@ -274,7 +274,6 @@ static void adec_EndThread ( adec_thread_t *p_adec )
vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
}
/* Destroy descriptor */
free( p_adec->p_config );
free( p_adec );
intf_DbgMsg ("adec debug: audio decoder thread %p destroyed", p_adec);

View File

@ -2,7 +2,7 @@
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_parser.c,v 1.1 2001/11/13 12:09:18 henri Exp $
* $Id: video_parser.c,v 1.2 2001/11/15 17:39:12 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
@ -410,8 +410,6 @@ static void mpeg_vdec_EndThread( vpar_thread_t *p_vpar )
vpar_EndPool( p_vpar );
free( p_vpar->p_config );
module_Unneed( p_vpar->p_idct_module );
module_Unneed( p_vpar->p_motion_module );

View File

@ -2,7 +2,7 @@
* spu_decoder.c : spu decoder thread
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: spu_decoder.c,v 1.2 2001/11/13 15:08:25 sam Exp $
* $Id: spu_decoder.c,v 1.3 2001/11/15 17:39:13 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
@ -265,7 +265,6 @@ static void spu_dec_ErrorThread( spudec_thread_t *p_spudec )
*****************************************************************************/
static void spu_dec_EndThread( spudec_thread_t *p_spudec )
{
free( p_spudec->p_config );
free( p_spudec );
}

View File

@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_dec.c,v 1.14 2001/11/13 12:09:18 henri Exp $
* $Id: input_dec.c,v 1.15 2001/11/15 17:39:13 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
@ -43,40 +43,57 @@
#include "modules.h"
static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
es_descriptor_t * p_es );
static void DeleteDecoderConfig( decoder_config_t * p_config );
/*****************************************************************************
* input_RunDecoder: spawns a new decoder thread
*****************************************************************************/
vlc_thread_t input_RunDecoder( void * p_data )
vlc_thread_t input_RunDecoder( input_thread_t * p_input,
es_descriptor_t * p_es )
{
decoder_config_t * p_config;
probedata_t probedata;
probedata_t probedata;
vlc_thread_t thread_id;
p_config = (decoder_config_t *)p_data;
probedata.i_type = p_config->i_type;
p_config->p_dec_module = module_Need(
MODULE_CAPABILITY_DEC, &probedata);
if( p_config->p_dec_module == NULL )
/* Get a suitable module */
probedata.i_type = p_es->i_type;
p_es->p_module = module_Need( MODULE_CAPABILITY_DEC, &probedata );
if( p_es->p_module == NULL )
{
intf_ErrMsg( "dec error: no suitable dec module for type 0x%x",
p_config->i_type );
intf_ErrMsg( "input error: no suitable decoder module for type 0x%x",
p_es->i_type );
return( 0 );
}
/* Create the decoder configuration structure */
p_es->p_config = CreateDecoderConfig( p_input, p_es );
if( p_es->p_config == NULL )
{
intf_ErrMsg( "input error: could not create decoder config" );
module_Unneed( p_es->p_module );
return( 0 );
}
/* Spawn the decoder thread */
if ( vlc_thread_create(&p_config->thread_id,
"decoder", (vlc_thread_func_t)p_config->p_dec_module->
p_functions->dec.functions.dec.pf_RunThread, (void *)p_config) )
if ( vlc_thread_create( &thread_id, "decoder",
(vlc_thread_func_t)p_es->p_module->
p_functions->dec.functions.dec.pf_RunThread,
(void *)p_es->p_config) )
{
intf_ErrMsg( "dec error: can't spawn decoder thread \"%s\"",
p_config->p_dec_module->psz_name );
intf_ErrMsg( "input error: can't spawn decoder thread \"%s\"",
p_es->p_module->psz_name );
free( p_es->p_config );
module_Unneed( p_es->p_module );
return( 0 );
}
intf_DbgMsg( "dec debug: decoder \"%s\"thread (%p) created",
p_config->p_dec_module->psz_name, p_dec );
intf_DbgMsg( "input debug: decoder \"%s\"thread created",
p_es->p_module->psz_name );
return p_config->thread_id;
return thread_id;
}
@ -108,24 +125,11 @@ void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
vlc_thread_join( p_es->thread_id );
// vlc_mutex_lock( &p_input->stream.stream_lock );
/* Unneed module*/
module_Unneed( p_es->p_dec_config->p_dec_module );
/* Delete decoder configuration */
DeleteDecoderConfig( p_es->p_config );
/* Freeing all packets still in the decoder fifo. */
while( !DECODER_FIFO_ISEMPTY( *p_es->p_decoder_fifo ) )
{
p_es->p_decoder_fifo->pf_delete_pes(
p_es->p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_es->p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_es->p_decoder_fifo );
}
/* Destroy the lock and cond */
vlc_cond_destroy( &p_es->p_decoder_fifo->data_wait );
vlc_mutex_destroy( &p_es->p_decoder_fifo->data_lock );
free( p_es->p_decoder_fifo );
p_es->p_decoder_fifo = NULL;
/* Unneed module */
module_Unneed( p_es->p_module );
}
/*****************************************************************************
@ -203,3 +207,86 @@ void input_EscapeAudioDiscontinuity( input_thread_t * p_input )
}
}
/*****************************************************************************
* CreateDecoderConfig: create a decoder_config_t
*****************************************************************************/
static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
es_descriptor_t * p_es )
{
decoder_config_t * p_config;
p_config = (decoder_config_t *)malloc( sizeof(decoder_config_t) );
if( p_config == NULL )
{
intf_ErrMsg( "Unable to allocate memory in CreateDecoderConfig" );
return NULL;
}
/* Decoder FIFO */
if( (p_config->p_decoder_fifo =
(decoder_fifo_t *)malloc( sizeof(decoder_fifo_t) )) == NULL )
{
intf_ErrMsg( "Out of memory" );
free( p_config );
return NULL;
}
/* Select a new ES */
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 *) );
if( p_input->stream.pp_selected_es == NULL )
{
intf_ErrMsg( "Unable to realloc memory" );
free( p_config->p_decoder_fifo );
free( p_config );
return NULL;
}
p_input->stream.pp_selected_es[p_input->stream.i_selected_es_number - 1]
= p_es;
/* Initialize the p_config structure */
vlc_mutex_init(&p_config->p_decoder_fifo->data_lock);
vlc_cond_init(&p_config->p_decoder_fifo->data_wait);
p_es->p_decoder_fifo = p_config->p_decoder_fifo;
p_config->pf_init_bit_stream = p_input->pf_init_bit_stream;
p_config->i_id = p_es->i_id;
p_config->i_type = p_es->i_type;
p_config->p_stream_ctrl = &p_input->stream.control;
p_config->p_decoder_fifo->i_start = p_config->p_decoder_fifo->i_end = 0;
p_config->p_decoder_fifo->b_die = p_config->p_decoder_fifo->b_error = 0;
p_config->p_decoder_fifo->p_packets_mgt = p_input->p_method_data;
p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes;
return p_config;
}
/*****************************************************************************
* DeleteDecoderConfig: create a decoder_config_t
*****************************************************************************/
static void DeleteDecoderConfig( decoder_config_t * p_config )
{
/* Free all packets still in the decoder fifo. */
while( !DECODER_FIFO_ISEMPTY( *p_config->p_decoder_fifo ) )
{
p_config->p_decoder_fifo->pf_delete_pes(
p_config->p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_config->p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_config->p_decoder_fifo );
}
/* Destroy the lock and cond */
vlc_cond_destroy( &p_config->p_decoder_fifo->data_wait );
vlc_mutex_destroy( &p_config->p_decoder_fifo->data_lock );
free( p_config->p_decoder_fifo );
p_config->p_decoder_fifo = NULL;
free( p_config );
}

View File

@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_programs.c,v 1.64 2001/11/13 12:09:18 henri Exp $
* $Id: input_programs.c,v 1.65 2001/11/15 17:39:13 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
@ -506,95 +506,14 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
}
/*****************************************************************************
* InitDecConfig: initializes a decoder_config_t
*****************************************************************************/
static int InitDecConfig( input_thread_t * p_input, es_descriptor_t * p_es,
decoder_config_t * p_config )
{
p_config->i_id = p_es->i_id;
p_config->i_type = p_es->i_type;
p_config->p_stream_ctrl =
&p_input->stream.control;
/* Decoder FIFO */
if( (p_config->p_decoder_fifo =
(decoder_fifo_t *)malloc( sizeof(decoder_fifo_t) )) == NULL )
{
intf_ErrMsg( "Out of memory" );
return( -1 );
}
vlc_mutex_init(&p_config->p_decoder_fifo->data_lock);
vlc_cond_init(&p_config->p_decoder_fifo->data_wait);
p_config->p_decoder_fifo->i_start = p_config->p_decoder_fifo->i_end = 0;
p_config->p_decoder_fifo->b_die = p_config->p_decoder_fifo->b_error = 0;
p_config->p_decoder_fifo->p_packets_mgt = p_input->p_method_data;
p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes;
p_es->p_decoder_fifo = p_config->p_decoder_fifo;
p_config->pf_init_bit_stream = p_input->pf_init_bit_stream;
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 *) );
if( p_input->stream.pp_selected_es == NULL )
{
intf_ErrMsg( "Unable to realloc memory in input_SelectES" );
return(-1);
}
p_input->stream.pp_selected_es[p_input->stream.i_selected_es_number - 1]
= p_es;
return( 0 );
}
/*****************************************************************************
* GetDecConfig: returns a valid decoder_config_t
*****************************************************************************/
static decoder_config_t * GetDecConfig( input_thread_t * p_input,
es_descriptor_t * p_es )
{
decoder_config_t * p_config;
p_config = (decoder_config_t *)malloc( sizeof(decoder_config_t) );
if( p_config == NULL )
{
intf_ErrMsg( "Unable to allocate memory in GetDecConfig" );
return( NULL );
}
if( InitDecConfig( p_input, p_es, p_config ) == -1 )
{
free( p_config );
return( NULL );
}
return( p_config );
}
/*****************************************************************************
* input_SelectES: selects an ES and spawns the associated decoder
*****************************************************************************
* Remember we are still supposed to have stream_lock when entering this
* function ?
*****************************************************************************/
/* FIXME */
vlc_thread_t adec_CreateThread( void * );
vlc_thread_t ac3dec_CreateThread( void * );
vlc_thread_t ac3spdif_CreateThread( void * );
vlc_thread_t spdif_CreateThread( void * );
vlc_thread_t vpar_CreateThread( void * );
vlc_thread_t spudec_CreateThread( void * );
vlc_thread_t lpcmdec_CreateThread( void * );
int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
{
/* FIXME ! */
void * p_config;
if( p_es == NULL )
{
intf_ErrMsg( "Nothing to do in input_SelectES" );
@ -619,20 +538,13 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
case LPCM_AUDIO_ES:
if( p_main->b_audio )
{
decoder_config_t * p_dec_config;
p_dec_config = GetDecConfig( p_input, p_es );
p_config =(void *)p_dec_config;
p_dec_config->i_type = p_es->i_type;
/* This kludge should be removed */
p_main->b_ac3 = ( p_es->i_type == AC3_AUDIO_ES );
/* Useful to Unned decoder module */
p_es->p_dec_config = p_dec_config;
/* Release the lock, not to block the input thread during
* the creation of the thread. */
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_es->thread_id = input_RunDecoder( p_config );
p_es->thread_id = input_RunDecoder( p_input, p_es );
vlc_mutex_lock( &p_input->stream.stream_lock );
}
break;
@ -642,18 +554,10 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
case DVD_SPU_ES:
if( p_main->b_video )
{
decoder_config_t * p_dec_config;
p_dec_config = GetDecConfig( p_input, p_es );
p_config = (void *)p_dec_config;
p_dec_config->i_type = p_es->i_type;
/* Useful to Unned decoder module */
p_es->p_dec_config = p_dec_config;
/* Release the lock, not to block the input thread during
* the creation of the thread. */
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_es->thread_id = input_RunDecoder( p_config );
p_es->thread_id = input_RunDecoder( p_input, p_es );
vlc_mutex_lock( &p_input->stream.stream_lock );
}
break;