OSDN Git Service

add bootstrap step to libdca
[handbrake-jp/handbrake-jp-git.git] / libhb / common.c
index 35417cb..3788d31 100644 (file)
@@ -34,7 +34,7 @@ hb_rate_t hb_audio_bitrates[] =
   {  "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 */
@@ -77,6 +77,310 @@ const char * hb_mixdown_get_short_name_from_mixdown( int amixdown )
     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
  **********************************************************************
@@ -255,6 +559,8 @@ int hb_calc_bitrate( hb_job_t * job, int size )
             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;
@@ -263,8 +569,8 @@ int hb_calc_bitrate( hb_job_t * job, int size )
                 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
@@ -904,7 +1210,8 @@ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg)
      */
     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;
@@ -915,6 +1222,7 @@ int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg)
     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;