summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2010-10-04 23:16:57 +0000
committerjstebbins <[email protected]>2010-10-04 23:16:57 +0000
commitafffc15c0fec6680f6a612c729d184d92fbc809c (patch)
tree84266ecb82c48e371039feac8527f06573e57dc4
parente10652943a245468659a3ed0dfed452ccd12ae0c (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.c114
-rw-r--r--gtk/src/hb-backend.c152
-rw-r--r--gtk/src/hb-backend.h5
-rw-r--r--gtk/src/internal_defaults.xml2
-rw-r--r--gtk/src/makedeps.py10
-rw-r--r--gtk/src/presets.c3
-rw-r--r--gtk/src/queuehandler.c2
-rw-r--r--libhb/common.c12
-rw-r--r--libhb/common.h26
-rw-r--r--libhb/deca52.c2
-rw-r--r--libhb/decavcodec.c51
-rw-r--r--libhb/decdca.c2
-rw-r--r--libhb/encac3.c257
-rw-r--r--libhb/hb.c2
-rw-r--r--libhb/internal.h1
-rw-r--r--libhb/muxmkv.c6
-rw-r--r--libhb/muxmp4.c216
-rw-r--r--libhb/sync.c16
-rw-r--r--libhb/work.c44
-rw-r--r--macosx/HBAudio.m50
-rw-r--r--macosx/HBAudioController.m5
-rwxr-xr-xscripts/manicure.rb16
-rw-r--r--test/test.c34
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" ) )
{