[vlc-commits] transcode/audio: fix dec->fmt_out thread safety
Thomas Guillem
git at videolan.org
Wed Jan 10 19:32:23 CET 2018
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Wed Jan 10 19:22:45 2018 +0100| [0b80b6d1b8ca8f15d096af43490faaa600e0a837] | committer: Thomas Guillem
transcode/audio: fix dec->fmt_out thread safety
Since the decoder fmt_out can be updated from any threads with async decoders.
PS: As audio output blocks are not linked with a audio_format_t, it's still not
possible to know the real fmt of an audio output block if the format changed.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0b80b6d1b8ca8f15d096af43490faaa600e0a837
---
modules/stream_out/transcode/audio.c | 97 ++++++++++++++++++++------------
modules/stream_out/transcode/transcode.h | 1 +
2 files changed, 62 insertions(+), 36 deletions(-)
diff --git a/modules/stream_out/transcode/audio.c b/modules/stream_out/transcode/audio.c
index 2aa4a8b456..e304a16b96 100644
--- a/modules/stream_out/transcode/audio.c
+++ b/modules/stream_out/transcode/audio.c
@@ -57,12 +57,20 @@ static const int pi_channels_maps[9] =
static int audio_update_format( decoder_t *p_dec )
{
+ sout_stream_id_sys_t *id = p_dec->p_queue_ctx;
+
+ p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
aout_FormatPrepare( &p_dec->fmt_out.audio );
+
+ vlc_mutex_lock(&id->fifo.lock);
+ id->audio_dec_out = p_dec->fmt_out.audio;
+ vlc_mutex_unlock(&id->fifo.lock);
+
return ( p_dec->fmt_out.audio.i_bitspersample > 0 ) ? 0 : -1;
}
static int transcode_audio_initialize_filters( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
- sout_stream_sys_t *p_sys, audio_sample_format_t *fmt_last )
+ sout_stream_sys_t *p_sys )
{
/* Load user specified audio filters */
/* XXX: These variable names come kinda out of nowhere... */
@@ -70,7 +78,7 @@ static int transcode_audio_initialize_filters( sout_stream_t *p_stream, sout_str
var_Create( p_stream, "audio-filter", VLC_VAR_STRING );
if( p_sys->psz_af )
var_SetString( p_stream, "audio-filter", p_sys->psz_af );
- id->p_af_chain = aout_FiltersNew( p_stream, fmt_last,
+ id->p_af_chain = aout_FiltersNew( p_stream, &id->audio_dec_out,
&id->p_encoder->fmt_in.audio, NULL, NULL );
var_Destroy( p_stream, "audio-filter" );
var_Destroy( p_stream, "audio-time-stretch" );
@@ -83,18 +91,33 @@ static int transcode_audio_initialize_filters( sout_stream_t *p_stream, sout_str
id->p_decoder->p_module = NULL;
return VLC_EGENERIC;
}
- id->fmt_audio.i_rate = fmt_last->i_rate;
- id->fmt_audio.i_physical_channels = fmt_last->i_physical_channels;
+ id->fmt_audio.i_rate = id->audio_dec_out.i_rate;
+ id->fmt_audio.i_physical_channels = id->audio_dec_out.i_physical_channels;
return VLC_SUCCESS;
}
static int transcode_audio_initialize_encoder( sout_stream_id_sys_t *id, sout_stream_t *p_stream )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
+
+ /* Complete destination format */
+ id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
+ id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
+ p_sys->i_sample_rate : id->audio_dec_out.i_rate;
+ id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
+ id->p_encoder->fmt_out.audio.i_bitspersample = id->audio_dec_out.i_bitspersample;
+ id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
+ p_sys->i_channels : id->audio_dec_out.i_channels;
+ assert(id->p_encoder->fmt_out.audio.i_channels > 0);
+
+ id->p_encoder->fmt_in.audio.i_physical_channels =
+ id->p_encoder->fmt_out.audio.i_physical_channels =
+ pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
+
/* Initialization of encoder format structures */
es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
- id->p_decoder->fmt_out.i_codec );
- id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
+ id->audio_dec_out.i_format );
+ id->p_encoder->fmt_in.audio.i_format = id->audio_dec_out.i_format;
id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
id->p_encoder->fmt_in.audio.i_physical_channels =
id->p_encoder->fmt_out.audio.i_physical_channels;
@@ -175,18 +198,31 @@ static int transcode_audio_new( sout_stream_t *p_stream,
msg_Err( p_stream, "cannot find audio decoder" );
return VLC_EGENERIC;
}
- /* decoders don't set audio.i_format, but audio filters use it */
- id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec;
- aout_FormatPrepare( &id->p_decoder->fmt_out.audio );
+
+ vlc_mutex_lock(&id->fifo.lock);
+ id->audio_dec_out = id->p_decoder->fmt_out.audio;
+ id->audio_dec_out.i_format = id->p_decoder->fmt_out.i_codec;
+ if (id->audio_dec_out.i_rate == 0)
+ id->audio_dec_out.i_rate = id->p_decoder->fmt_in.audio.i_rate;
+ if (id->audio_dec_out.i_physical_channels == 0)
+ id->audio_dec_out.i_physical_channels = id->p_decoder->fmt_in.audio.i_physical_channels;
+ aout_FormatPrepare( &id->audio_dec_out );
+
/*
* Open encoder
*/
if( transcode_audio_initialize_encoder( id, p_stream ) == VLC_EGENERIC )
+ {
+ vlc_mutex_unlock(&id->fifo.lock);
return VLC_EGENERIC;
+ }
- if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys,
- &id->p_decoder->fmt_out.audio ) != VLC_SUCCESS ) )
+ if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys ) != VLC_SUCCESS ) )
+ {
+ vlc_mutex_unlock(&id->fifo.lock);
return VLC_EGENERIC;
+ }
+ vlc_mutex_unlock(&id->fifo.lock);
return VLC_SUCCESS;
}
@@ -240,54 +276,43 @@ int transcode_audio_process( sout_stream_t *p_stream,
continue;
}
+ vlc_mutex_lock(&id->fifo.lock);
if( unlikely( !id->p_encoder->p_module ) )
{
- /* Complete destination format */
- id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
- id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
- p_sys->i_sample_rate : id->p_decoder->fmt_out.audio.i_rate;
- id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
- id->p_encoder->fmt_out.audio.i_bitspersample =
- id->p_decoder->fmt_out.audio.i_bitspersample;
- id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
- p_sys->i_channels : id->p_decoder->fmt_out.audio.i_channels;
-
- id->p_encoder->fmt_in.audio.i_physical_channels =
- id->p_encoder->fmt_out.audio.i_physical_channels =
- pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
-
if( transcode_audio_initialize_encoder( id, p_stream ) )
{
msg_Err( p_stream, "cannot create audio chain" );
+ vlc_mutex_unlock(&id->fifo.lock);
goto error;
}
- if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys,
- &id->p_decoder->fmt_out.audio ) != VLC_SUCCESS ) )
+ if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys ) != VLC_SUCCESS ) )
+ {
+ vlc_mutex_unlock(&id->fifo.lock);
goto error;
- date_Init( &id->next_input_pts, id->p_decoder->fmt_out.audio.i_rate, 1 );
+ }
+ date_Init( &id->next_input_pts, id->audio_dec_out.i_rate, 1 );
date_Set( &id->next_input_pts, p_audio_buf->i_pts );
}
/* Check if audio format has changed, and filters need reinit */
- if( unlikely( ( id->p_decoder->fmt_out.audio.i_rate != id->fmt_audio.i_rate ) ||
- ( id->p_decoder->fmt_out.audio.i_physical_channels != id->fmt_audio.i_physical_channels ) ) )
+ if( unlikely( ( id->audio_dec_out.i_rate != id->fmt_audio.i_rate ) ||
+ ( id->audio_dec_out.i_physical_channels != id->fmt_audio.i_physical_channels ) ) )
{
msg_Info( p_stream, "Audio changed, trying to reinitialize filters" );
if( id->p_af_chain != NULL )
aout_FiltersDelete( (vlc_object_t *)NULL, id->p_af_chain );
- /* decoders don't set audio.i_format, but audio filters use it */
- id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec;
- aout_FormatPrepare( &id->p_decoder->fmt_out.audio );
-
- if( transcode_audio_initialize_filters( p_stream, id, p_sys,
- &id->p_decoder->fmt_out.audio ) != VLC_SUCCESS )
+ if( transcode_audio_initialize_filters( p_stream, id, p_sys ) != VLC_SUCCESS )
+ {
+ vlc_mutex_unlock(&id->fifo.lock);
goto error;
+ }
/* Set next_input_pts to run with new samplerate */
date_Init( &id->next_input_pts, id->fmt_audio.i_rate, 1 );
date_Set( &id->next_input_pts, p_audio_buf->i_pts );
}
+ vlc_mutex_unlock(&id->fifo.lock);
if( p_sys->b_master_sync )
{
diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h
index 0009b18dd1..8ab9b2111d 100644
--- a/modules/stream_out/transcode/transcode.h
+++ b/modules/stream_out/transcode/transcode.h
@@ -113,6 +113,7 @@ struct sout_stream_id_sys_t
{
struct aout_filters *p_af_chain; /**< Audio filters */
audio_format_t fmt_audio;
+ audio_format_t audio_dec_out; /* only rw from pf_aout_format_update() */
};
};
More information about the vlc-commits
mailing list