OSDN Git Service

Use libhb functions for mixdown and bitrate defaults in the cli
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 23 Oct 2010 18:48:26 +0000 (18:48 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 23 Oct 2010 18:48:26 +0000 (18:48 +0000)
sanitize mixdown and audio bitrates in work.c

git-svn-id: svn://localhost/HandBrake/trunk@3620 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/common.c
libhb/common.h
libhb/work.c
test/test.c

index 3788d31..d800267 100644 (file)
@@ -37,7 +37,6 @@ hb_rate_t hb_audio_bitrates[] =
   { "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 */
 
 static hb_error_handler_t *error_handler = NULL;
 
@@ -279,33 +278,45 @@ int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown )
     return bitrate;
 }
 
-int hb_get_best_mixdown( uint32_t codec, int layout )
+int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown )
 {
+
+    int best_mixdown;
+    
+    if (codec & HB_ACODEC_PASS_FLAG)
+    {
+        // Audio pass-thru.  No mixdown.
+        return 0;
+    }
     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;
+            best_mixdown = HB_AMIXDOWN_STEREO;
+            break;
 
         // mono input
         case HB_INPUT_CH_LAYOUT_MONO:
             // everything else passes through
-            return HB_AMIXDOWN_MONO;
+            best_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:
-            return HB_AMIXDOWN_DOLBY;
+            best_mixdown = HB_AMIXDOWN_DOLBY;
+            break;
 
         // 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;
+            best_mixdown = HB_AMIXDOWN_DOLBYPLII;
+            break;
 
         // 5 or 6 channel discrete
         case HB_INPUT_CH_LAYOUT_3F2R:
@@ -314,71 +325,47 @@ int hb_get_best_mixdown( uint32_t codec, int layout )
                 // 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;
+                best_mixdown = HB_AMIXDOWN_DOLBYPLII;
             }
             else
             {
                 switch (codec)
                 {
                     case HB_ACODEC_LAME:
-                        return HB_AMIXDOWN_DOLBYPLII;
+                        best_mixdown = HB_AMIXDOWN_DOLBYPLII;
+                        break;
 
                     default:
-                        return HB_AMIXDOWN_6CH;
+                        best_mixdown = HB_AMIXDOWN_6CH;
+                        break;
                 }
             }
+            break;
     }
+    // return the best that is not greater than the requested mixdown
+    // 0 means the caller requested the best available mixdown
+    if( best_mixdown > mixdown && mixdown != 0 )
+        best_mixdown = mixdown;
+    
+    return best_mixdown;
 }
 
 int hb_get_default_mixdown( uint32_t codec, int layout )
 {
-    switch (layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK)
+    int mixdown;
+    switch (codec)
     {
-        // stereo input or something not handled below
+        // the AC3 encoder defaults to the best mixdown up to 6-channel
+        case HB_ACODEC_AC3:
+            mixdown = HB_AMIXDOWN_6CH;
+            break;
+        // other encoders default to the best mixdown up to DPLII
         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;
-                }
-            }
+            mixdown = HB_AMIXDOWN_DOLBYPLII;
+            break;
     }
+    // return the best available mixdown up to the selected default
+    return hb_get_best_mixdown( codec, layout, mixdown );
 }
 
 /**********************************************************************
index 2a3d070..7383bf6 100644 (file)
@@ -145,12 +145,11 @@ extern int          hb_audio_rates_count;
 extern int          hb_audio_rates_default;
 extern hb_rate_t    hb_audio_bitrates[];
 extern int          hb_audio_bitrates_count;
-extern int          hb_audio_bitrates_default;
 extern hb_mixdown_t hb_audio_mixdowns[];
 extern int          hb_audio_mixdowns_count;
 int hb_mixdown_get_mixdown_from_short_name( const char * short_name );
 const char * hb_mixdown_get_short_name_from_mixdown( int amixdown );
-int hb_get_best_mixdown( uint32_t codec, int layout );
+int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown );
 int hb_get_default_mixdown( uint32_t codec, int layout );
 int hb_find_closest_audio_bitrate(int bitrate);
 void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, int *low, int *high);
index c9d32de..ebbc408 100644 (file)
@@ -559,28 +559,30 @@ static void do_job( hb_job_t * job, int cpu_count )
     }
 
     int requested_mixdown = 0;
-    int best_mixdown = 0;
     int requested_mixdown_index = 0;
+    int best_mixdown = 0;
+    int requested_bitrate = 0;
+    int best_bitrate = 0;
 
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
 
         best_mixdown = hb_get_best_mixdown( audio->config.out.codec,
-                                            audio->config.in.channel_layout );
+                                            audio->config.in.channel_layout, 0 );
 
         /* sense-check the current mixdown options */
 
         /* sense-check the requested mixdown */
         if( audio->config.out.mixdown == 0 &&
-            audio->config.out.codec != HB_ACODEC_AC3_PASS && 
-            audio->config.out.codec != HB_ACODEC_DCA_PASS )
+            !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
         {
             /*
              * Mixdown wasn't specified and this is not pass-through,
              * set a default mixdown
              */
-            audio->config.out.mixdown = best_mixdown;
+            audio->config.out.mixdown = hb_get_default_mixdown( audio->config.out.codec,
+                                                                audio->config.in.channel_layout );
             for (j = 0; j < hb_audio_mixdowns_count; j++)
             {
                 if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown)
@@ -616,10 +618,50 @@ static void do_job( hb_job_t * job, int cpu_count )
                 if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown)
                 {
                     hb_log("work: sanitizing track %i mixdown %s to %s", i, hb_audio_mixdowns[requested_mixdown_index].human_readable_name, hb_audio_mixdowns[j].human_readable_name);
-                break;
+                    break;
                 }
             }
         }
+        
+        /* sense-check the current bitrates */
+        
+        /* sense-check the requested bitrate */
+        if( audio->config.out.bitrate == 0 &&
+            !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
+        {
+            /*
+             * Bitrate wasn't specified and this is not pass-through,
+             * set a default bitrate
+             */
+            audio->config.out.bitrate = hb_get_default_audio_bitrate( audio->config.out.codec,
+                                                                      audio->config.out.samplerate,
+                                                                      audio->config.out.mixdown );
+            
+            hb_log( "work: bitrate not specified, track %d setting bitrate %d",
+                    i, audio->config.out.bitrate );
+        }
+        
+        /* log the requested bitrate */
+        requested_bitrate = audio->config.out.bitrate;
+        best_bitrate = hb_get_best_audio_bitrate( audio->config.out.codec, 
+                                                  audio->config.out.bitrate,
+                                                  audio->config.out.samplerate,
+                                                  audio->config.out.mixdown );
+        
+        if ( !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
+        {
+            if ( audio->config.out.bitrate != best_bitrate )
+            {
+                audio->config.out.bitrate = best_bitrate;
+            }
+        }
+        
+        if ( audio->config.out.bitrate != requested_bitrate )
+        {
+            /* log the output bitrate */
+            hb_log( "work: sanitizing track %d audio bitrate %d to %d", 
+                    i, requested_bitrate, audio->config.out.bitrate);
+        }
 
         if (audio->config.out.codec == HB_ACODEC_VORBIS)
             audio->priv.config.vorbis.language = audio->config.lang.simple;
index 14046cf..2af2408 100644 (file)
@@ -74,8 +74,11 @@ static char * arates      = NULL;
 static char * abitrates   = NULL;
 static char * acodecs     = NULL;
 static char * anames      = NULL;
+#ifdef __APPLE_CC__
+static int    default_acodec = HB_ACODEC_CA_AAC;
+#else
 static int    default_acodec = HB_ACODEC_FAAC;
-static int    default_abitrate = 160;
+#endif
 static int    audio_explicit = 0;
 static char ** subtracks   = NULL;
 static char ** subforce    = NULL;
@@ -1635,6 +1638,52 @@ static int HandleEvents( hb_handle_t * h )
                 }
             }
             /* Sample Rate */
+            
+            /* Audio Mixdown */
+            i = 0;
+            if ( mixdowns )
+            {
+                char * token = strtok(mixdowns, ",");
+                if (token == NULL)
+                    token = mixdowns;
+                while ( token != NULL )
+                {
+                    mixdown = hb_mixdown_get_mixdown_from_short_name(token);
+                    audio = hb_list_audio_config_item(job->list_audio, i);
+                    if( audio != NULL )
+                    {
+                        audio->out.mixdown = mixdown;
+                        if( (++i) >= num_audio_tracks )
+                            break;  /* We have more inputs than audio tracks, oops */
+                    }
+                    else
+                    {
+                        fprintf(stderr, "Ignoring mixdown, no audio tracks\n");
+                    }
+                    token = strtok(NULL, ",");
+                }
+            }
+            if (i < num_audio_tracks)
+            {
+                /* We have fewer inputs than audio tracks, use the default mixdown for the rest. Unless
+                 * we only have one input, then use that.
+                 */
+                int use_default = 0;
+                if (i != 1)
+                    use_default = 1;
+
+                for (; i < num_audio_tracks; i++)
+                {
+                    audio = hb_list_audio_config_item(job->list_audio, i);
+                    if (use_default)
+                    {
+                        // Get default for this tracks codec and layout
+                        mixdown = hb_get_default_mixdown( audio->out.codec, audio->in.channel_layout );
+                    }
+                    audio->out.mixdown = mixdown;
+                }
+            }
+            /* Audio Mixdown */
 
             /* Audio Bitrate */
             i = 0;
@@ -1667,11 +1716,19 @@ static int HandleEvents( hb_handle_t * h )
                  * for the remaining tracks. Unless we only have one input, then use
                  * that for all tracks.
                  */
+                int use_default = 0;
                 if (i != 1)
-                    abitrate = default_abitrate;
+                    use_default = 1;
+
                 for (; i < num_audio_tracks; i++)
                 {
                     audio = hb_list_audio_config_item(job->list_audio, i);
+                    if (use_default)
+                    {
+                        abitrate = hb_get_default_audio_bitrate( 
+                                        audio->out.codec, audio->out.samplerate,
+                                        audio->out.mixdown );
+                    }
                     audio->out.bitrate = abitrate;
                 }
             }
@@ -1717,45 +1774,6 @@ static int HandleEvents( hb_handle_t * h )
             }
             /* Audio DRC */
 
-            /* Audio Mixdown */
-            i = 0;
-            if ( mixdowns )
-            {
-                char * token = strtok(mixdowns, ",");
-                if (token == NULL)
-                    token = mixdowns;
-                while ( token != NULL )
-                {
-                    mixdown = hb_mixdown_get_mixdown_from_short_name(token);
-                    audio = hb_list_audio_config_item(job->list_audio, i);
-                    if( audio != NULL )
-                    {
-                        audio->out.mixdown = mixdown;
-                        if( (++i) >= num_audio_tracks )
-                            break;  /* We have more inputs than audio tracks, oops */
-                    }
-                    else
-                    {
-                        fprintf(stderr, "Ignoring mixdown, no audio tracks\n");
-                    }
-                    token = strtok(NULL, ",");
-                }
-            }
-            if (i < num_audio_tracks)
-            {
-                /* We have fewer inputs than audio tracks, use DPLII for the rest. Unless
-                 * we only have one input, then use that.
-                 */
-                if (i != 1)
-                    mixdown = HB_AMIXDOWN_DOLBYPLII;
-                for (; i < num_audio_tracks; i++)
-                {
-                   audio = hb_list_audio_config_item(job->list_audio, i);
-                   audio->out.mixdown = mixdown;
-                }
-            }
-            /* Audio Mixdown */
-
             /* Audio Track Names */
             i = 0;
             if ( anames )
@@ -2401,7 +2419,7 @@ static void ShowHelp()
     "                            copy, copy:ac3 and copy:dts meaning passthrough.\n"
     "                            copy will passthrough either ac3 or dts.\n"
     "                            Separated by commas for more than one audio track.\n"
-    "                            (default: guessed)\n" );
+    "                            (default: ca_aac)\n" );
 #else
     fprintf( out,
     "    -E, --aencoder <string> Audio encoder(s):\n"
@@ -2409,14 +2427,16 @@ static void ShowHelp()
     "                            copy, copy:ac3 and copy:dts meaning passthrough.\n"
     "                            copy will passthrough either ac3 or dts.\n"
     "                            Separated by commas for more than one audio track.\n"
-    "                            (default: guessed)\n" );
+    "                            (default: faac for mp4, lame for mkv)\n" );
 #endif
     fprintf( out,
-    "    -B, --ab <kb/s>         Set audio bitrate(s)  (default: 160)\n"
+    "    -B, --ab <kb/s>         Set audio bitrate(s) (default: depends on the\n"
+    "                            selected codec, mixdown and samplerate)\n"
     "                            Separated by commas for more than one audio track.\n"
     "    -6, --mixdown <string>  Format(s) for surround sound downmixing\n"
     "                            Separated by commas for more than one audio track.\n"
-    "                            (mono/stereo/dpl1/dpl2/6ch, default: dpl2)\n"
+    "                            (mono/stereo/dpl1/dpl2/6ch, default: up to 6ch for ac3,\n"
+    "                            up to dpl2 for other encoders)\n"
     "    -R, --arate             Set audio samplerate(s) (" );
     for( i = 0; i < hb_audio_rates_count; i++ )
     {
@@ -3368,12 +3388,14 @@ static int CheckOptions( int argc, char ** argv )
                     mux = HB_MUX_IPOD;
                 else
                     mux = HB_MUX_MP4;
-                default_acodec = HB_ACODEC_FAAC;
             }
             else if( p && !strcasecmp(p, ".mkv" ) )
             {
                 mux = HB_MUX_MKV;
-                default_acodec = HB_ACODEC_AC3;
+#ifndef __APPLE_CC__
+                // default to Lame for MKV (except under OS X where Core Audio is available)
+                default_acodec = HB_ACODEC_LAME;
+#endif
             }
             else
             {
@@ -3389,12 +3411,14 @@ static int CheckOptions( int argc, char ** argv )
                 mux = HB_MUX_IPOD;
             else
                 mux = HB_MUX_MP4;
-            default_acodec = HB_ACODEC_FAAC;
         }
         else if( !strcasecmp( format, "mkv" ) )
         {
             mux = HB_MUX_MKV;
-            default_acodec = HB_ACODEC_AC3;
+#ifndef __APPLE_CC__
+            // default to Lame for MKV (except under OS X where Core Audio is available)
+            default_acodec = HB_ACODEC_LAME;
+#endif
         }
         else
         {