From b2a296d98c0363f781fe37f6a28678bbaaba0377 Mon Sep 17 00:00:00 2001 From: van Date: Sat, 29 Nov 2008 20:06:26 +0000 Subject: Don't allow multiple decodes of the same ffmpeg audio stream. Because ffmpeg mixes stream reader state with decoder state we only have one decoder instance for the streamso multiple decode requests will garble the audio and/or cause an abort. (Since the Universal preset specifies AC-3 passthru, using it on non-ac3 audio caused a second decode of the first audio track to be requested which triggered this bug and resulted in lots of aborts for wmv & avi conversions.) git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1969 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- libhb/work.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'libhb') diff --git a/libhb/work.c b/libhb/work.c index 2538f41ff..0d57dd4ff 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -7,6 +7,7 @@ #include "hb.h" #include "a52dec/a52.h" #include "dca.h" +#include "libavformat/avformat.h" typedef struct { @@ -113,7 +114,7 @@ hb_work_object_t * hb_codec_encoder( int codec ) * Displays job parameters in the debug log. * @param job Handle work hb_job_t. */ -hb_display_job_info( hb_job_t * job ) +void hb_display_job_info( hb_job_t * job ) { hb_title_t * title = job->title; hb_audio_t * audio; @@ -524,9 +525,14 @@ static void do_job( hb_job_t * job, int cpu_count ) if( !job->indepth_scan ) { - /* if we are doing passthru, and the input codec is not the same as the output - * codec, then remove this audio from the job */ - /* otherwise, Bad Things will happen */ + // if we are doing passthru, and the input codec is not the same as the output + // codec, then remove this audio from the job. If we're not doing passthru and + // the input codec is the 'internal' ffmpeg codec, make sure that only one + // audio references that audio stream since the codec context is specific to + // the audio id & multiple copies of the same stream will garble the audio + // or cause aborts. + uint8_t aud_id_uses[MAX_STREAMS]; + memset( aud_id_uses, 0, sizeof(aud_id_uses) ); for( i = 0; i < hb_list_count( title->list_audio ); ) { audio = hb_list_item( title->list_audio, i ); @@ -539,6 +545,18 @@ static void do_job( hb_job_t * job, int cpu_count ) free( audio ); continue; } + if ( audio->config.in.codec == HB_ACODEC_FFMPEG ) + { + if ( aud_id_uses[audio->id] ) + { + hb_log( "Multiple decodes of audio id %d, removing track %d", + audio->id, audio->config.out.track ); + hb_list_rem( title->list_audio, audio ); + free( audio ); + continue; + } + ++aud_id_uses[audio->id]; + } /* Adjust output track number, in case we removed one. * Output tracks sadly still need to be in sequential order. */ -- cgit v1.2.3