diff options
author | jstebbins <[email protected]> | 2010-10-04 23:16:57 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2010-10-04 23:16:57 +0000 |
commit | afffc15c0fec6680f6a612c729d184d92fbc809c (patch) | |
tree | 84266ecb82c48e371039feac8527f06573e57dc4 | |
parent | e10652943a245468659a3ed0dfed452ccd12ae0c (diff) |
Add ac3 encoding
Uses ffmpeg's ac3 encoder.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3570 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | gtk/src/audiohandler.c | 114 | ||||
-rw-r--r-- | gtk/src/hb-backend.c | 152 | ||||
-rw-r--r-- | gtk/src/hb-backend.h | 5 | ||||
-rw-r--r-- | gtk/src/internal_defaults.xml | 2 | ||||
-rw-r--r-- | gtk/src/makedeps.py | 10 | ||||
-rw-r--r-- | gtk/src/presets.c | 3 | ||||
-rw-r--r-- | gtk/src/queuehandler.c | 2 | ||||
-rw-r--r-- | libhb/common.c | 12 | ||||
-rw-r--r-- | libhb/common.h | 26 | ||||
-rw-r--r-- | libhb/deca52.c | 2 | ||||
-rw-r--r-- | libhb/decavcodec.c | 51 | ||||
-rw-r--r-- | libhb/decdca.c | 2 | ||||
-rw-r--r-- | libhb/encac3.c | 257 | ||||
-rw-r--r-- | libhb/hb.c | 2 | ||||
-rw-r--r-- | libhb/internal.h | 1 | ||||
-rw-r--r-- | libhb/muxmkv.c | 6 | ||||
-rw-r--r-- | libhb/muxmp4.c | 216 | ||||
-rw-r--r-- | libhb/sync.c | 16 | ||||
-rw-r--r-- | libhb/work.c | 44 | ||||
-rw-r--r-- | macosx/HBAudio.m | 50 | ||||
-rw-r--r-- | macosx/HBAudioController.m | 5 | ||||
-rwxr-xr-x | scripts/manicure.rb | 16 | ||||
-rw-r--r-- | test/test.c | 34 |
23 files changed, 744 insertions, 284 deletions
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c index 4ecc509c3..6e0748f13 100644 --- a/gtk/src/audiohandler.c +++ b/gtk/src/audiohandler.c @@ -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); diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index d23d3c746..8614b0a99 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -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; } diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h index ff31e90a3..cd6198c25 100644 --- a/gtk/src/hb-backend.h +++ b/gtk/src/hb-backend.h @@ -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); diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml index 0e41912f1..568da2fa9 100644 --- a/gtk/src/internal_defaults.xml +++ b/gtk/src/internal_defaults.xml @@ -291,7 +291,7 @@ <key>AudioBitrate</key> <string>192</string> <key>AudioEncoder</key> - <string>ac3</string> + <string>ac3pass</string> <key>AudioTrack</key> <integer>1</integer> <key>AudioTrackDescription</key> diff --git a/gtk/src/makedeps.py b/gtk/src/makedeps.py index 986cf5b52..121c5654a 100644 --- a/gtk/src/makedeps.py +++ b/gtk/src/makedeps.py @@ -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), diff --git a/gtk/src/presets.c b/gtk/src/presets.c index 1946f0ba8..e50ca054c 100644 --- a/gtk/src/presets.c +++ b/gtk/src/presets.c @@ -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} diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c index 0680a88fc..6d3261638 100644 --- a/gtk/src/queuehandler.c +++ b/gtk/src/queuehandler.c @@ -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 diff --git a/libhb/common.c b/libhb/common.c index 35417cb6c..0c9ac629e 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -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; diff --git a/libhb/common.h b/libhb/common.h index bba48350c..fcb4d4d04 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -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 diff --git a/libhb/deca52.c b/libhb/deca52.c index 785bf6aef..0958a9139 100644 --- a/libhb/deca52.c +++ b/libhb/deca52.c @@ -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 ); diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index abf7ed179..bbdd4d668 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -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 ); } diff --git a/libhb/decdca.c b/libhb/decdca.c index 89c2b1c17..ea4cb560c 100644 --- a/libhb/decdca.c +++ b/libhb/decdca.c @@ -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 index 000000000..5c45b9800 --- /dev/null +++ b/libhb/encac3.c @@ -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; +} + + diff --git a/libhb/hb.c b/libhb/hb.c index fcb4a55df..f7489c162 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -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; } diff --git a/libhb/internal.h b/libhb/internal.h index 30bf022d5..b6fbd1ddb 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -355,6 +355,7 @@ enum WORK_ENCLAME, WORK_ENCVORBIS, WORK_ENC_CA_AAC, + WORK_ENCAC3, WORK_MUX }; diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c index aa320e9aa..073b39f45 100644 --- a/libhb/muxmkv.c +++ b/libhb/muxmkv.c @@ -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); } diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c index bc523f836..5225ea523 100644 --- a/libhb/muxmp4.c +++ b/libhb/muxmp4.c @@ -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 ); diff --git a/libhb/sync.c b/libhb/sync.c index 58628f316..acc782e4a 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -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; diff --git a/libhb/work.c b/libhb/work.c index 3c3346d19..b7dda2736 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -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 diff --git a/macosx/HBAudio.m b/macosx/HBAudio.m index c3598da3f..b32d90d1f 100644 --- a/macosx/HBAudio.m +++ b/macosx/HBAudio.m @@ -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) { diff --git a/macosx/HBAudioController.m b/macosx/HBAudioController.m index da58cfbc1..823dd439f 100644 --- a/macosx/HBAudioController.m +++ b/macosx/HBAudioController.m @@ -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]) { diff --git a/scripts/manicure.rb b/scripts/manicure.rb index f808b27f7..73742bcff 100755 --- a/scripts/manicure.rb +++ b/scripts/manicure.rb @@ -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" diff --git a/test/test.c b/test/test.c index fe9ef8012..f72538667 100644 --- a/test/test.c +++ b/test/test.c @@ -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" ) ) { |