{ "64", 64 }, { "80", 80 }, { "96", 96 }, { "112", 112 },
{ "128", 128 }, { "160", 160 }, { "192", 192 }, { "224", 224 },
{ "256", 256 }, { "320", 320 }, { "384", 384 }, { "448", 448 },
- { "768", 768 } };
+ { "512", 512 }, { "576", 576 }, { "640", 640 }, { "768", 768 } };
int hb_audio_bitrates_count = sizeof( hb_audio_bitrates ) /
sizeof( hb_rate_t );
int hb_audio_bitrates_default = 8; /* 128 kbps */
return "";
}
+// Given an input bitrate, find closest match in the set of allowed bitrates
+int hb_find_closest_audio_bitrate(int bitrate)
+{
+ int ii;
+ int result;
+
+ // result is highest rate if none found during search.
+ // rate returned will always be <= rate asked for.
+ result = hb_audio_bitrates[0].rate;
+ for (ii = hb_audio_bitrates_count-1; ii >= 0; ii--)
+ {
+ if (bitrate >= hb_audio_bitrates[ii].rate)
+ {
+ result = hb_audio_bitrates[ii].rate;
+ break;
+ }
+ }
+ return result;
+}
+
+// Get the bitrate low and high limits for a codec/samplerate/mixdown triplet
+// The limits have been empirically determined through testing. Max bitrates
+// in table below. Numbers in parenthesis are the target bitrate chosen.
+/*
+Encoder 1 channel 2 channels 6 channels
+
+faac
+24kHz 86 (128) 173 (256) 460 (768)
+48kHz 152 (160) 304 (320) 759 (768)
+
+Vorbis
+24kHz 97 (80) 177 (160) 527 (512)
+48kHz 241 (224) 465 (448) 783 (768)
+
+Lame
+24kHz 146 (768) 138 (768)
+48kHz 318 (768) 318 (768)
+
+ffac3
+24kHz 318 (320) 318 (320) 318 (320)
+48kHz 636 (640) 636 (640) 636 (640)
+
+Core Audio (core audio api provides range of allowed bitrates)
+24kHz 16-64 32-128 80-320
+44.1kHz 64-320 160-768
+48kHz 32-256 64-320 160-768
+
+Core Audio (minimum limits found in testing)
+24kHz 16 32 96
+44.1kHz 32 64 160
+48kHz 40 80 240
+*/
+
+void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, int *low, int *high)
+{
+ int channels;
+
+ channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mixdown);
+ switch (codec)
+ {
+ case HB_ACODEC_AC3:
+ *low = 32 * channels;
+ if (samplerate > 24000)
+ {
+ *high = 640;
+ }
+ else
+ {
+ *high = 320;
+ }
+ break;
+
+ case HB_ACODEC_CA_AAC:
+ if (samplerate > 44100)
+ {
+ *low = channels * 40;
+ *high = 256;
+ if (channels == 2)
+ *high = 320;
+ if (channels == 6)
+ {
+ *high = 768;
+ }
+ }
+ else if (samplerate > 24000)
+ {
+ *low = channels * 32;
+ *high = 256;
+ if (channels == 2)
+ *high = 320;
+ if (channels == 6)
+ {
+ *low = 160;
+ *high = 768;
+ }
+ }
+ else
+ {
+ *low = channels * 16;
+ *high = channels * 64;
+ if (channels == 6)
+ {
+ *high = 320;
+ }
+ }
+ break;
+
+ case HB_ACODEC_FAAC:
+ *low = 32 * channels;
+ if (samplerate > 24000)
+ {
+ *high = 160 * channels;
+ }
+ else
+ {
+ *high = 128 * channels;
+ }
+ if (*high > 768)
+ *high = 768;
+ break;
+
+ case HB_ACODEC_VORBIS:
+ *high = channels * 80;
+ if (samplerate > 24000)
+ {
+ if (channels > 2)
+ {
+ // Vorbis minimum is around 30kbps/ch for 6ch
+ // at rates > 24k (32k/44.1k/48k)
+ *low = 32 * channels;
+ *high = 128 * channels;
+ }
+ else
+ {
+ // Allow 24kbps mono and 48kbps stereo at rates > 24k
+ // (32k/44.1k/48k)
+ *low = 24 * channels;
+ if (samplerate > 32000)
+ *high = channels * 224;
+ else
+ *high = channels * 160;
+ }
+ }
+ else
+ {
+ *low = channels * 16;
+ *high = 80 * channels;
+ }
+ break;
+
+ default:
+ *low = hb_audio_bitrates[0].rate;
+ *high = hb_audio_bitrates[hb_audio_bitrates_count-1].rate;
+ break;
+ }
+}
+
+// Given an input bitrate, sanitize it. Check low and high limits and
+// make sure it is in the set of allowed bitrates.
+int hb_get_best_audio_bitrate( uint32_t codec, int bitrate, int samplerate, int mixdown)
+{
+ int low, high;
+
+ hb_get_audio_bitrate_limits(codec, samplerate, mixdown, &low, &high);
+ if (bitrate > high)
+ bitrate = high;
+ if (bitrate < low)
+ bitrate = low;
+ bitrate = hb_find_closest_audio_bitrate(bitrate);
+ return bitrate;
+}
+
+// Get the default bitrate for a given codec/samplerate/mixdown triplet.
+int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown )
+{
+ int bitrate, channels;
+ int sr_shift;
+
+ channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mixdown);
+
+ // Min bitrate is established such that we get good quality
+ // audio as a minimum.
+ sr_shift = (samplerate <= 24000) ? 1 : 0;
+
+ switch ( codec )
+ {
+ case HB_ACODEC_AC3:
+ if (channels == 1)
+ bitrate = 96;
+ else if (channels <= 2)
+ bitrate = 224;
+ else
+ bitrate = 640;
+ break;
+ default:
+ bitrate = channels * 80;
+ }
+ bitrate >>= sr_shift;
+ bitrate = hb_get_best_audio_bitrate( codec, bitrate, samplerate, mixdown );
+ return bitrate;
+}
+
+int hb_get_best_mixdown( uint32_t codec, int layout )
+{
+ switch (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
+ return HB_AMIXDOWN_STEREO;
+
+ // mono input
+ case HB_INPUT_CH_LAYOUT_MONO:
+ // everything else passes through
+ return HB_AMIXDOWN_MONO;
+
+ // 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:
+ return HB_AMIXDOWN_DOLBY;
+
+ // 4 channel discrete
+ case HB_INPUT_CH_LAYOUT_2F2R:
+ case HB_INPUT_CH_LAYOUT_3F1R:
+ // a52dec and libdca can't upmix to 6ch,
+ // so we must downmix these.
+ return HB_AMIXDOWN_DOLBYPLII;
+
+ // 5 or 6 channel discrete
+ case HB_INPUT_CH_LAYOUT_3F2R:
+ if ( ! ( layout & HB_INPUT_CH_LAYOUT_HAS_LFE ) )
+ {
+ // we don't do 5 channel discrete so mixdown to DPLII
+ // a52dec and libdca can't upmix to 6ch,
+ // so we must downmix this.
+ return HB_AMIXDOWN_DOLBYPLII;
+ }
+ else
+ {
+ switch (codec)
+ {
+ case HB_ACODEC_LAME:
+ return HB_AMIXDOWN_DOLBYPLII;
+
+ default:
+ return HB_AMIXDOWN_6CH;
+ }
+ }
+ }
+}
+
+int hb_get_default_mixdown( uint32_t codec, int layout )
+{
+ switch (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
+ return HB_AMIXDOWN_STEREO;
+
+ // mono input
+ case HB_INPUT_CH_LAYOUT_MONO:
+ // everything else passes through
+ return HB_AMIXDOWN_MONO;
+
+ // 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:
+ return HB_AMIXDOWN_DOLBY;
+
+ // 4 channel discrete
+ case HB_INPUT_CH_LAYOUT_2F2R:
+ case HB_INPUT_CH_LAYOUT_3F1R:
+ // a52dec and libdca can't upmix to 6ch,
+ // so we must downmix these.
+ return HB_AMIXDOWN_DOLBYPLII;
+
+ // 5 or 6 channel discrete
+ case HB_INPUT_CH_LAYOUT_3F2R:
+ if ( ! ( layout & HB_INPUT_CH_LAYOUT_HAS_LFE ) )
+ {
+ // we don't do 5 channel discrete so mixdown to DPLII
+ // a52dec and libdca can't upmix to 6ch,
+ // so we must downmix this.
+ return HB_AMIXDOWN_DOLBYPLII;
+ }
+ else
+ {
+ switch (codec)
+ {
+ case HB_ACODEC_AC3:
+ return HB_AMIXDOWN_6CH;
+
+ default:
+ return HB_AMIXDOWN_DOLBYPLII;
+ }
+ }
+ }
+}
+
/**********************************************************************
* hb_reduce
**********************************************************************
case HB_ACODEC_LAME:
samples_per_frame = 1152;
break;
+ case HB_ACODEC_AC3_PASS:
+ case HB_ACODEC_DCA_PASS:
case HB_ACODEC_AC3:
case HB_ACODEC_DCA:
samples_per_frame = 1536;
return 0;
}
- if( audio->config.out.codec == HB_ACODEC_AC3 ||
- audio->config.out.codec == HB_ACODEC_DCA)
+ if( audio->config.out.codec == HB_ACODEC_AC3_PASS ||
+ audio->config.out.codec == HB_ACODEC_DCA_PASS)
{
/*
* For pass through we take the bitrate from the input audio
*/
audio->config.out.track = hb_list_count(job->list_audio) + 1;
audio->config.out.codec = audiocfg->out.codec;
- if( audiocfg->out.codec == audio->config.in.codec )
+ if( (audiocfg->out.codec & HB_ACODEC_MASK) == audio->config.in.codec &&
+ (audiocfg->out.codec & HB_ACODEC_PASS_FLAG ) )
{
/* Pass-through, copy from input. */
audio->config.out.samplerate = audio->config.in.samplerate;
else
{
/* Non pass-through, use what is given. */
+ audio->config.out.codec &= ~HB_ACODEC_PASS_FLAG;
audio->config.out.samplerate = audiocfg->out.samplerate;
audio->config.out.bitrate = audiocfg->out.bitrate;
audio->config.out.dynamic_range_compression = audiocfg->out.dynamic_range_compression;