From 98bd3d5d78a7657807f578331de9d72f868a2cee Mon Sep 17 00:00:00 2001 From: Gildas Bazin Date: Thu, 30 Jan 2003 16:36:04 +0000 Subject: [PATCH] * modules/codec/spudec/spudec.c, modules/codec/spudec/text.c: fixed the race condition between spudec and vout. This patch may not be all that nice because it does a lot of vlc_object_find() but it is the only solution I've been able to come-up with. Oh and I didn't fix the memory leak caused by the font when using text subtitles. If the vout changes while the spudec is running then we don't unload this font. --- modules/codec/spudec/spudec.c | 108 ++++++++++++++++++++++++++-------- modules/codec/spudec/text.c | 3 +- 2 files changed, 83 insertions(+), 28 deletions(-) diff --git a/modules/codec/spudec/spudec.c b/modules/codec/spudec/spudec.c index 897d6d43ac..404717aca5 100644 --- a/modules/codec/spudec/spudec.c +++ b/modules/codec/spudec/spudec.c @@ -2,7 +2,7 @@ * spudec.c : SPU decoder thread ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: spudec.c,v 1.13 2003/01/28 22:03:21 sam Exp $ + * $Id: spudec.c,v 1.14 2003/01/30 16:36:04 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -40,6 +40,7 @@ static int OpenDecoder ( vlc_object_t * ); static int RunDecoder ( decoder_fifo_t * ); static int InitThread ( spudec_thread_t * ); static void EndThread ( spudec_thread_t * ); +static vout_thread_t *FindVout( spudec_thread_t * ); /***************************************************************************** * Module descriptor. @@ -93,8 +94,9 @@ static int OpenDecoder( vlc_object_t *p_this ) static int RunDecoder( decoder_fifo_t * p_fifo ) { spudec_thread_t * p_spudec; - subtitler_font_t * p_font; + subtitler_font_t * p_font = NULL; char * psz_font; + vout_thread_t * p_vout_backup = NULL; /* Allocate the memory needed to store the thread's structure */ p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) ); @@ -137,28 +139,54 @@ static int RunDecoder( decoder_fifo_t * p_fifo ) if( (psz_font = config_GetPsz( p_fifo, "spudec-font" )) == NULL ) { msg_Err( p_fifo, "no default font selected" ); - p_font = NULL; - p_spudec->p_fifo->b_error; + p_spudec->p_fifo->b_error = VLC_TRUE; } - else #endif + + while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) ) { - p_font = E_(subtitler_LoadFont)( p_spudec->p_vout, psz_font ); - if ( p_font == NULL ) + /* Find/Wait for a video output */ + p_spudec->p_vout = FindVout( p_spudec ); + + if( p_spudec->p_vout ) { - msg_Err( p_fifo, "unable to load font: %s", psz_font ); - p_spudec->p_fifo->b_error; + if( p_spudec->p_vout != p_vout_backup ) + { + /* The vout has changed, we need to reload the fonts */ + p_vout_backup = p_spudec->p_vout; + + p_font = E_(subtitler_LoadFont)( p_spudec->p_vout, + psz_font ); + if( p_font == NULL ) + { + msg_Err( p_fifo, "unable to load font: %s", psz_font ); + p_spudec->p_fifo->b_error = VLC_TRUE; + + vlc_object_release( p_spudec->p_vout ); + break; + } + } + + E_(ParseText)( p_spudec, p_font ); + + vlc_object_release( p_spudec->p_vout ); } } + if( psz_font ) free( psz_font ); - while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) ) + if( p_font ) { - E_(ParseText)( p_spudec, p_font ); - } + /* Find/Wait for a video output */ + p_spudec->p_vout = FindVout( p_spudec ); - if( p_font ) E_(subtitler_UnloadFont)( p_spudec->p_vout, p_font ); + if( p_spudec->p_vout ) + { + E_(subtitler_UnloadFont)( p_spudec->p_vout, p_font ); + vlc_object_release( p_spudec->p_vout ); + } + } } else { @@ -171,7 +199,13 @@ static int RunDecoder( decoder_fifo_t * p_fifo ) continue; } - E_(ParsePacket)( p_spudec ); + /* Find/Wait for a video output */ + p_spudec->p_vout = FindVout( p_spudec ); + if( p_spudec->p_vout ) + { + E_(ParsePacket)( p_spudec ); + vlc_object_release( p_spudec->p_vout ); + } } } @@ -203,22 +237,47 @@ static int RunDecoder( decoder_fifo_t * p_fifo ) *****************************************************************************/ static int InitThread( spudec_thread_t *p_spudec ) { + int i_ret; + + /* Call InitBitstream anyway so p_spudec->bit_stream is in a known + * state before calling CloseBitstream */ + i_ret = InitBitstream( &p_spudec->bit_stream, p_spudec->p_fifo, + NULL, NULL ); + + /* Check for a video output */ + p_spudec->p_vout = FindVout( p_spudec ); + + if( !p_spudec->p_vout ) + { + return -1; + } + + /* It was just a check */ + vlc_object_release( p_spudec->p_vout ); + p_spudec->p_vout = NULL; + + return i_ret; +} + +/***************************************************************************** + * FindVout: Find a vout or wait for one to be created. + *****************************************************************************/ +static vout_thread_t *FindVout( spudec_thread_t *p_spudec ) +{ + vout_thread_t *p_vout = NULL; + /* Find an available video output */ do { if( p_spudec->p_fifo->b_die || p_spudec->p_fifo->b_error ) { - /* Call InitBitstream anyway so p_spudec->bit_stream is in a known - * state before calling CloseBitstream */ - InitBitstream( &p_spudec->bit_stream, p_spudec->p_fifo, - NULL, NULL ); - return -1; + break; } - p_spudec->p_vout = vlc_object_find( p_spudec->p_fifo, VLC_OBJECT_VOUT, - FIND_ANYWHERE ); + p_vout = vlc_object_find( p_spudec->p_fifo, VLC_OBJECT_VOUT, + FIND_ANYWHERE ); - if( p_spudec->p_vout ) + if( p_vout ) { break; } @@ -227,8 +286,7 @@ static int InitThread( spudec_thread_t *p_spudec ) } while( 1 ); - return InitBitstream( &p_spudec->bit_stream, p_spudec->p_fifo, - NULL, NULL ); + return p_vout; } /***************************************************************************** @@ -256,8 +314,6 @@ static void EndThread( spudec_thread_t *p_spudec ) vout_DestroySubPicture( p_spudec->p_vout, p_subpic ); } } - - vlc_object_release( p_spudec->p_vout ); } CloseBitstream( &p_spudec->bit_stream ); diff --git a/modules/codec/spudec/text.c b/modules/codec/spudec/text.c index 07f49a9958..656f4b5e1d 100644 --- a/modules/codec/spudec/text.c +++ b/modules/codec/spudec/text.c @@ -2,7 +2,7 @@ * text.c: text subtitles parser ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: text.c,v 1.3 2002/12/06 16:34:05 sam Exp $ + * $Id: text.c,v 1.4 2003/01/30 16:36:04 gbazin Exp $ * * Authors: Gildas Bazin * @@ -55,7 +55,6 @@ void E_(ParseText)( spudec_thread_t *p_spudec, subtitler_font_t *p_font ) msg_Warn( p_spudec->p_fifo, "subtitle without a date" ); return; } - else /* Check validity of packet data */ if( (p_spudec->bit_stream.p_data->p_payload_end -- 2.39.2