]> granicus.if.org Git - handbrake/commitdiff
Add ac3 encoding
authorjstebbins <jstebbins.hb@gmail.com>
Mon, 4 Oct 2010 23:16:57 +0000 (23:16 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Mon, 4 Oct 2010 23:16:57 +0000 (23:16 +0000)
Uses ffmpeg's ac3 encoder.

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3570 b64f7644-9d1e-0410-96f1-a4d463321fa5

23 files changed:
gtk/src/audiohandler.c
gtk/src/hb-backend.c
gtk/src/hb-backend.h
gtk/src/internal_defaults.xml
gtk/src/makedeps.py
gtk/src/presets.c
gtk/src/queuehandler.c
libhb/common.c
libhb/common.h
libhb/deca52.c
libhb/decavcodec.c
libhb/decdca.c
libhb/encac3.c [new file with mode: 0644]
libhb/hb.c
libhb/internal.h
libhb/muxmkv.c
libhb/muxmp4.c
libhb/sync.c
libhb/work.c
macosx/HBAudio.m
macosx/HBAudioController.m
scripts/manicure.rb
test/test.c

index 4ecc509c3c907d7127b0c5cbe013cc125959a4c0..6e0748f130b50ed0cacad26212526ff8f076c9dd 100644 (file)
@@ -25,12 +25,14 @@ static void ghb_add_audio(signal_user_data_t *ud, GValue *settings);
 void
 ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
 {
-       gint titleindex, track, acodec, mix;
+       gint titleindex, track, acodec, select_acodec, mix;
        ghb_audio_info_t ainfo;
        GtkWidget *widget;
        GValue *gval;
+       int mux;
        
        g_debug("ghb_adjust_audio_rate_combos ()");
+       mux = ghb_settings_combo_int(ud->settings, "FileFormat");
        titleindex = ghb_settings_combo_int(ud->settings, "title");
 
        widget = GHB_WIDGET(ud->builder, "AudioTrack");
@@ -47,34 +49,48 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
        mix = ghb_lookup_combo_int("AudioMixdown", gval);
        ghb_value_free(gval);
 
-       if (ghb_audio_is_passthru (acodec))
+       select_acodec = acodec;
+       if (mux == HB_MUX_MP4)
+       {
+               select_acodec &= ~HB_ACODEC_DCA;
+       }
+       if ((select_acodec & HB_ACODEC_MASK) == 0)
+       {
+               // Unsuported codec in this container.
+               select_acodec |= HB_ACODEC_AC3;
+               acodec = select_acodec;
+       }
+
+       if (ghb_audio_is_passthru (select_acodec))
        {
                ghb_set_default_bitrate_opts (ud->builder, 0, -1);
                if (ghb_get_audio_info (&ainfo, titleindex, track))
                {
                        gint br = ainfo.bitrate / 1000;
+
                        // Set the values for bitrate and samplerate to the input rates
-                       if (br < 8)
-                               br = 160;
-                       if (ghb_audio_is_passthru (ainfo.codec))
+                       if (ainfo.codec & select_acodec & HB_ACODEC_PASS_MASK)
                        {
                                ghb_set_passthru_bitrate_opts (ud->builder, br);
                                ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
-                               acodec &= ainfo.codec;
+                               select_acodec &= ainfo.codec | HB_ACODEC_PASS_FLAG;
                        }
                        else
                        {
-                               if (acodec != HB_ACODEC_MASK)
-                               {
-                                       acodec = ghb_select_audio_codec(ud, track);
-                                       ghb_ui_update(ud, "AudioEncoder", ghb_int64_value(acodec));
-                               }
-                               else
+                               select_acodec = ghb_select_audio_codec(ud->settings, acodec, track);
+                               if (acodec != HB_ACODEC_ANY)
                                {
-                                       acodec = ghb_select_audio_codec(ud, track);
+                                       ghb_ui_update(ud, "AudioEncoder", ghb_int64_value(select_acodec));
                                }
-                               br = ghb_find_closest_audio_bitrate(acodec, br);
-                               mix = ghb_get_best_mix( titleindex, track, acodec, 0);
+
+                               int channels, min_rate;
+                               mix = ghb_get_best_mix( titleindex, track, select_acodec, mix);
+                               channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mix);
+                               br = ainfo.bitrate / 1000;
+                               min_rate = channels * 32;
+                               if (br < min_rate)
+                                       br = min_rate;
+                               br = ghb_find_closest_audio_bitrate(select_acodec, br);
                                ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix));
                        }
                        ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(br));
@@ -85,11 +101,11 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
                        ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(384));
                        ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
                        ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
-                       acodec = HB_ACODEC_AC3;
+                       select_acodec = HB_ACODEC_AC3;
                }
                ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(0));
        }
-       else if (acodec == HB_ACODEC_FAAC)
+       if (select_acodec == HB_ACODEC_FAAC)
        {
                gint br, last = 320, first = 0;
 
@@ -109,12 +125,16 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
                        ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(first));
                ghb_set_default_bitrate_opts (ud->builder, first, last);
        }
+       else if (select_acodec == HB_ACODEC_AC3)
+       {
+               ghb_set_default_bitrate_opts (ud->builder, 0, 640);
+       }
        else
        {
                ghb_set_default_bitrate_opts (ud->builder, 0, -1);
        }
        ghb_settings_take_value(ud->settings, "AudioEncoderActual", 
-                                                       ghb_lookup_acodec_value(acodec));
+                                                       ghb_lookup_acodec_value(select_acodec));
        ghb_check_dependency(ud, NULL, "AudioEncoderActual");
 }
 
@@ -151,16 +171,20 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
 
        const GValue *pref_audio;
        const GValue *audio, *drc;
-       gint acodec, bitrate, mix;
+       gint mix_acodec, acodec, bitrate, mix;
        gdouble rate;
        gint count, ii, list_count;
        
        g_debug("set_pref_audio");
        mux = ghb_settings_combo_int(ud->settings, "FileFormat");
        if (mux == HB_MUX_MP4)
+       {
                fallback_acodec = HB_ACODEC_FAAC;
+       }
        else
+       {
                fallback_acodec = HB_ACODEC_LAME;
+       }
        track_indices = g_hash_table_new_full(g_int_hash, g_int_equal, 
                                                free_audio_hash_key_value, free_audio_hash_key_value);
        // Clear the audio list
@@ -180,8 +204,25 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
        count = ghb_array_len(pref_audio);
        for (ii = 0; ii < count; ii++)
        {
+               int select_acodec;
+
                audio = ghb_array_get_nth(pref_audio, ii);
-               acodec = ghb_settings_combo_int(audio, "AudioEncoder");
+               select_acodec = acodec = ghb_settings_combo_int(audio, "AudioEncoder");
+               if (mux == HB_MUX_MP4)
+               {
+                       select_acodec &= ~HB_ACODEC_DCA;
+               }
+               if ((select_acodec & HB_ACODEC_MASK) == 0)
+               {
+                       // Unsuported codec in this container.
+                       select_acodec |= HB_ACODEC_AC3;
+                       acodec = select_acodec;
+               }
+               if ( ghb_audio_can_passthru( select_acodec ) )
+               {
+                       fallback_acodec = HB_ACODEC_AC3;
+               }
+               mix_acodec = acodec;
                bitrate = ghb_settings_combo_int(audio, "AudioBitrate");
                rate = ghb_settings_combo_double(audio, "AudioSamplerate");
                mix = ghb_settings_combo_int(audio, "AudioMixdown");
@@ -190,7 +231,7 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
                // select sequential tracks for each.  The hash keeps track 
                // of the tracks used for each codec.
                track = ghb_find_audio_track(titleindex, source_lang, 
-                                                               acodec, fallback_acodec, track_indices);
+                                                               select_acodec, fallback_acodec, track_indices);
                // Check to see if:
                // 1. pref codec is passthru
                // 2. source codec is not passthru
@@ -199,24 +240,33 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
                        ghb_audio_is_passthru (acodec))
                {
                        // HB_ACODEC_* are bit fields.  Treat acodec as mask
-                       if (!(ainfo.codec & acodec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)))
+                       if (!(ainfo.codec & select_acodec & HB_ACODEC_PASS_MASK))
                        {
-                               if (acodec != HB_ACODEC_MASK)
+                               if (acodec != HB_ACODEC_ANY)
                                        acodec = fallback_acodec;
+                               mix_acodec = fallback_acodec;
+                               // If we can't substitute the passthru with a suitable
+                               // encoder and
                                // If there's more audio to process, or we've already
                                // placed one in the list, then we can skip this one
-                               if ((ii + 1 < count) || (list_count != 0))
+                               if (!(select_acodec & fallback_acodec) && 
+                                       ((ii + 1 < count) || (list_count != 0)))
                                {
                                        // Skip this audio
                                        acodec = 0;
                                }
                                else
                                {
+                                       int channels, min_rate;
+                                       mix = ghb_get_best_mix( titleindex, track, mix_acodec, mix);
+                                       channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mix);
                                        bitrate = ainfo.bitrate / 1000;
-                                       if (bitrate < 8)
-                                               bitrate = 160;
+                                       min_rate = channels * 32;
+                                       if (bitrate < min_rate)
+                                               bitrate = min_rate;
+                                       if (bitrate > 640)
+                                               bitrate = 640;
                                        rate = 0;
-                                       mix = HB_AMIXDOWN_DOLBYPLII;
                                }
                        }
                }
@@ -235,7 +285,7 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
                                ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate)));
                        ghb_settings_set_string(settings, "AudioSamplerate",
                                ghb_lookup_combo_string("AudioSamplerate", ghb_int_value(rate)));
-                       mix = ghb_get_best_mix( titleindex, track, acodec, mix);
+                       mix = ghb_get_best_mix( titleindex, track, mix_acodec, mix);
                        ghb_settings_set_string(settings, "AudioMixdown",
                                ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix)));
                        ghb_settings_set_value(settings, "AudioTrackDRCSlider", drc);
@@ -328,8 +378,8 @@ ghb_audio_list_refresh_selected(signal_user_data_t *ud)
                else
                        s_drc = g_strdup_printf("%.1f", drc);
 
-               if (icodec == HB_ACODEC_MASK)
-                       codec = ghb_select_audio_codec_str(ud, itrack);
+               if (icodec == HB_ACODEC_ANY)
+                       codec = ghb_select_audio_codec_str(ud->settings, icodec, itrack);
 
                gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
                        // These are displayed in list
@@ -537,9 +587,9 @@ add_to_audio_list(signal_user_data_t *ud, GValue *settings)
        else
                s_drc = g_strdup_printf("%.1f", drc);
 
-       if (icodec == HB_ACODEC_MASK)
+       if (icodec == HB_ACODEC_ANY)
        {
-               codec = ghb_select_audio_codec_str(ud, itrack);
+               codec = ghb_select_audio_codec_str(ud->settings, icodec, itrack);
        }
 
        gtk_list_store_append(store, &iter);
index d23d3c7460d9e17036627f089c6dec02c3f9dabd..8614b0a99747a92af12f4a4d77905168b24f3727 100644 (file)
@@ -249,12 +249,13 @@ combo_opts_t vcodec_opts =
 
 static options_map_t d_acodec_opts[] =
 {
-       {"AAC (faac)",      "faac",   HB_ACODEC_FAAC,   "faac"},
-       {"MP3 (lame)",      "lame",   HB_ACODEC_LAME,   "lame"},
-       {"Vorbis",          "vorbis", HB_ACODEC_VORBIS, "vorbis"},
-       {"AC3 (pass-thru)", "ac3",    HB_ACODEC_AC3,    "ac3"},
-       {"DTS (pass-thru)", "dts",    HB_ACODEC_DCA,    "dts"},
-       {"Choose For Me",   "auto",   HB_ACODEC_MASK,   "auto"},
+       {"AAC (faac)",      "faac",    HB_ACODEC_FAAC,     "faac"},
+       {"MP3 (lame)",      "lame",    HB_ACODEC_LAME,     "lame"},
+       {"Vorbis",          "vorbis",  HB_ACODEC_VORBIS,   "vorbis"},
+       {"AC3 (ffmpeg)",    "ac3",     HB_ACODEC_AC3,      "ac3"},
+       {"AC3 (pass-thru)", "ac3pass", HB_ACODEC_AC3_PASS, "ac3pass"},
+       {"DTS (pass-thru)", "dtspass", HB_ACODEC_DCA_PASS, "dtspass"},
+       {"Choose For Me",   "auto",    HB_ACODEC_ANY,      "auto"},
 };
 combo_opts_t acodec_opts =
 {
@@ -1104,6 +1105,8 @@ ghb_find_closest_audio_bitrate(gint codec, gint rate)
 
        if (codec == HB_ACODEC_FAAC)
                high = 320;
+       else if (codec == HB_ACODEC_AC3)
+               high = 640;
 
        result = high;
        for (ii = 0; ii < hb_audio_bitrates_count; ii++)
@@ -1581,19 +1584,19 @@ ghb_grey_combo_options(GtkBuilder *builder)
        gboolean allow_dca = TRUE;
        allow_dca = (container != HB_MUX_MP4);
 
-       grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_AC3, FALSE);
+       grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_AC3_PASS, FALSE);
        if (allow_dca)
-               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA, FALSE);
+               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, FALSE);
        else
-               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA, TRUE);
+               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
 
        if (audio && audio->in.codec != HB_ACODEC_AC3)
        {
-               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_AC3, TRUE);
+               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_AC3_PASS, TRUE);
        }
        if (audio && audio->in.codec != HB_ACODEC_DCA)
        {
-               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA, TRUE);
+               grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
        }
        grey_combo_box_item(builder, "VideoEncoder", HB_VCODEC_THEORA, FALSE);
 
@@ -1601,10 +1604,7 @@ ghb_grey_combo_options(GtkBuilder *builder)
        gval = ghb_widget_value(widget);
        acodec = ghb_lookup_combo_int("AudioEncoder", gval);
        ghb_value_free(gval);
-       if (acodec != HB_ACODEC_AC3)
-       {
-               grey_combo_box_item(builder, "AudioMixdown", 0, TRUE);
-       }
+       grey_combo_box_item(builder, "AudioMixdown", 0, TRUE);
        if (container == HB_MUX_MP4)
        {
                grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_VORBIS, TRUE);
@@ -1666,7 +1666,7 @@ ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix)
        gboolean allow_dpl2 = TRUE;
        gboolean allow_6ch = TRUE;
        
-       if (acodec & (HB_ACODEC_AC3 | HB_ACODEC_DCA))
+       if (acodec & HB_ACODEC_PASS_FLAG)
        {
                // Audio codec pass-thru.  No mixdown
                return 0;
@@ -2047,7 +2047,7 @@ find_combo_item_by_int(GtkTreeModel *store, gint value, GtkTreeIter *iter)
                do
                {
                        gtk_tree_model_get(store, iter, 3, &ivalue, -1);
-                       if (value == (int)ivalue)
+                       if (value == (gint)ivalue)
                        {
                                foundit = TRUE;
                                break;
@@ -2340,14 +2340,14 @@ ghb_find_audio_track(
        // Try to find an item that matches the preferred language and
        // the passthru codec type
        max_chan = 0;
-       passthru = (acodec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)) != 0;
+       passthru = (acodec & HB_ACODEC_PASS_FLAG) != 0;
        if (passthru)
        {
                for (ii = 0; ii < count; ii++)
                {
                        audio = (hb_audio_config_t*)hb_list_audio_config_item( 
                                                                                                        title->list_audio, ii );
-                       passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec;
+                       passthru_acodec = acodec & audio->in.codec;
                        // Is the source track use a passthru capable codec?
                        if (passthru_acodec == 0)
                                continue;
@@ -2392,7 +2392,7 @@ ghb_find_audio_track(
                        continue;
                audio = (hb_audio_config_t*)hb_list_audio_config_item( 
                                                                                                title->list_audio, ii );
-               passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec;
+               passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
                if (passthru_acodec && passthru)
                {
                        passthru_used = get_track_used(passthru_acodec, track_indices, count);
@@ -2428,7 +2428,7 @@ ghb_find_audio_track(
                {
                        audio = (hb_audio_config_t*)hb_list_audio_config_item( 
                                                                                                        title->list_audio, ii );
-                       passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec;
+                       passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
                        // Is the source track use a passthru capable codec?
                        if (passthru_acodec == 0)
                                continue;
@@ -2471,7 +2471,7 @@ ghb_find_audio_track(
                        continue;
                audio = (hb_audio_config_t*)hb_list_audio_config_item( 
                                                                                                        title->list_audio, ii );
-               passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec;
+               passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
                channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(
                                                                                                audio->in.channel_layout);
                if (passthru_acodec && passthru)
@@ -2501,7 +2501,7 @@ ghb_find_audio_track(
        {
                audio = (hb_audio_config_t*)hb_list_audio_config_item( 
                                                                                                title->list_audio, ii );
-               passthru_acodec = (HB_ACODEC_AC3 | HB_ACODEC_DCA) & audio->in.codec;
+               passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
                if (passthru_acodec && passthru)
                {
                        passthru_used = get_track_used(passthru_acodec, track_indices, count);
@@ -3502,7 +3502,14 @@ gboolean
 ghb_audio_is_passthru(gint acodec)
 {
        g_debug("ghb_audio_is_passthru () \n");
-       return (acodec & (HB_ACODEC_AC3 | HB_ACODEC_DCA));
+       return (acodec & HB_ACODEC_PASS_FLAG) != 0;
+}
+
+gboolean
+ghb_audio_can_passthru(gint acodec)
+{
+       g_debug("ghb_audio_can_passthru () \n");
+       return (acodec & HB_ACODEC_PASS_MASK) != 0;
 }
 
 gint
@@ -4166,7 +4173,7 @@ ghb_validate_subtitles(signal_user_data_t *ud)
 }
 
 gint
-ghb_select_audio_codec(signal_user_data_t *ud, gint track)
+ghb_select_audio_codec(GValue *settings, gint acodec, gint track)
 {
        hb_list_t  * list;
        hb_title_t * title;
@@ -4181,39 +4188,68 @@ ghb_select_audio_codec(signal_user_data_t *ud, gint track)
 
        gint titleindex;
 
-       titleindex = ghb_settings_combo_int(ud->settings, "title");
+       titleindex = ghb_settings_combo_int(settings, "title");
     title = hb_list_item( list, titleindex );
        if (title == NULL) return -1;
 
-       gint mux = ghb_settings_combo_int(ud->settings, "FileFormat");
+       gint mux = ghb_settings_combo_int(settings, "FileFormat");
 
        if (track < 0 || track >= hb_list_count(title->list_audio))
                return -1;
 
        audio = (hb_audio_config_t *) hb_list_audio_config_item(
                                                                        title->list_audio, track );
+
        if (mux == HB_MUX_MP4)
        {
-               if (audio->in.codec == HB_ACODEC_AC3)
-                       return audio->in.codec;
+               if ((acodec & audio->in.codec & HB_ACODEC_AC3))
+               {
+                       return acodec & (audio->in.codec | HB_ACODEC_PASS_FLAG);
+               }
+               else if (acodec & HB_ACODEC_AC3)
+               {
+                       return HB_ACODEC_AC3;
+               }
+               else if (acodec & HB_ACODEC_FAAC)
+               {
+                       return HB_ACODEC_FAAC;
+               }
                else
+               {
                        return HB_ACODEC_FAAC;
+               }
        }
        else
        {
-               if (audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA)
-                       return audio->in.codec;
+               if ((acodec & audio->in.codec & HB_ACODEC_PASS_MASK))
+               {
+                       return acodec & (audio->in.codec | HB_ACODEC_PASS_FLAG);
+               }
+               else if (acodec & HB_ACODEC_AC3)
+               {
+                       return HB_ACODEC_AC3;
+               }
+               else if (acodec & HB_ACODEC_VORBIS)
+               {
+                       return HB_ACODEC_VORBIS;
+               }
+               else if (acodec & HB_ACODEC_LAME)
+               {
+                       return HB_ACODEC_LAME;
+               }
                else
+               {
                        return HB_ACODEC_LAME;
+               }
        }
 }
 
 const gchar*
-ghb_select_audio_codec_str(signal_user_data_t *ud, gint track)
+ghb_select_audio_codec_str(GValue *settings, gint icodec, gint track)
 {
        gint acodec, ii;
 
-       acodec = ghb_select_audio_codec(ud, track);
+       acodec = ghb_select_audio_codec(settings, icodec, track);
        for (ii = 0; ii < acodec_opts.count; ii++)
        {
                if (acodec_opts.map[ii].ivalue == acodec)
@@ -4259,13 +4295,14 @@ ghb_validate_audio(signal_user_data_t *ud)
                asettings = ghb_array_get_nth(audio_list, ii);
                gint track = ghb_settings_combo_int(asettings, "AudioTrack");
                gint codec = ghb_settings_combo_int(asettings, "AudioEncoder");
-               if (codec == HB_ACODEC_MASK)
+               if (codec == HB_ACODEC_ANY)
                        continue;
 
         taudio = (hb_audio_config_t *) hb_list_audio_config_item(
                                                                                        title->list_audio, track );
-               if (!(taudio->in.codec & codec) && 
-                       (codec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)))
+               if ( ghb_audio_is_passthru(codec) &&
+                       !(ghb_audio_can_passthru(taudio->in.codec) && 
+                        (taudio->in.codec & codec)))
                {
                        // Not supported.  AC3 is passthrough only, so input must be AC3
                        message = g_strdup_printf(
@@ -4278,7 +4315,12 @@ ghb_validate_audio(signal_user_data_t *ud)
                                return FALSE;
                        }
                        g_free(message);
-                       if (mux == HB_MUX_MKV)
+                       if ((codec & HB_ACODEC_AC3) ||
+                               taudio->in.codec == HB_ACODEC_DCA)
+                       {
+                               codec = HB_ACODEC_AC3;
+                       }
+                       else if (mux == HB_MUX_MKV)
                        {
                                codec = HB_ACODEC_LAME;
                        }
@@ -4303,7 +4345,7 @@ ghb_validate_audio(signal_user_data_t *ud)
                        if (codec == HB_ACODEC_DCA)
                        {
                                a_unsup = "DTS";
-                               codec = HB_ACODEC_FAAC;
+                               codec = HB_ACODEC_AC3;
                        }
                }
                if (a_unsup)
@@ -4715,48 +4757,24 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                GValue *asettings;
            hb_audio_config_t audio;
            hb_audio_config_t *taudio;
+               gint acodec;
 
                hb_audio_config_init(&audio);
                asettings = ghb_array_get_nth(audio_list, ii);
                audio.in.track = ghb_settings_get_int(asettings, "AudioTrack");
                audio.out.track = tcount;
-               audio.out.codec = ghb_settings_combo_int(asettings, "AudioEncoder");
+               acodec = ghb_settings_combo_int(asettings, "AudioEncoder");
+               audio.out.codec = ghb_select_audio_codec(js, acodec, audio.in.track);
+
         taudio = (hb_audio_config_t *) hb_list_audio_config_item(
                                                                        title->list_audio, audio.in.track );
-               if (audio.out.codec & (HB_ACODEC_AC3 | HB_ACODEC_DCA))
-               {
-                       if (!(taudio->in.codec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)))
-                       {
-                               // Not supported.  
-                               // AC3/DTS is passthrough only, so input must be AC3/DTS
-                               if (job->mux == HB_MUX_MKV)
-                               {
-                                       audio.out.codec = HB_ACODEC_LAME;
-                               }
-                               else
-                               {
-                                       audio.out.codec = HB_ACODEC_FAAC;
-                               }
-                       }
-                       else
-                       {
-                               audio.out.codec &= taudio->in.codec;
-                       }
-               }
-               if ((job->mux == HB_MUX_MP4) && 
-                       ((audio.out.codec & HB_ACODEC_DCA) ||
-                       (audio.out.codec & HB_ACODEC_VORBIS)))
-               {
-                       // mp4/mp3|dts|vorbis combination is not supported.
-                       audio.out.codec = HB_ACODEC_FAAC;
-               }
         audio.out.dynamic_range_compression = 
                        ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
         if (audio.out.dynamic_range_compression < 1.0)
                audio.out.dynamic_range_compression = 0.0;
 
                // It would be better if this were done in libhb for us, but its not yet.
-               if (audio.out.codec & (HB_ACODEC_AC3 | HB_ACODEC_DCA))
+               if (ghb_audio_is_passthru(audio.out.codec))
                {
                        audio.out.mixdown = 0;
                }
index ff31e90a3a832a588bcdfae77d742c0adca71988..cd6198c25349824e7bbe665cce35d9fe357bee06 100644 (file)
@@ -137,6 +137,7 @@ void ghb_part_duration(gint tt, gint sc, gint ec, gint *hh, gint *mm, gint *ss);
 gint ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix);
 gboolean ghb_ac3_in_audio_list(const GValue *audio_list);
 gboolean ghb_audio_is_passthru(gint acodec);
+gboolean ghb_audio_can_passthru(gint acodec);
 gint ghb_get_default_acodec(void);
 gboolean ghb_get_audio_info(
        ghb_audio_info_t *ainfo, gint titleindex, gint audioindex);
@@ -182,8 +183,8 @@ gdouble ghb_lookup_combo_double(const gchar *name, const GValue *gval);
 const gchar* ghb_lookup_combo_option(const gchar *name, const GValue *gval);
 const gchar* ghb_lookup_combo_string(const gchar *name, const GValue *gval);
 gchar* ghb_get_tmp_dir();
-gint ghb_select_audio_codec(signal_user_data_t *ud, gint track);
-const gchar* ghb_select_audio_codec_str(signal_user_data_t *ud, gint track);
+gint ghb_select_audio_codec(GValue *settings, gint acodec, gint track);
+const gchar* ghb_select_audio_codec_str(GValue *settings, gint acodec, gint track);
 gint ghb_find_closest_audio_bitrate(gint codec, gint rate);
 gint ghb_find_closest_audio_rate(gint rate);
 GValue* ghb_lookup_acodec_value(gint val);
index 0e41912f1f62addcdb7fe16bb8e5be152d26b8a6..568da2fa955e5e8bd71117a9591172c3e2b85575 100644 (file)
                                <key>AudioBitrate</key>
                                <string>192</string>
                                <key>AudioEncoder</key>
-                               <string>ac3</string>
+                               <string>ac3pass</string>
                                <key>AudioTrack</key>
                                <integer>1</integer>
                                <key>AudioTrackDescription</key>
index 986cf5b52459a43b10e710246fc3a415e72b6588..121c5654a4b274c56843169bc1082b9929cc651f 100644 (file)
@@ -49,11 +49,11 @@ dep_map = (
        DepEntry("VideoEncoder", "x264_tab", "x264", False, False),
        DepEntry("VideoEncoder", "x264_tab_label", "x264", False, False),
        DepEntry("VideoEncoder", "Mp4iPodCompatible", "x264", False, False),
-       DepEntry("AudioEncoderActual", "AudioBitrate", "ac3|dts", True, False),
-       DepEntry("AudioEncoderActual", "AudioSamplerate", "ac3|dts", True, False),
-       DepEntry("AudioEncoderActual", "AudioMixdown", "ac3|dts", True, False),
-       DepEntry("AudioEncoderActual", "AudioTrackDRCSlider", "ac3|dts", True, False),
-       DepEntry("AudioEncoderActual", "drc_label", "ac3|dts", True, False),
+       DepEntry("AudioEncoderActual", "AudioBitrate", "ac3pass|dtspass", True, False),
+       DepEntry("AudioEncoderActual", "AudioSamplerate", "ac3pass|dtspass", True, False),
+       DepEntry("AudioEncoderActual", "AudioMixdown", "ac3pass|dtspass", True, False),
+       DepEntry("AudioEncoderActual", "AudioTrackDRCSlider", "ac3pass|dtspass", True, False),
+       DepEntry("AudioEncoderActual", "drc_label", "ac3pass|dtspass", True, False),
        DepEntry("x264_bframes", "x264_bpyramid", "<2", True, False),
        DepEntry("x264_bframes", "x264_direct", "0", True, False),
        DepEntry("x264_bframes", "x264_b_adapt", "0", True, False),
index 1946f0ba888d2af7dbde2464f50f324485b80537..e50ca054c92181f35f12d1fd7626fe25b1ac92f2 100644 (file)
@@ -1999,7 +1999,8 @@ static value_map_t acodec_xlat[] =
 {
        {"AAC (faac)", "faac"},
        {"AAC (CoreAudio)", "faac"},
-       {"AC3 Passthru", "ac3"},
+       {"AC3 Passthru", "ac3pass"},
+       {"DTS Passthru", "dtspass"},
        {"MP3 (lame)", "lame"},
        {"Vorbis (vorbis)", "vorbis"},
        {NULL,NULL}
index 0680a88fcf60b80acb8f8248e4feda8087fe30a9..6d3261638d7c4fc26ad31b5cdfd10fabfbe37efe 100644 (file)
@@ -550,7 +550,7 @@ audio_list_refresh(signal_user_data_t *ud)
                                s_drc = g_strdup_printf("%.1f", drc);
 
                        if (icodec == HB_ACODEC_MASK)
-                               codec = ghb_select_audio_codec_str(ud, itrack);
+                               codec = ghb_select_audio_codec_str(ud->settings, icodec, itrack);
 
                        gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
                                // These are displayed in list
index 35417cb6c65805f1d955f3660aad4c06e47d1c9a..0c9ac629eb2f3e2dc936ee3302d64d5d6b361b9c 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 */
@@ -255,6 +255,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 +265,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 +906,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 +918,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;
index bba48350c83bf6f74f472c7638a8fd0e533dbcbd..fcb4d4d046e54ca37b9a621559a0febd0ed31c3e 100644 (file)
@@ -307,16 +307,21 @@ struct hb_job_s
 
 /* Audio starts here */
 /* Audio Codecs */
-#define HB_ACODEC_MASK   0x00FF00
-#define HB_ACODEC_FAAC   0x000100
-#define HB_ACODEC_LAME   0x000200
-#define HB_ACODEC_VORBIS 0x000400
-#define HB_ACODEC_AC3    0x000800
-#define HB_ACODEC_MPGA   0x001000
-#define HB_ACODEC_LPCM   0x002000
-#define HB_ACODEC_DCA    0x004000
-#define HB_ACODEC_FFMPEG 0x008000
-#define HB_ACODEC_CA_AAC 0x010000
+#define HB_ACODEC_MASK      0x000FFF00
+#define HB_ACODEC_FAAC      0x00000100
+#define HB_ACODEC_LAME      0x00000200
+#define HB_ACODEC_VORBIS    0x00000400
+#define HB_ACODEC_AC3       0x00000800
+#define HB_ACODEC_MPGA      0x00001000
+#define HB_ACODEC_LPCM      0x00002000
+#define HB_ACODEC_DCA       0x00004000
+#define HB_ACODEC_FFMPEG    0x00008000
+#define HB_ACODEC_CA_AAC    0x00010000
+#define HB_ACODEC_PASS_FLAG 0x40000000
+#define HB_ACODEC_PASS_MASK (HB_ACODEC_AC3 | HB_ACODEC_DCA)
+#define HB_ACODEC_AC3_PASS  (HB_ACODEC_AC3 | HB_ACODEC_PASS_FLAG)
+#define HB_ACODEC_DCA_PASS  (HB_ACODEC_DCA | HB_ACODEC_PASS_FLAG)
+#define HB_ACODEC_ANY       (HB_ACODEC_MASK | HB_ACODEC_PASS_FLAG)
 
 /* Audio Mixdown */
 /* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
@@ -771,6 +776,7 @@ extern hb_work_object_t hb_enclame;
 extern hb_work_object_t hb_encvorbis;
 extern hb_work_object_t hb_muxer;
 extern hb_work_object_t hb_encca_aac;
+extern hb_work_object_t hb_encac3;
 
 #define FILTER_OK      0
 #define FILTER_DELAY   1
index 785bf6aefa146a5917f7f008c017f2f9d65cc973..0958a9139beb00b871a7c30e36b5ae7e02f5de22 100644 (file)
@@ -259,7 +259,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
     double frame_dur = (6. * 256. * 90000.) / pv->rate;
 
     /* AC3 passthrough: don't decode the AC3 frame */
-    if( audio->config.out.codec == HB_ACODEC_AC3 )
+    if( audio->config.out.codec == HB_ACODEC_AC3_PASS )
     {
         buf = hb_buffer_init( size );
         memcpy( buf->data, pv->frame, size );
index abf7ed179f8cee5a86ca44e56d4d414f8fcf6271..bbdd4d668e622bfc41d1f58957c5c1b6677670f4 100644 (file)
@@ -111,6 +111,7 @@ struct hb_work_private_s
     struct SwsContext *sws_context; // if we have to rescale or convert color space
     hb_downmix_t    *downmix;
     hb_sample_t     *downmix_buffer;
+    hb_chan_map_t   *out_map;
 };
 
 static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *data, int size );
@@ -203,13 +204,25 @@ static int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
     pv->context = avcodec_alloc_context();
     hb_avcodec_open( pv->context, codec );
 
-    if ( w->audio != NULL &&
-         hb_need_downmix( w->audio->config.in.channel_layout, 
-                          w->audio->config.out.mixdown) )
+    if ( w->audio != NULL )
     {
-        pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, 
-                                      w->audio->config.out.mixdown);
-        hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_qt_chan_map );
+        if ( w->audio->config.out.codec == HB_ACODEC_AC3 )
+        {
+            // ffmpegs audio encoder expect an smpte chan map as input.
+            // So we need to map the decoders output to smpte.
+            pv->out_map = &hb_smpte_chan_map;
+        }
+        else
+        {
+            pv->out_map = &hb_qt_chan_map;
+        }
+        if ( hb_need_downmix( w->audio->config.in.channel_layout, 
+                              w->audio->config.out.mixdown) )
+        {
+            pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, 
+                                          w->audio->config.out.mixdown);
+            hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, pv->out_map );
+        }
     }
 
     return 0;
@@ -1129,13 +1142,25 @@ static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job )
     pv->pts_next = -1;
     pv->pts = -1;
 
-    if ( w->audio != NULL &&
-         hb_need_downmix( w->audio->config.in.channel_layout, 
-                          w->audio->config.out.mixdown) )
+    if ( w->audio != NULL )
     {
-        pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, 
-                                      w->audio->config.out.mixdown);
-        hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_qt_chan_map );
+        if ( w->audio->config.out.codec == HB_ACODEC_AC3 )
+        {
+            // ffmpegs audio encoder expect an smpte chan map as input.
+            // So we need to map the decoders output to smpte.
+            pv->out_map = &hb_smpte_chan_map;
+        }
+        else
+        {
+            pv->out_map = &hb_qt_chan_map;
+        }
+        if ( hb_need_downmix( w->audio->config.in.channel_layout, 
+                              w->audio->config.out.mixdown) )
+        {
+            pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, 
+                                          w->audio->config.out.mixdown);
+            hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, pv->out_map );
+        }
     }
 
     return 0;
@@ -1308,7 +1333,7 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat
                     fl32[i] = buffer[i];
                 }
                 int n_ch_samples = nsamples / context->channels;
-                hb_layout_remap( &hb_smpte_chan_map, &hb_qt_chan_map,
+                hb_layout_remap( &hb_smpte_chan_map, pv->out_map,
                                  audio->config.in.channel_layout, 
                                  fl32, n_ch_samples );
             }
index 89c2b1c177c76d7b2de193c500a57b448ae7bc85..ea4cb560cb13c91a745a327dfb09589b17d7a206 100644 (file)
@@ -231,7 +231,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
     double frame_dur = (double)(pv->frame_length & ~0xFF) / (double)pv->rate * 90000.;
 
     /* DCA passthrough: don't decode the DCA frame */
-    if( audio->config.out.codec == HB_ACODEC_DCA )
+    if( audio->config.out.codec == HB_ACODEC_DCA_PASS )
     {
         buf = hb_buffer_init( pv->size );
         memcpy( buf->data, pv->frame, pv->size );
diff --git a/libhb/encac3.c b/libhb/encac3.c
new file mode 100644 (file)
index 0000000..5c45b98
--- /dev/null
@@ -0,0 +1,257 @@
+/* $Id: encac3.c,v 1.23 2005/10/13 23:47:06 titer Exp $
+
+   This file is part of the HandBrake source code.
+   Homepage: <http://handbrake.fr/>.
+   It may be used under the terms of the GNU General Public License. */
+
+#include "hb.h"
+#include "hbffmpeg.h"
+#include "downmix.h"
+
+struct hb_work_private_s
+{
+    hb_job_t       * job;
+    AVCodecContext * context;
+
+    int              out_discrete_channels;
+    unsigned long    input_samples;
+    unsigned long    output_bytes;
+    hb_list_t      * list;
+    uint8_t        * buf;
+    int16_t        * samples;
+};
+
+int  encac3Init( hb_work_object_t *, hb_job_t * );
+int  encac3Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void encac3Close( hb_work_object_t * );
+
+#define AC3_SAMPLES_PER_FRAME 1536
+#define AC3_MAX_CODED_FRAME_SIZE 3840
+
+hb_work_object_t hb_encac3 =
+{
+    WORK_ENCAC3,
+    "AC-3 encoder (libavcodec)",
+    encac3Init,
+    encac3Work,
+    encac3Close
+};
+
+int encac3Init( hb_work_object_t * w, hb_job_t * job )
+{
+    AVCodec * codec;
+    AVCodecContext * context;
+    hb_audio_t * audio = w->audio;
+
+    hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+    w->private_data = pv;
+
+    pv->job = job;
+
+    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
+    pv->input_samples = AC3_SAMPLES_PER_FRAME * pv->out_discrete_channels;
+    pv->output_bytes = AC3_MAX_CODED_FRAME_SIZE;
+
+    pv->buf = malloc( pv->input_samples * sizeof( float ) );
+    pv->samples = malloc( pv->input_samples * sizeof( int16_t ) );
+
+    codec = avcodec_find_encoder( CODEC_ID_AC3 );
+    if( !codec )
+    {
+        hb_log( "encac3Init: avcodec_find_encoder "
+                "failed" );
+    }
+    context = avcodec_alloc_context();
+
+    context->channel_layout = CH_LAYOUT_STEREO;
+    switch( audio->config.out.mixdown )
+    {
+        case HB_AMIXDOWN_MONO:
+            context->channel_layout = CH_LAYOUT_MONO;
+            break;
+
+        case HB_AMIXDOWN_STEREO:
+        case HB_AMIXDOWN_DOLBY:
+        case HB_AMIXDOWN_DOLBYPLII:
+            context->channel_layout = CH_LAYOUT_STEREO;
+            break;
+
+        case HB_AMIXDOWN_6CH:
+            context->channel_layout = CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY;
+            break;
+
+        default:
+            hb_log(" encac3Init: bad mixdown" );
+            break;
+    }
+
+    context->bit_rate = audio->config.out.bitrate * 1000;
+    context->sample_rate = audio->config.out.samplerate;
+    context->channels = pv->out_discrete_channels;
+
+    if( hb_avcodec_open( context, codec ) )
+    {
+        hb_log( "encac3Init: avcodec_open failed" );
+    }
+    pv->context = context;
+
+    pv->list = hb_list_init();
+
+    return 0;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+void encac3Close( hb_work_object_t * w )
+{
+    hb_work_private_t * pv = w->private_data;
+
+    if ( pv )
+    {
+        if( pv->context )
+        {
+            hb_deep_log( 2, "encac3: closing libavcodec" );
+            if ( pv->context->codec )
+                avcodec_flush_buffers( pv->context );
+            hb_avcodec_close( pv->context );
+        }
+
+        if ( pv->buf )
+        {
+            free( pv->buf );
+            pv->buf = NULL;
+        }
+
+        if ( pv->samples )
+        {
+            free( pv->samples );
+            pv->samples = NULL;
+        }
+
+        if ( pv->list )
+            hb_list_empty( &pv->list );
+
+        free( pv );
+        w->private_data = NULL;
+    }
+}
+
+static hb_buffer_t * Encode( hb_work_object_t * w )
+{
+    hb_work_private_t * pv = w->private_data;
+    uint64_t pts, pos;
+    hb_audio_t * audio = w->audio;
+    hb_buffer_t * buf;
+    int ii;
+
+    if( hb_list_bytes( pv->list ) < pv->input_samples * sizeof( float ) )
+    {
+        return NULL;
+    }
+
+    hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ),
+                      &pts, &pos);
+
+    hb_chan_map_t *map = NULL;
+    if ( audio->config.in.codec == HB_ACODEC_AC3 )
+    {
+        map = &hb_ac3_chan_map;
+    }
+    else if ( audio->config.in.codec == HB_ACODEC_DCA )
+    {
+        map = &hb_qt_chan_map;
+    }
+    if ( map )
+    {
+        int layout;
+        switch (audio->config.out.mixdown)
+        {
+            case HB_AMIXDOWN_MONO:
+                layout = HB_INPUT_CH_LAYOUT_MONO;
+                break;
+            case HB_AMIXDOWN_STEREO:
+            case HB_AMIXDOWN_DOLBY:
+            case HB_AMIXDOWN_DOLBYPLII:
+                layout = HB_INPUT_CH_LAYOUT_STEREO;
+                break;
+            case HB_AMIXDOWN_6CH:
+            default:
+                layout = HB_INPUT_CH_LAYOUT_3F2R | HB_INPUT_CH_LAYOUT_HAS_LFE;
+                break;
+        }
+        hb_layout_remap( map, &hb_smpte_chan_map, layout, 
+                        (float*)pv->buf, AC3_SAMPLES_PER_FRAME);
+    }
+    
+    for (ii = 0; ii < pv->input_samples; ii++)
+    {
+        pv->samples[ii] = (int16_t)((float*)pv->buf)[ii];
+    }
+
+    buf = hb_buffer_init( pv->output_bytes );
+    buf->size = avcodec_encode_audio( pv->context, buf->data, buf->alloc,
+                                          pv->samples );
+
+    buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
+    buf->stop  = buf->start + 90000 * AC3_SAMPLES_PER_FRAME / audio->config.out.samplerate;
+
+    buf->frametype = HB_FRAME_AUDIO;
+
+    if ( !buf->size )
+    {
+        hb_buffer_close( &buf );
+        return Encode( w );
+    }
+    else if (buf->size < 0)
+    {
+        hb_log( "encac3: avcodec_encode_audio failed" );
+        hb_buffer_close( &buf );
+        return NULL;
+    }
+
+    return buf;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+int encac3Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                    hb_buffer_t ** buf_out )
+{
+    hb_work_private_t * pv = w->private_data;
+    hb_buffer_t * in = *buf_in, * buf;
+
+    if ( in->size <= 0 )
+    {
+        /* EOF on input - send it downstream & say we're done */
+        *buf_out = in;
+        *buf_in = NULL;
+       return HB_WORK_DONE;
+    }
+
+    if ( pv->context == NULL || pv->context->codec == NULL )
+    {
+        // No encoder context. Nothing we can do.
+        return HB_WORK_OK;
+    }
+
+    hb_list_add( pv->list, in );
+    *buf_in = NULL;
+
+    *buf_out = buf = Encode( w );
+
+    while ( buf )
+    {
+        buf->next = Encode( w );
+        buf = buf->next;
+    }
+
+    return HB_WORK_OK;
+}
+
+
index fcb4a55dfa41909972da37181b38fa58edc462b4..f7489c162e97d81957bf2ca9e0da0e26235f2c52 100644 (file)
@@ -346,6 +346,7 @@ hb_handle_t * hb_init( int verbose, int update_check )
 #ifdef __APPLE__
        hb_register( &hb_encca_aac );
 #endif
+       hb_register( &hb_encac3 );
     
     return h;
 }
@@ -450,6 +451,7 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
 #ifdef __APPLE__
        hb_register( &hb_encca_aac );
 #endif
+       hb_register( &hb_encac3 );
 
        return h;
 }
index 30bf022d5c6c562be490fbb7e6b851fd3a74f199..b6fbd1ddbd75e07b42783155ecfa7c89e4513405 100644 (file)
@@ -355,6 +355,7 @@ enum
     WORK_ENCLAME,
     WORK_ENCVORBIS,
     WORK_ENC_CA_AAC,
+    WORK_ENCAC3,
     WORK_MUX
 };
 
index aa320e9aa873383f5f6dda2ab87aac8f90b2dd8c..073b39f450f1623072731c4b16b6eb2e162de3c1 100644 (file)
@@ -167,11 +167,13 @@ static int MKVInit( hb_mux_object_t * m )
         switch (audio->config.out.codec)
         {
             case HB_ACODEC_DCA:
+            case HB_ACODEC_DCA_PASS:
                 track->codecPrivate = NULL;
                 track->codecPrivateSize = 0;
                 track->codecID = MK_ACODEC_DTS;
                 break;
             case HB_ACODEC_AC3:
+            case HB_ACODEC_AC3_PASS:
                 track->codecPrivate = NULL;
                 track->codecPrivateSize = 0;
                 track->codecID = MK_ACODEC_AC3;
@@ -228,8 +230,8 @@ static int MKVInit( hb_mux_object_t * m )
         track->trackType = MK_TRACK_AUDIO;
         track->language = audio->config.lang.iso639_2;
         track->extra.audio.samplingFreq = (float)audio->config.out.samplerate;
-        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)
         {
             track->extra.audio.channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->config.in.channel_layout);
         }
index bc523f836634c587c77f3a5680936a13a28bf4a7..5225ea5235bf26e7f1da1eb2f500932fa1f7acb6 100644 (file)
@@ -63,6 +63,14 @@ static int MP4TuneTrackDurationPerChunk( hb_mux_object_t* m, MP4TrackId trackId
     return 1;
 }
 
+static const uint16_t ac3_sample_rate_tab[3] = { 48000, 44100, 32000 };
+/* possible bitrates */
+static const uint16_t ac3_bitrate_tab[19] = {
+    32, 40, 48, 56, 64, 80, 96, 112, 128,
+    160, 192, 224, 256, 320, 384, 448, 512, 576, 640
+};  
+
+
 /**********************************************************************
  * MP4Init
  **********************************************************************
@@ -225,106 +233,142 @@ static int MP4Init( hb_mux_object_t * m )
         mux_data = calloc(1, sizeof( hb_mux_data_t ) );
         audio->priv.mux_data = mux_data;
 
-        if( audio->config.out.codec == HB_ACODEC_AC3 )
+        if( audio->config.out.codec == HB_ACODEC_AC3_PASS )
         {
-            uint8_t fscod = 0;
             uint8_t bsid = audio->config.in.version;
             uint8_t bsmod = audio->config.in.mode;
             uint8_t acmod = audio->config.flags.ac3 & 0x7;
             uint8_t lfeon = (audio->config.flags.ac3 & A52_LFE) ? 1 : 0;
             uint8_t bit_rate_code = 0;
+            int ii, jj;
+            int freq = audio->config.in.samplerate;
+            int bitrate = audio->config.in.bitrate;
+            int sr_shift, sr_code;
 
-            /*
-             * Rewrite AC3 information into correct format for dac3 atom
-             */
-            switch( audio->config.in.samplerate )
+            for (ii = 0; ii < 3; ii++)
             {
-            case 48000:
-                fscod = 0;
-                break;
-            case 44100:
-                fscod = 1;
-                break;
-            case 32000:
-                fscod = 2;
-                break;
-            default:
-                /*
-                 * Error value, tells decoder to not decode this audio.
-                 */
-                fscod = 3;
-                break;
+                for (jj = 0; jj < 3; jj++)
+                {
+                    if ((ac3_sample_rate_tab[jj] >> ii) == freq)
+                    {
+                        break;
+                    }
+                }
             }
+            if ( ii >= 3 )
+            {
+                hb_error("Unknown AC3 samplerate");
+                ii = jj = 0;
+            }
+            sr_shift = ii;
+            sr_code = jj;
+            for (ii = 0; ii < 19; ii++)
+            {
+                if ((ac3_bitrate_tab[ii] >> sr_shift)*1000 == bitrate)
+                    break;
+            }
+            if ( ii >= 19 )
+            {
+                hb_error("Unknown AC3 bitrate");
+                ii = 0;
+            }
+            bit_rate_code = ii;
+
+            mux_data->track = MP4AddAC3AudioTrack(
+                m->file,
+                audio->config.in.samplerate, 
+                sr_code,
+                bsid,
+                bsmod,
+                acmod,
+                lfeon,
+                bit_rate_code);
+
+            /* Tune track chunk duration */
+            MP4TuneTrackDurationPerChunk( m, mux_data->track );
 
-            switch( audio->config.in.bitrate )
+            if (audio->config.out.name == NULL) {
+                MP4SetTrackBytesProperty(
+                    m->file, mux_data->track,
+                    "udta.name.value",
+                    (const uint8_t*)"Surround", strlen("Surround"));
+            }
+            else {
+                MP4SetTrackBytesProperty(
+                    m->file, mux_data->track,
+                    "udta.name.value",
+                    (const uint8_t*)(audio->config.out.name),
+                    strlen(audio->config.out.name));
+            }
+        }
+        else if( audio->config.out.codec == HB_ACODEC_AC3 )
+        {
+            uint8_t bsid = 8;
+            uint8_t bsmod = 0;
+            uint8_t acmod = 2;
+            uint8_t lfeon = 0;
+            uint8_t bit_rate_code = 0;
+            int ii, jj;
+            int freq = audio->config.out.samplerate;
+            int bitrate = audio->config.out.bitrate;
+            int sr_shift, sr_code;
+
+            for (ii = 0; ii < 3; ii++)
+            {
+                for (jj = 0; jj < 3; jj++)
+                {
+                    if ((ac3_sample_rate_tab[jj] >> ii) == freq)
+                    {
+                        break;
+                    }
+                }
+            }
+            if ( ii >= 3 )
+            {
+                hb_error("Unknown AC3 samplerate");
+                ii = jj = 0;
+            }
+            sr_shift = ii;
+            sr_code = jj;
+            bsid = 8 + ii;
+            for (ii = 0; ii < 19; ii++)
+            {
+                if ((ac3_bitrate_tab[ii] >> sr_shift)*1000 == bitrate)
+                    break;
+            }
+            if ( ii >= 19 )
             {
-            case 32000:
-                bit_rate_code = 0;
-                break;
-            case 40000:
-                bit_rate_code = 1;
-                break;
-            case 48000:
-                bit_rate_code = 2;
-                break;
-            case 56000:
-                bit_rate_code = 3;
-                break;
-            case 64000:
-                bit_rate_code = 4;
-                break;
-            case 80000:
-                bit_rate_code = 5;
-                break;
-            case 96000:
-                bit_rate_code = 6;
-                break;
-            case 112000:
-                bit_rate_code = 7;
-                break;
-            case 128000:
-                bit_rate_code = 8;
-                break;
-            case 160000:
-                bit_rate_code = 9;
-                break;
-            case 192000:
-                bit_rate_code = 10;
-                break;
-            case 224000:
-                bit_rate_code = 11;
-                break;
-            case 256000:
-                bit_rate_code = 12;
-                break;
-            case 320000:
-                bit_rate_code = 13;
-                break;
-            case 384000:
-                bit_rate_code = 14;
-                break;
-            case 448000:
-                bit_rate_code = 15;
-                break;
-            case 512000:
-                bit_rate_code = 16;
-                break;
-            case 576000:
-                bit_rate_code = 17;
-                break;
-            case 640000:
-                bit_rate_code = 18;
-                break;
-            default:
                 hb_error("Unknown AC3 bitrate");
-                bit_rate_code = 0;
-                break;
+                ii = 0;
+            }
+            bit_rate_code = ii;
+
+            switch( audio->config.out.mixdown )
+            {
+                case HB_AMIXDOWN_MONO:
+                    acmod = 1;
+                    break;
+
+                case HB_AMIXDOWN_STEREO:
+                case HB_AMIXDOWN_DOLBY:
+                case HB_AMIXDOWN_DOLBYPLII:
+                    acmod = 2;
+                    break;
+
+                case HB_AMIXDOWN_6CH:
+                    acmod = 7;
+                    lfeon = 1;
+                    break;
+
+                default:
+                    hb_log(" MP4Init: bad mixdown" );
+                    break;
             }
 
             mux_data->track = MP4AddAC3AudioTrack(
                 m->file,
                 audio->config.out.samplerate, 
-                fscod,
+                sr_code,
                 bsid,
                 bsmod,
                 acmod,
@@ -347,8 +391,10 @@ static int MP4Init( hb_mux_object_t * m )
                     (const uint8_t*)(audio->config.out.name),
                     strlen(audio->config.out.name));
             }
-        } else if( audio->config.out.codec == HB_ACODEC_FAAC ||
-                   audio->config.out.codec == HB_ACODEC_CA_AAC ) {
+        } 
+        else if( audio->config.out.codec == HB_ACODEC_FAAC ||
+                 audio->config.out.codec == HB_ACODEC_CA_AAC ) 
+        {
             mux_data->track = MP4AddAudioTrack(
                 m->file,
                 audio->config.out.samplerate, 1024, MP4_MPEG4_AUDIO_TYPE );
index 58628f316866c15b28c90f7c795747fe46941413..acc782e4ab415cb4eb36b6a366bf96c479e5e42f 100644 (file)
@@ -898,7 +898,7 @@ void syncAudioClose( hb_work_object_t * w )
     hb_work_private_t * pv    = w->private_data;
     hb_sync_audio_t   * sync  = &pv->type.audio;
 
-    if( w->audio->config.out.codec == HB_ACODEC_AC3 )
+    if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS )
     {
         free( sync->ac3_buf );
     }
@@ -1073,7 +1073,7 @@ static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
          * Or in the case of DCA, skip some frames from the
          * other streams.
          */
-        if( w->audio->config.out.codec == HB_ACODEC_DCA )
+        if( w->audio->config.out.codec == HB_ACODEC_DCA_PASS )
         {
             hb_log( "sync: audio gap %d ms. Skipping frames. Audio %d"
                     "  start %"PRId64", next %"PRId64,
@@ -1131,8 +1131,8 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
     w->audio = hb_list_item( title->list_audio, i );
     w->fifo_in = w->audio->priv.fifo_raw;
 
-    if( w->audio->config.out.codec == HB_ACODEC_AC3 ||
-        w->audio->config.out.codec == HB_ACODEC_DCA )
+    if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
+        w->audio->config.out.codec == HB_ACODEC_DCA_PASS )
     {
         w->fifo_out = w->audio->priv.fifo_out;
     }
@@ -1141,7 +1141,7 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
         w->fifo_out = w->audio->priv.fifo_sync;
     }
 
-    if( w->audio->config.out.codec == HB_ACODEC_AC3 )
+    if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS )
     {
         /* Have a silent AC-3 frame ready in case we have to fill a
            gap */
@@ -1199,8 +1199,8 @@ static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
     sync->next_pts += duration;
 
     if( audio->config.in.samplerate == audio->config.out.samplerate ||
-        audio->config.out.codec == HB_ACODEC_AC3 ||
-        audio->config.out.codec == HB_ACODEC_DCA )
+        audio->config.out.codec == HB_ACODEC_AC3_PASS ||
+        audio->config.out.codec == HB_ACODEC_DCA_PASS )
     {
         /*
          * If we don't have to do sample rate conversion or this audio is 
@@ -1271,7 +1271,7 @@ static void InsertSilence( hb_work_object_t * w, int64_t duration )
 
     while ( --frame_count >= 0 )
     {
-        if( w->audio->config.out.codec == HB_ACODEC_AC3 )
+        if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS )
         {
             buf        = hb_buffer_init( sync->ac3_size );
             buf->start = sync->next_pts;
index 3c3346d19ff0150a9b901d0047dd6312be87e16f..b7dda2736172d03ec0f68315cf2d76a5a1884fca 100644 (file)
@@ -128,7 +128,8 @@ hb_work_object_t * hb_codec_encoder( int codec )
         case HB_ACODEC_FAAC:   return hb_get_work( WORK_ENCFAAC );
         case HB_ACODEC_LAME:   return hb_get_work( WORK_ENCLAME );
         case HB_ACODEC_VORBIS: return hb_get_work( WORK_ENCVORBIS );
-        case HB_ACODEC_CA_AAC:  return hb_get_work( WORK_ENC_CA_AAC );
+        case HB_ACODEC_CA_AAC: return hb_get_work( WORK_ENC_CA_AAC );
+        case HB_ACODEC_AC3:    return hb_get_work( WORK_ENCAC3 );
     }
     return NULL;
 }
@@ -344,7 +345,7 @@ void hb_display_job_info( hb_job_t * job )
                 hb_log( "     + bitrate: %d kbps, samplerate: %d Hz", audio->config.in.bitrate / 1000, audio->config.in.samplerate );
             }
 
-            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 (j = 0; j < hb_audio_mixdowns_count; j++)
                 {
@@ -355,22 +356,24 @@ void hb_display_job_info( hb_job_t * job )
                 }
             }
 
-            if ( audio->config.out.dynamic_range_compression && (audio->config.out.codec != HB_ACODEC_AC3) && (audio->config.out.codec != HB_ACODEC_DCA))
+            if ( audio->config.out.dynamic_range_compression && (audio->config.out.codec != HB_ACODEC_AC3_PASS) && (audio->config.out.codec != HB_ACODEC_DCA_PASS))
             {
                 hb_log("   + dynamic range compression: %f", audio->config.out.dynamic_range_compression);
             }
             
-            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) )
             {
-                hb_log( "   + %s passthrough", (audio->config.out.codec == HB_ACODEC_AC3) ?
+                hb_log( "   + %s passthrough", (audio->config.out.codec == HB_ACODEC_AC3_PASS) ?
                     "AC3" : "DCA" );
             }
             else
             {
-                hb_log( "   + encoder: %s", ( audio->config.out.codec == HB_ACODEC_FAAC ) ?
-                    "faac" : ( ( audio->config.out.codec == HB_ACODEC_LAME ) ?
-                    "lame" : ( ( audio->config.out.codec == HB_ACODEC_CA_AAC ) ?
-                              "ca_aac" : "vorbis"  ) ) );
+                hb_log( "   + encoder: %s", 
+                    ( audio->config.out.codec == HB_ACODEC_FAAC ) ?  "faac" : 
+                    ( ( audio->config.out.codec == HB_ACODEC_LAME ) ?  "lame" : 
+                    ( ( audio->config.out.codec == HB_ACODEC_CA_AAC ) ?  "ca_aac" : 
+                    ( ( audio->config.out.codec == HB_ACODEC_AC3 ) ?  "ffac3" : 
+                    "vorbis"  ) ) ) );
                 hb_log( "     + bitrate: %d kbps, samplerate: %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );            
             }
         }
@@ -513,8 +516,8 @@ static void do_job( hb_job_t * job, int cpu_count )
     for( i = 0; i < hb_list_count( title->list_audio ); )
     {
         audio = hb_list_item( title->list_audio, i );
-        if( ( ( audio->config.out.codec == HB_ACODEC_AC3 ) && ( audio->config.in.codec != HB_ACODEC_AC3 ) ) ||
-            ( ( audio->config.out.codec == HB_ACODEC_DCA ) && ( audio->config.in.codec != HB_ACODEC_DCA ) ) )
+        if( ( ( audio->config.out.codec == HB_ACODEC_AC3_PASS ) && ( audio->config.in.codec != HB_ACODEC_AC3 ) ) ||
+            ( ( audio->config.out.codec == HB_ACODEC_DCA_PASS ) && ( audio->config.in.codec != HB_ACODEC_DCA ) ) )
         {
             hb_log( "Passthru requested and input codec is not the same as output codec for track %d",
                     audio->config.out.track );
@@ -522,14 +525,21 @@ static void do_job( hb_job_t * job, int cpu_count )
             free( audio );
             continue;
         }
-        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 &&
             audio->config.out.samplerate > 48000 )
         {
             hb_log( "Sample rate %d not supported.  Down-sampling to 48kHz.",
                     audio->config.out.samplerate );
             audio->config.out.samplerate = 48000;
         }
+        if( audio->config.out.codec == HB_ACODEC_AC3 && 
+            audio->config.out.bitrate > 640 )
+        {
+            hb_log( "Bitrate %d not supported.  Reducing to 640Kbps.",
+                    audio->config.out.bitrate );
+            audio->config.out.bitrate = 640;
+        }
         if ( audio->config.in.codec == HB_ACODEC_FFMPEG )
         {
             if ( aud_id_uses[audio->id] )
@@ -570,8 +580,8 @@ static void do_job( hb_job_t * job, int cpu_count )
             /* sense-check the requested mixdown */
 
             if( audio->config.out.mixdown == 0 &&
-                audio->config.out.codec != HB_ACODEC_AC3 && 
-                audio->config.out.codec != HB_ACODEC_DCA )
+                audio->config.out.codec != HB_ACODEC_AC3_PASS && 
+                audio->config.out.codec != HB_ACODEC_DCA_PASS )
             {
                 /*
                  * Mixdown wasn't specified and this is not pass-through,
@@ -863,8 +873,8 @@ static void do_job( hb_job_t * job, int cpu_count )
             /*
             * Audio Encoder Thread
             */
-            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 )
             {
                 /*
                 * Add the encoder thread if not doing AC-3 pass through
index c3598da3f49d97436cd0da137ef9197ca4bbdaf8..b32d90d1f24eeac50c4e0f29423e52c16ea49ef1 100644 (file)
@@ -110,21 +110,32 @@ static NSDictionary *bitRate384 = nil;
                                                                          nil]];
                [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
                                                                          NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioCodecName,
-                                                                         [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioCodec,
+                                                                         [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioCodec,
                                                                          [NSNumber numberWithBool: YES], keyAudioMP4,
                                                                          [NSNumber numberWithBool: YES], keyAudioMKV,
-                                                                         [NSNumber numberWithBool: YES], keyAudioMustMatchTrack,
+                                                                         [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioMustMatchTrack,
                                                                          [NSNumber numberWithInt: 32], keyAudioMinimumBitrate,
                                                                          [NSNumber numberWithInt: 384], keyAudioMaximumBitrate,
                                                                          [NSNumber numberWithInt: 32], keyAudioMinimumBitrate6Channel,
                                                                          [NSNumber numberWithInt: 384], keyAudioMaximumBitrate6Channel,
                                                                          nil]];
+               [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
+                                                                         NSLocalizedString(@"AC3", @"AC3"), keyAudioCodecName,
+                                                                         [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioCodec,
+                                                                         [NSNumber numberWithBool: YES], keyAudioMP4,
+                                                                         [NSNumber numberWithBool: YES], keyAudioMKV,
+                                                                         [NSNumber numberWithBool: NO], keyAudioMustMatchTrack,
+                                                                         [NSNumber numberWithInt: 32], keyAudioMinimumBitrate,
+                                                                         [NSNumber numberWithInt: 640], keyAudioMaximumBitrate,
+                                                                         [NSNumber numberWithInt: 32], keyAudioMinimumBitrate6Channel,
+                                                                         [NSNumber numberWithInt: 640], keyAudioMaximumBitrate6Channel,
+                                                                         nil]];
                [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
                                                                          NSLocalizedString(@"DTS Passthru", @"DTS Passthru"), keyAudioCodecName,
-                                                                         [NSNumber numberWithInt: HB_ACODEC_DCA], keyAudioCodec,
+                                                                         [NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioCodec,
                                                                          [NSNumber numberWithBool: NO], keyAudioMP4,
                                                                          [NSNumber numberWithBool: YES], keyAudioMKV,
-                                                                         [NSNumber numberWithBool: YES], keyAudioMustMatchTrack,
+                                                                         [NSNumber numberWithInt: HB_ACODEC_DCA], keyAudioMustMatchTrack,
                                                                          [NSNumber numberWithInt: 32], keyAudioMinimumBitrate,
                                                                          [NSNumber numberWithInt: 384], keyAudioMaximumBitrate,
                                                                          [NSNumber numberWithInt: 32], keyAudioMinimumBitrate6Channel,
@@ -214,7 +225,7 @@ static NSDictionary *bitRate384 = nil;
                        
                        //      Now we make sure if DTS or AC3 is not available in the track it is not put in the codec list, but in a general way
                        if (YES == [[dict objectForKey: keyAudioMustMatchTrack] boolValue]) {
-                               if ([[dict objectForKey: keyAudioCodec] intValue] != [[[self track] objectForKey: keyAudioInputCodec] intValue]) {
+                               if ([[dict objectForKey: keyAudioMustMatchTrack] intValue] != [[[self track] objectForKey: keyAudioInputCodec] intValue]) {
                                        goodToAdd = NO;
                                }
                        }
@@ -250,18 +261,18 @@ static NSDictionary *bitRate384 = nil;
        int trackCodec = [[track objectForKey: keyAudioInputCodec] intValue];
        int codecCodec = [[codec objectForKey: keyAudioCodec] intValue];
 
-       if (HB_ACODEC_AC3 == trackCodec && HB_ACODEC_AC3 == codecCodec) {
+       if (HB_ACODEC_AC3 == trackCodec && HB_ACODEC_AC3_PASS == codecCodec) {
                [retval addObject: [NSDictionary dictionaryWithObjectsAndKeys:
                                                        NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioMixdownName,
-                                                       [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioMixdown,
+                                                       [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioMixdown,
                                                        [NSNumber numberWithBool: YES], keyAudioMixdownLimitsToTrackBitRate,
                                                        [NSNumber numberWithBool: YES], keyAudioMixdownCanBeDefault,
                                                        nil]];
        }
-       else if (HB_ACODEC_DCA == trackCodec && HB_ACODEC_DCA == codecCodec) {
+       else if (HB_ACODEC_DCA == trackCodec && HB_ACODEC_DCA_PASS == codecCodec) {
                [retval addObject: [NSDictionary dictionaryWithObjectsAndKeys:
                                                        NSLocalizedString(@"DTS Passthru", @"DTS Passthru"), keyAudioMixdownName,
-                                                       [NSNumber numberWithInt: HB_ACODEC_DCA], keyAudioMixdown,
+                                                       [NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioMixdown,
                                                        [NSNumber numberWithBool: YES], keyAudioMixdownLimitsToTrackBitRate,
                                                        [NSNumber numberWithBool: YES], keyAudioMixdownCanBeDefault,
                                                        nil]];
@@ -315,7 +326,7 @@ static NSDictionary *bitRate384 = nil;
                                                                [NSString stringWithUTF8String: hb_audio_mixdowns[4].human_readable_name], keyAudioMixdownName,
                                                                [NSNumber numberWithInt: hb_audio_mixdowns[4].amixdown], keyAudioMixdown,
                                                                [NSNumber numberWithBool: NO], keyAudioMixdownLimitsToTrackBitRate,
-                                                               [NSNumber numberWithBool: NO], keyAudioMixdownCanBeDefault,
+                                                               [NSNumber numberWithBool: (HB_ACODEC_AC3 == trackCodec) ? NO : YES], keyAudioMixdownCanBeDefault,
                                                                nil]];
                }
                
@@ -323,20 +334,20 @@ static NSDictionary *bitRate384 = nil;
                //      situations, the following code will never add anything to the returned array.  I am leaving this in place for
                //      historical reasons.
                /* do we want to add an AC-3 passthrough option? */
-               if (HB_ACODEC_AC3 == trackCodec && HB_ACODEC_AC3 == codecCodec) {
+               if (HB_ACODEC_AC3 == trackCodec && HB_ACODEC_AC3_PASS == codecCodec) {
                        [retval addObject: [NSDictionary dictionaryWithObjectsAndKeys:
                                                                [NSString stringWithUTF8String: hb_audio_mixdowns[5].human_readable_name], keyAudioMixdownName,
-                                                               [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioMixdown,
+                                                               [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioMixdown,
                                                                [NSNumber numberWithBool: YES], keyAudioMixdownLimitsToTrackBitRate,
                                                                [NSNumber numberWithBool: YES], keyAudioMixdownCanBeDefault,
                                                                nil]];
                }
                        
                /* do we want to add a DTS Passthru option ? HB_ACODEC_DCA*/
-               if (HB_ACODEC_DCA == trackCodec && HB_ACODEC_DCA == codecCodec) {
+               if (HB_ACODEC_DCA == trackCodec && HB_ACODEC_DCA_PASS == codecCodec) {
                        [retval addObject: [NSDictionary dictionaryWithObjectsAndKeys:
                                                                [NSString stringWithUTF8String: hb_audio_mixdowns[5].human_readable_name], keyAudioMixdownName,
-                                                               [NSNumber numberWithInt: HB_ACODEC_DCA], keyAudioMixdown,
+                                                               [NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioMixdown,
                                                                [NSNumber numberWithBool: YES], keyAudioMixdownLimitsToTrackBitRate,
                                                                [NSNumber numberWithBool: YES], keyAudioMixdownCanBeDefault,
                                                                nil]];
@@ -386,6 +397,13 @@ static NSDictionary *bitRate384 = nil;
                        }
                }
                
+               //      Now make sure the bitrate does not exceed the track's bitrate
+               if (YES == shouldAdd) {
+                       if (currentBitRate > trackInputBitRate) {
+                               shouldAdd = NO;
+                       }
+               }
+               
                if (YES == shouldAdd) {
                        [permittedBitRates addObject: dict];
                }
@@ -618,7 +636,7 @@ static NSDictionary *bitRate384 = nil;
 
        if (YES == retval) {
                int myMixdown = [[[self mixdown] objectForKey: keyAudioMixdown] intValue];
-               if (HB_ACODEC_AC3 == myMixdown || HB_ACODEC_DCA == myMixdown) {
+               if (HB_ACODEC_AC3_PASS == myMixdown || HB_ACODEC_DCA_PASS == myMixdown) {
                        retval = NO;
                }
        }
@@ -629,7 +647,7 @@ static NSDictionary *bitRate384 = nil;
 
 {
        BOOL retval = [self enabled];
-
+       
        if (YES == retval) {
                int myTrackCodec = [[[self track] objectForKey: keyAudioInputCodec] intValue];
                if (HB_ACODEC_AC3 != myTrackCodec) {
index da58cfbc1977a3fa767c78196f392e34f61b82ee..823dd439f6370fdf47174dd76bc4d58c5ff16a2e 100644 (file)
@@ -253,6 +253,11 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
                                ) {
                                key = @"AAC (CoreAudio)";
                        }
+                       if (YES == [key isEqualToString: @"AC3 Passthru"]) {
+                               if (NO == [newAudio setCodecFromName: key]) {
+                                       key = @"AC3";
+                               }
+                       }
                        //      If our preset wants us to support a codec that the track does not support, instead
                        //      of changing the codec we remove the audio instead.
                        if (YES == [newAudio setCodecFromName: key]) {
index f808b27f7984a46f85c42224baad325be06b1953..73742bcff3858ac9f43a00d846642a77aa48db75 100755 (executable)
@@ -334,7 +334,9 @@ class Display
       
       #Encoders
       case audioTrack["AudioEncoder"]
-        when /AC3 /
+        when /AC3 Pass/
+          audioEncoders << "ac3pass"
+        when /AC3/
           audioEncoders << "ac3"
         when /AAC/
           audioEncoders << "faac"
@@ -581,7 +583,9 @@ class Display
       
       #Encoders
       case audioTrack["AudioEncoder"]
-        when /AC3 /
+        when /AC3 Pass/
+          audioEncoders << "ac3pass"
+        when /AC3/
           audioEncoders << "ac3"
         when /AAC/
           audioEncoders << "faac"
@@ -823,7 +827,9 @@ class Display
 
       #Encoders
       case audioTrack["AudioEncoder"]
-        when /AC3 /
+        when /AC3 Pass/
+          audioEncoders << "ac3pass"
+        when /AC3/
           audioEncoders << "ac3"
         when /AAC/
           audioEncoders << "faac"
@@ -1102,7 +1108,9 @@ class Display
       
       #Encoders
       case audioTrack["AudioEncoder"]
-        when /AC3 /
+        when /AC3 Pass/
+          audioEncoders << "ac3pass"
+        when /AC3/
           audioEncoders << "ac3"
         when /AAC/
           audioEncoders << "faac"
index fe9ef8012892427455259c72b9fe11434f06e2bb..f7253866758415a625215cb4929df19d8a95be76 100644 (file)
@@ -623,7 +623,7 @@ static int HandleEvents( hb_handle_t * h )
                     }
                     if( !acodecs )
                     {
-                        acodecs = strdup("faac,ac3");
+                        acodecs = strdup("faac,ac3pass");
                     }
                     if( !abitrates )
                     {
@@ -796,7 +796,7 @@ static int HandleEvents( hb_handle_t * h )
                     }
                     if( !acodecs )
                     {
-                        acodecs = strdup("faac,ac3");
+                        acodecs = strdup("faac,ac3pass");
                     }
                     if( !abitrates )
                     {
@@ -885,7 +885,7 @@ static int HandleEvents( hb_handle_t * h )
                     }
                     if( !acodecs )
                     {
-                        acodecs = strdup("faac,ac3");
+                        acodecs = strdup("faac,ac3pass");
                     }
                     if( !abitrates )
                     {
@@ -966,7 +966,7 @@ static int HandleEvents( hb_handle_t * h )
                     }
                     if( !acodecs )
                     {
-                        acodecs = strdup("faac,ac3");
+                        acodecs = strdup("faac,ac3pass");
                     }
                     if( !abitrates )
                     {
@@ -2361,14 +2361,16 @@ static void ShowHelp()
 
 #ifdef __APPLE_CC__
     fprintf( out,
-    "    -E, --aencoder <string> Audio encoder(s) (ca_aac/faac/lame/vorbis/ac3/dts) \n"
-    "                            ac3 and dts meaning passthrough\n"
+    "    -E, --aencoder <string> Audio encoder(s)\n"
+    "                                (ca_aac/faac/lame/vorbis/ac3/ac3pass/dtspass)\n"
+    "                            ac3pass and dtspass meaning passthrough\n"
     "                            Separated by commas for more than one audio track.\n"
     "                            (default: guessed)\n" );
 #else
     fprintf( out,
-    "    -E, --aencoder <string> Audio encoder(s) (faac/lame/vorbis/ac3/dts) \n"
-    "                            ac3 and dts meaning passthrough\n"
+    "    -E, --aencoder <string> Audio encoder(s):\n"
+    "                                (faac/lame/vorbis/ac3/ac3pass/dtspass)\n"
+    "                            ac3pass and dtspass meaning passthrough\n"
     "                            Separated by commas for more than one audio track.\n"
     "                            (default: guessed)\n" );
 #endif
@@ -2519,7 +2521,7 @@ static void ShowPresets()
 {
     printf("\n< Apple\n");
 
-    printf("\n   + Universal:  -e x264  -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -X 720 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:bframes=0:8x8dct=0:trellis=0:subme=6\n");
+    printf("\n   + Universal:  -e x264  -q 20.0 -a 1,1 -E faac,ac3pass -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -X 720 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:bframes=0:8x8dct=0:trellis=0:subme=6\n");
 
     printf("\n   + iPod:  -e x264  -b 700 -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4 -I -X 320 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:subme=6:8x8dct=0:trellis=0\n");
 
@@ -2527,7 +2529,7 @@ static void ShowPresets()
 
     printf("\n   + iPad:  -e x264  -q 20.0 -r 29.97 --pfr  -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4 -4 -X 1024 --loose-anamorphic -m\n");
 
-    printf("\n   + AppleTV:  -e x264  -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 -X 960 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:b-pyramid=none:b-adapt=2:weightb=0:trellis=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500\n");
+    printf("\n   + AppleTV:  -e x264  -q 20.0 -a 1,1 -E faac,ac3pass -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 -X 960 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:b-pyramid=none:b-adapt=2:weightb=0:trellis=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500\n");
 
     printf("\n>\n");
 
@@ -2535,7 +2537,7 @@ static void ShowPresets()
 
     printf("\n   + Normal:  -e x264  -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4 --strict-anamorphic -m -x ref=2:bframes=2:subme=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0\n");
 
-    printf("\n   + High Profile:  -e x264  -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 --detelecine --decomb --loose-anamorphic -m -x b-adapt=2:rc-lookahead=50\n");
+    printf("\n   + High Profile:  -e x264  -q 20.0 -a 1,1 -E faac,ac3pass -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 --detelecine --decomb --loose-anamorphic -m -x b-adapt=2:rc-lookahead=50\n");
 
     printf("\n>\n");
 
@@ -2543,7 +2545,7 @@ static void ShowPresets()
 
     printf("\n   + Classic:  -b 1000 -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4\n");
 
-    printf("\n   + AppleTV Legacy:  -e x264  -b 2500 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 --strict-anamorphic -m -x ref=1:b-pyramid=none:subme=5:me=umh:no-fast-pskip=1:cabac=0:weightb=0:8x8dct=0:trellis=0\n");
+    printf("\n   + AppleTV Legacy:  -e x264  -b 2500 -a 1,1 -E faac,ac3pass -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 --strict-anamorphic -m -x ref=1:b-pyramid=none:subme=5:me=umh:no-fast-pskip=1:cabac=0:weightb=0:8x8dct=0:trellis=0\n");
 
     printf("\n   + iPhone Legacy:  -e x264  -b 960 -a 1 -E faac -B 128 -6 dpl2 -R Auto -D 0.0 -f mp4 -I -X 480 -m -x level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0:bframes=0:subme=6:8x8dct=0:trellis=0\n");
 
@@ -3374,9 +3376,13 @@ static int get_acodec_for_string( char *codec )
     {
         return HB_ACODEC_AC3;
     }
-    else if( !strcasecmp( codec, "dts" ) || !strcasecmp( codec, "dca" ) )
+    else if( !strcasecmp( codec, "ac3pass" ) )
     {
-        return HB_ACODEC_DCA;
+        return HB_ACODEC_AC3_PASS;
+    }
+    else if( !strcasecmp( codec, "dtspass" ) || !strcasecmp( codec, "dcapass" ) )
+    {
+        return HB_ACODEC_DCA_PASS;
     }
     else if( !strcasecmp( codec, "lame" ) )
     {