- /* 3F/2R input */
- case HB_INPUT_CH_LAYOUT_3F2R:
- /* if we've requested a mono mixdown, and it is supported, then do the mix */
- /* use dpl2 if not supported */
- if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
- audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
- } else {
- /* check if we have 3F2R input and also have an LFE - i.e. we have a 5.1 source) */
- if (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE) {
- /* we have a 5.1 source */
- /* if we requested 6ch, but our audio format doesn't support it, then mix to DPLII instead */
- if (audio->config.out.mixdown == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {
- audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
+ // Here we try to sanitize the audio input to output mapping.
+ // Constraints are:
+ // 1. only the AC3 & DCA decoder libraries currently support mixdown
+ // 2. the lame encoder library only supports stereo.
+ // So if the encoder is lame we need the output to be stereo (or multichannel
+ // matrixed into stereo like dpl). If the decoder is not AC3 or DCA the
+ // encoder has to handle the input format since we can't do a mixdown.
+#define CAN_MIXDOWN(a) ( a->config.in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA) )
+#define STEREO_ONLY(a) ( a->config.out.codec & HB_ACODEC_LAME )
+
+ switch (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK)
+ {
+ // stereo input or something not handled below
+ default:
+ case HB_INPUT_CH_LAYOUT_STEREO:
+ // mono gets mixed up to stereo & more than stereo gets mixed down
+ if ( STEREO_ONLY( audio ) ||
+ audio->config.out.mixdown > HB_AMIXDOWN_STEREO)
+ {
+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
+ }
+ break;
+
+ // mono input
+ case HB_INPUT_CH_LAYOUT_MONO:
+ if ( STEREO_ONLY( audio ) )
+ {
+ if ( !CAN_MIXDOWN( audio ) )
+ {
+ // XXX we're hosed - we can't mix up & lame can't handle
+ // the input format. The user shouldn't be able to make
+ // this choice. It's too late to do anything about it now
+ // so complain in the log & let things abort in lame.
+ hb_log( "ERROR - can't use lame mp3 audio output with "
+ "mono audio stream %x - output will be messed up",
+ audio->id );
+ }
+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
+ }
+ else
+ {
+ // everything else passes through
+ audio->config.out.mixdown = HB_AMIXDOWN_MONO;
+ }
+ break;
+
+ // dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input
+ // the A52 flags don't allow for a way to distinguish between DPL1 and
+ // DPL2 on a DVD so we always assume a DPL1 source for A52_DOLBY.
+ case HB_INPUT_CH_LAYOUT_DOLBY:
+ if ( STEREO_ONLY( audio ) || !CAN_MIXDOWN( audio ) ||
+ audio->config.out.mixdown > HB_AMIXDOWN_DOLBY )
+ {
+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
+ }
+ break;
+
+ // 4 channel discrete
+ case HB_INPUT_CH_LAYOUT_2F2R:
+ case HB_INPUT_CH_LAYOUT_3F1R:
+ if ( CAN_MIXDOWN( audio ) )
+ {
+ if ( STEREO_ONLY( audio ) ||
+ audio->config.out.mixdown > HB_AMIXDOWN_DOLBY )
+ {
+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
+ }
+ }
+ else
+ {
+ // XXX we can't mixdown & don't have any way to specify
+ // 4 channel discrete output so we're hosed.
+ hb_log( "ERROR - can't handle 4 channel discrete audio stream "
+ "%x - output will be messed up", audio->id );
+ }
+ break;
+
+ // 5 or 6 channel discrete
+ case HB_INPUT_CH_LAYOUT_3F2R:
+ if ( CAN_MIXDOWN( audio ) )
+ {
+ if ( STEREO_ONLY( audio ) )
+ {
+ if ( audio->config.out.mixdown < HB_AMIXDOWN_STEREO )
+ {
+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
+ }
+ else if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBYPLII )
+ {
+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
+ }