summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2010-04-24 17:36:07 +0000
committerjstebbins <[email protected]>2010-04-24 17:36:07 +0000
commit8d7bf485002a1d9358254632f13be1f392d2ba81 (patch)
tree362e54689f86d0df32a65b8254f132ffe71e1780
parenta5687f98414788475d8ba26ca6db176b0b2c5a4a (diff)
add test to ensure that ffmpeg's reported audio layout agrees with channel count
a crash report from a user leads me to believe ffmpeg is giving us a channel layout that has a different number of channels than the channel count it tells us. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3260 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/hb.c96
-rw-r--r--libhb/stream.c10
2 files changed, 80 insertions, 26 deletions
diff --git a/libhb/hb.c b/libhb/hb.c
index 30fce039c..1a725659e 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -86,47 +86,95 @@ int hb_avcodec_close(AVCodecContext *avctx)
int hb_ff_layout_xlat(int64_t ff_channel_layout, int channels)
{
+ int hb_layout;
+
switch (ff_channel_layout)
{
case CH_LAYOUT_MONO:
- return HB_INPUT_CH_LAYOUT_MONO;
+ hb_layout = HB_INPUT_CH_LAYOUT_MONO;
+ break;
case CH_LAYOUT_STEREO:
- return HB_INPUT_CH_LAYOUT_STEREO;
+ hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ break;
case CH_LAYOUT_SURROUND:
- return HB_INPUT_CH_LAYOUT_3F;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F;
+ break;
case CH_LAYOUT_4POINT0:
- return HB_INPUT_CH_LAYOUT_3F1R;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
+ break;
case CH_LAYOUT_2_2:
- return HB_INPUT_CH_LAYOUT_2F2R;
+ hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
+ break;
case CH_LAYOUT_QUAD:
- return HB_INPUT_CH_LAYOUT_2F2R;
+ hb_layout = HB_INPUT_CH_LAYOUT_2F2R;
+ break;
case CH_LAYOUT_5POINT0:
- // ffmpeg like to neglect to signal LFE
- if (channels == 6)
- return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
- return HB_INPUT_CH_LAYOUT_3F2R;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
+ break;
case CH_LAYOUT_5POINT1:
- return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ break;
case CH_LAYOUT_5POINT0_BACK:
- // ffmpeg like to neglect to signal LFE
- if (channels == 6)
- return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
- return HB_INPUT_CH_LAYOUT_3F2R;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
+ break;
case CH_LAYOUT_5POINT1_BACK:
- return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ break;
case CH_LAYOUT_7POINT0:
- // ffmpeg like to neglect to signal LFE
- if (channels == 8)
- return HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
- return HB_INPUT_CH_LAYOUT_3F4R;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
+ break;
case CH_LAYOUT_7POINT1:
- return HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ break;
case CH_LAYOUT_STEREO_DOWNMIX:
- return HB_INPUT_CH_LAYOUT_STEREO;
+ hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ break;
+ default:
+ hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ break;
+ }
+ // Now make sure the chosen layout agrees with the number of channels
+ // ffmpeg tells us there are. It seems ffmpeg is sometimes confused
+ // about this. So we will make a best guess based on the number
+ // of channels.
+ int chans = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( hb_layout );
+ if ( chans == channels )
+ {
+ return hb_layout;
+ }
+ hb_log( "Channels reported by ffmpeg (%d) != computed layout channels (%d).\n", channels, chans );
+ switch (channels)
+ {
+ case 1:
+ hb_layout = HB_INPUT_CH_LAYOUT_MONO;
+ break;
+ case 2:
+ hb_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ break;
+ case 3:
+ hb_layout = HB_INPUT_CH_LAYOUT_3F;
+ break;
+ case 4:
+ hb_layout = HB_INPUT_CH_LAYOUT_3F1R;
+ break;
+ case 5:
+ hb_layout = HB_INPUT_CH_LAYOUT_3F2R;
+ break;
+ case 6:
+ hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ break;
+ case 7:
+ hb_layout = HB_INPUT_CH_LAYOUT_3F4R;
+ break;
+ case 8:
+ hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE;
+ break;
default:
- return HB_INPUT_CH_LAYOUT_STEREO;
+ hb_log("Unsupported number of audio channels (%d).\n", channels);
+ hb_layout = 0;
+ break;
}
- return HB_INPUT_CH_LAYOUT_STEREO;
+ return hb_layout;
}
/**
diff --git a/libhb/stream.c b/libhb/stream.c
index f75400f45..d2d2a4a47 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -2783,10 +2783,17 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
{
AVStream *st = stream->ffmpeg_ic->streams[id];
AVCodecContext *codec = st->codec;
+ int layout;
// scan will ignore any audio without a bitrate. Since we've already
// typed the audio in order to determine its codec we set up the audio
// paramters here.
+ layout = hb_ff_layout_xlat( codec->channel_layout, codec->channels );
+ if ( !layout )
+ {
+ // Unsupported layout
+ return;
+ }
if ( codec->bit_rate || codec->sample_rate )
{
hb_audio_t *audio = calloc( 1, sizeof(*audio) );;
@@ -2807,8 +2814,7 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
audio->config.in.bitrate = codec->bit_rate? codec->bit_rate : 1;
audio->config.in.samplerate = codec->sample_rate;
- audio->config.in.channel_layout =
- hb_ff_layout_xlat(codec->channel_layout, codec->channels);
+ audio->config.in.channel_layout = layout;
}
set_audio_description( audio, lang_for_code2( st->language ) );