summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-08-01 18:06:22 +0000
committerjstebbins <[email protected]>2011-08-01 18:06:22 +0000
commit76d480815a9c6773e0fa5bcffaded04646279b8a (patch)
tree01fb72f321632a8bfb928bb3cfc40448f371eb0c
parent7a083edaa1a8d331ca8eb2878f051a4fc1966d43 (diff)
add more audio passthru options
adds aac and mp3 passthru for mp4 and mkv containers adds dts and dtshd for mp4 container (mkv already had it) Note: The only player known (to me) to support dts(hd) in mp4 is ff/avplay In LinGui there is a new option to limit which passthru codecs will be used by the "Auto Passthru" audio codec options. The CLI already has this ability with "--audio_copy-mask" which is use in conjunction with the "copy" audio codec option. Also corrects some A/V sync issues when video frames are dropped due to a gap detected in the audio. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4149 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--contrib/ffmpeg/A04-dca-frame-size.patch12
-rw-r--r--gtk/src/audiohandler.c239
-rw-r--r--gtk/src/audiohandler.h2
-rw-r--r--gtk/src/callbacks.c7
-rw-r--r--gtk/src/ghb.ui144
-rw-r--r--gtk/src/hb-backend.c189
-rw-r--r--gtk/src/hb-backend.h3
-rw-r--r--gtk/src/internal_defaults.xml12
-rw-r--r--gtk/src/makedeps.py19
-rw-r--r--gtk/src/presets.c8
-rw-r--r--libhb/common.h10
-rw-r--r--libhb/deca52.c1
-rw-r--r--libhb/decavcodec.c6
-rw-r--r--libhb/decdca.c1
-rw-r--r--libhb/declpcm.c2
-rw-r--r--libhb/encavcodecaudio.c2
-rw-r--r--libhb/encfaac.c1
-rw-r--r--libhb/enclame.c1
-rw-r--r--libhb/encvorbis.c1
-rw-r--r--libhb/muxmkv.c9
-rw-r--r--libhb/muxmp4.c376
-rw-r--r--libhb/platform/macosx/encca_aac.c2
-rw-r--r--libhb/scan.c1
-rw-r--r--libhb/stream.c18
-rw-r--r--libhb/sync.c174
-rw-r--r--libhb/work.c2
-rw-r--r--macosx/HBAudio.m36
-rw-r--r--macosx/HBAudioController.m7
-rw-r--r--test/test.c46
29 files changed, 830 insertions, 501 deletions
diff --git a/contrib/ffmpeg/A04-dca-frame-size.patch b/contrib/ffmpeg/A04-dca-frame-size.patch
new file mode 100644
index 000000000..5af1040b2
--- /dev/null
+++ b/contrib/ffmpeg/A04-dca-frame-size.patch
@@ -0,0 +1,12 @@
+diff --git a/libavcodec/dca.c b/libavcodec/dca.c
+index 68731c9..cf62c48 100644
+--- a/libavcodec/dca.c
++++ b/libavcodec/dca.c
+@@ -1650,6 +1650,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
+ //set AVCodec values with parsed data
+ avctx->sample_rate = s->sample_rate;
+ avctx->bit_rate = s->bit_rate;
++ avctx->frame_size = s->sample_blocks * 32;
+
+ s->profile = FF_PROFILE_DTS;
+
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c
index 54cd1a496..ee84a798f 100644
--- a/gtk/src/audiohandler.c
+++ b/gtk/src/audiohandler.c
@@ -25,6 +25,130 @@ static GValue* get_selected_asettings(signal_user_data_t *ud);
static gboolean block_updates = FALSE;
+gint
+ghb_select_audio_codec(int mux, hb_audio_config_t *aconfig, gint acodec, gint fallback)
+{
+ guint32 in_codec = aconfig ? aconfig->in.codec : HB_ACODEC_MASK;
+ if (mux == HB_MUX_MP4)
+ {
+ if (acodec & HB_ACODEC_PASS_FLAG)
+ {
+ if ((acodec & in_codec & HB_ACODEC_MASK & ~HB_ACODEC_VORBIS))
+ {
+ return acodec & (in_codec | HB_ACODEC_PASS_FLAG);
+ }
+ else if (fallback & (HB_ACODEC_AC3 | HB_ACODEC_LAME | HB_ACODEC_FAAC | HB_ACODEC_FFAAC))
+ {
+ return fallback;
+ }
+ else
+ {
+ return HB_ACODEC_FAAC;
+ }
+ }
+ else if (acodec & HB_ACODEC_AC3)
+ {
+ return HB_ACODEC_AC3;
+ }
+ else if (acodec & HB_ACODEC_LAME)
+ {
+ return HB_ACODEC_LAME;
+ }
+ else if (acodec & HB_ACODEC_FAAC)
+ {
+ return HB_ACODEC_FAAC;
+ }
+ else if (acodec & HB_ACODEC_FFAAC)
+ {
+ return HB_ACODEC_FFAAC;
+ }
+ else if (fallback & (HB_ACODEC_AC3 | HB_ACODEC_LAME | HB_ACODEC_FAAC | HB_ACODEC_FFAAC))
+ {
+ return fallback;
+ }
+ else
+ {
+ return HB_ACODEC_FAAC;
+ }
+ }
+ else
+ {
+ if (acodec & HB_ACODEC_PASS_FLAG)
+ {
+ if ((acodec & in_codec & HB_ACODEC_PASS_MASK))
+ {
+ return acodec & (in_codec | HB_ACODEC_PASS_FLAG);
+ }
+ else if (fallback)
+ {
+ return fallback;
+ }
+ else
+ {
+ return HB_ACODEC_FAAC;
+ }
+ }
+ else if (acodec & HB_ACODEC_AC3)
+ {
+ return HB_ACODEC_AC3;
+ }
+ else if (acodec & HB_ACODEC_LAME)
+ {
+ return HB_ACODEC_LAME;
+ }
+ else if (acodec & HB_ACODEC_VORBIS)
+ {
+ return HB_ACODEC_VORBIS;
+ }
+ else if (acodec & HB_ACODEC_FAAC)
+ {
+ return HB_ACODEC_FAAC;
+ }
+ else if (acodec & HB_ACODEC_FFAAC)
+ {
+ return HB_ACODEC_FFAAC;
+ }
+ else if (fallback )
+ {
+ return fallback;
+ }
+ else
+ {
+ return HB_ACODEC_LAME;
+ }
+ }
+}
+
+int ghb_allowed_passthru_mask(GValue *settings, int acodec)
+{
+ gint ret = acodec;
+
+ if (acodec == HB_ACODEC_ANY)
+ {
+ if (!ghb_settings_get_boolean(settings, "AudioAllowMP3Pass"))
+ {
+ ret &= ~HB_ACODEC_MP3;
+ }
+ if (!ghb_settings_get_boolean(settings, "AudioAllowAACPass"))
+ {
+ ret &= ~HB_ACODEC_FFAAC;
+ }
+ if (!ghb_settings_get_boolean(settings, "AudioAllowAC3Pass"))
+ {
+ ret &= ~HB_ACODEC_AC3;
+ }
+ if (!ghb_settings_get_boolean(settings, "AudioAllowDTSPass"))
+ {
+ ret &= ~HB_ACODEC_DCA;
+ }
+ if (!ghb_settings_get_boolean(settings, "AudioAllowDTSHDPass"))
+ {
+ ret &= ~HB_ACODEC_DCA_HD;
+ }
+ }
+ return ret;
+}
+
void
ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
{
@@ -32,7 +156,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
hb_audio_config_t *aconfig;
GtkWidget *widget;
GValue *gval;
- int mux;
+ gint mux;
gint bitrate;
gint sr = 48000;
@@ -62,25 +186,15 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
gval = ghb_widget_value(widget);
sr = ghb_lookup_combo_int("AudioSamplerate", gval);
- 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;
- }
aconfig = ghb_get_scan_audio_info(titleindex, track);
if (sr == 0)
{
sr = aconfig ? aconfig->in.samplerate : 48000;
}
- if (aconfig)
- select_acodec = ghb_select_audio_codec(mux, aconfig, select_acodec);
+ gint fallback = ghb_settings_combo_int(ud->settings, "AudioEncoderFallback");
+ select_acodec = ghb_allowed_passthru_mask(ud->settings, acodec);
+ select_acodec = ghb_select_audio_codec(mux, aconfig, select_acodec, fallback);
gboolean codec_defined_bitrate = FALSE;
if (ghb_audio_is_passthru (select_acodec))
{
@@ -89,44 +203,33 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
bitrate = aconfig->in.bitrate / 1000;
// Set the values for bitrate and samplerate to the input rates
- if (aconfig->in.codec & select_acodec & HB_ACODEC_PASS_MASK)
- {
- ghb_set_passthru_bitrate_opts (ud->builder, bitrate);
- ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
- select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG;
- codec_defined_bitrate = TRUE;
- }
- else
- {
- gint mux = ghb_settings_get_int(ud->settings, "FileFormat");
- select_acodec = ghb_select_audio_codec(mux, aconfig, acodec);
- if (acodec != HB_ACODEC_ANY)
- {
- ghb_ui_update(ud, "AudioEncoder", ghb_int64_value(select_acodec));
- }
-
- mix = ghb_get_best_mix( aconfig, select_acodec, mix);
- bitrate = hb_get_default_audio_bitrate(select_acodec, sr, mix);
- ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix));
- }
+ ghb_set_passthru_bitrate_opts (ud->builder, bitrate);
+ mix = 0;
+ ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix));
+ select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG;
+ codec_defined_bitrate = TRUE;
ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
}
else
{
ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
- ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
+ mix = 0;
+ ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix));
bitrate = 448;
- mix = ghb_get_best_mix( aconfig, select_acodec, 0);
}
ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(0));
}
else
{
+ if (mix == 0)
+ mix = ghb_get_best_mix( aconfig, select_acodec, 0);
bitrate = hb_get_best_audio_bitrate(select_acodec, bitrate, sr, mix);
+ ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix));
}
if (!codec_defined_bitrate)
{
int low, high;
+ mix = ghb_get_best_mix( aconfig, select_acodec, mix);
hb_get_audio_bitrate_limits(select_acodec, sr, mix, &low, &high);
ghb_set_default_bitrate_opts (ud->builder, low, high);
}
@@ -182,14 +285,7 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
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;
- }
+ fallback_acodec = ghb_settings_combo_int(ud->settings, "AudioEncoderFallback");
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
@@ -208,24 +304,12 @@ 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;
+ gint select_acodec;
audio = ghb_array_get_nth(pref_audio, ii);
- 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;
- }
+ acodec = ghb_settings_combo_int(audio, "AudioEncoder");
+ select_acodec = ghb_allowed_passthru_mask(ud->settings, acodec);
+ select_acodec = ghb_select_audio_codec(mux, NULL, select_acodec, fallback_acodec);
bitrate = ghb_settings_combo_int(audio, "AudioBitrate");
rate = ghb_settings_combo_double(audio, "AudioSamplerate");
mix = ghb_settings_combo_int(audio, "AudioMixdown");
@@ -260,17 +344,13 @@ ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
}
else
{
- int channels, min_rate, max_rate;
+ int channels;
select_acodec = fallback_acodec;
mix = ghb_get_best_mix(aconfig, select_acodec, mix);
channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mix);
bitrate = aconfig->in.bitrate / 1000;
- min_rate = channels * 64;
- max_rate = channels * 160;
- if (bitrate < min_rate)
- bitrate = min_rate;
- if (bitrate > max_rate)
- bitrate = max_rate;
+ bitrate = hb_get_best_audio_bitrate(select_acodec, bitrate,
+ aconfig->in.samplerate, mix);
rate = 0;
}
}
@@ -417,7 +497,7 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
if (block_updates)
{
prev_acodec = acodec_code;
- ghb_grey_combo_options (ud->builder);
+ ghb_grey_combo_options (ud);
return;
}
@@ -469,7 +549,7 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
}
ghb_adjust_audio_rate_combos(ud);
- ghb_grey_combo_options (ud->builder);
+ ghb_grey_combo_options (ud);
ghb_check_dependency(ud, widget, NULL);
prev_acodec = acodec_code;
if (asettings != NULL)
@@ -488,11 +568,15 @@ audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
GValue *asettings;
g_debug("audio_track_changed_cb ()");
- if (block_updates) return;
+ if (block_updates)
+ {
+ ghb_grey_combo_options (ud);
+ return;
+ }
ghb_adjust_audio_rate_combos(ud);
ghb_check_dependency(ud, widget, NULL);
- ghb_grey_combo_options(ud->builder);
+ ghb_grey_combo_options(ud);
asettings = get_selected_asettings(ud);
if (asettings != NULL)
{
@@ -544,6 +628,19 @@ audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_live_reset(ud);
}
+G_MODULE_EXPORT void
+global_audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("global_audio_widget_changed_cb ()");
+ if (block_updates) return;
+
+ ghb_check_dependency(ud, widget, NULL);
+ ghb_widget_to_setting(ud->settings, widget);
+ ghb_adjust_audio_rate_combos(ud);
+ ghb_audio_list_refresh_selected(ud);
+ ghb_live_reset(ud);
+}
+
G_MODULE_EXPORT gchar*
format_drc_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
{
diff --git a/gtk/src/audiohandler.h b/gtk/src/audiohandler.h
index 87b9612f7..74df87a3d 100644
--- a/gtk/src/audiohandler.h
+++ b/gtk/src/audiohandler.h
@@ -34,5 +34,7 @@ void ghb_set_audio(signal_user_data_t *ud, GValue *settings);
gchar* ghb_get_user_audio_lang(
signal_user_data_t *ud, gint titleindex, gint track);
void ghb_audio_list_refresh_selected(signal_user_data_t *ud);
+int ghb_allowed_passthru_mask(GValue *settings, int acodec);
+gint ghb_select_audio_codec(gint mux, hb_audio_config_t *aconfig, gint acodec, int fallback_acodec);
#endif // _AUDIOHANDLER_H_
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index 0fd92a9e6..03d576603 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -1250,7 +1250,8 @@ window_delete_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *u
static void
update_acodec_combo(signal_user_data_t *ud)
{
- ghb_grey_combo_options (ud->builder);
+ ghb_adjust_audio_rate_combos(ud);
+ ghb_grey_combo_options (ud);
}
G_MODULE_EXPORT void
@@ -1507,7 +1508,7 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
update_chapter_list (ud);
ghb_adjust_audio_rate_combos(ud);
ghb_set_pref_audio(titleindex, ud);
- ghb_grey_combo_options (ud->builder);
+ ghb_grey_combo_options (ud);
ghb_set_pref_subtitle(titleindex, ud);
// Unfortunately, there is no way to query how many frames were
@@ -1662,7 +1663,7 @@ http_opt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_clear_presets_selection(ud);
ghb_live_reset(ud);
// AC3 is not allowed when Web optimized
- ghb_grey_combo_options (ud->builder);
+ ghb_grey_combo_options (ud);
}
G_MODULE_EXPORT void
diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui
index 999f3c621..7d037434b 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -1716,7 +1716,7 @@
<object class="GtkLabel" id="label46">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Video Codec:</property>
+ <property name="label" translatable="yes">Video Encoder:</property>
<property name="width_chars">11</property>
</object>
<packing>
@@ -2113,9 +2113,10 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
<object class="GtkTable" id="table14">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="n_rows">2</property>
+ <property name="n_rows">4</property>
<property name="n_columns">5</property>
<property name="row_spacing">5</property>
+ <property name="column_spacing">5</property>
<child>
<object class="GtkLabel" id="audio_name_label">
<property name="visible">True</property>
@@ -2228,7 +2229,7 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
<child>
<object class="GtkHScale" id="AudioTrackGain">
<property name="visible">True</property>
- <property name="width-request">200</property>
+ <property name="width-request">150</property>
<property name="orientation">horizontal</property>
<property name="adjustment">adjustment35</property>
<property name="value_pos">right</property>
@@ -2282,6 +2283,141 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
<property name="x_options">GTK_FILL</property>
</packing>
</child>
+ <child>
+ <object class="GtkHBox" id="hbox40">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkLabel" id="labela3">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Auto Passthru:</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowMP3Pass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AAC. This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">MP3</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowAACPass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AAC. This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">AAC</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowAC3Pass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports AC-3. This permits AC-3 passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">AC-3</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowDTSPass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports DTS. This permits DTS passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">DTS</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowDTSHDPass">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Enable this if your playback device supports DTS-HD. This permits DTS-HD passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="label" translatable="yes">DTS-HD</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="global_audio_widget_changed_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="left_attach">0</property>
+ <property name="right_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labela4">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Passthru Fallback:</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="AudioEncoderFallback">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Set the audio codec to encode with when a suitable track can not be found for audio passthru.</property>
+ <signal handler="global_audio_widget_changed_cb" name="changed"/>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
</object>
</child>
</object>
@@ -2323,7 +2459,7 @@ FFMpeg's and Theora's scale is more linear. These encoders do not have a lossle
<object class="GtkLabel" id="label68">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Codec</property>
+ <property name="label" translatable="yes">Encoder</property>
</object>
<packing>
<property name="top_attach">0</property>
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 8a90d4ece..a3b9e5106 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -57,7 +57,7 @@ static gint index_str_size = 0;
static void
index_str_init(gint max_index)
{
- int ii;
+ gint ii;
if (max_index+1 > index_str_size)
{
@@ -256,10 +256,12 @@ static options_map_t d_acodec_opts[] =
{"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"},
- {"DTS-HD (pass-thru)", "dtshdpass", HB_ACODEC_DCA_HD_PASS, "dtshdpass"},
- {"Choose For Me", "auto", HB_ACODEC_ANY, "auto"},
+ {"MP3 Passthru", "mp3pass", HB_ACODEC_MP3_PASS, "mp3pass"},
+ {"AAC Passthru", "aacpass", HB_ACODEC_AAC_PASS, "aacpass"},
+ {"AC3 Passthru", "ac3pass", HB_ACODEC_AC3_PASS, "ac3pass"},
+ {"DTS Passthru", "dtspass", HB_ACODEC_DCA_PASS, "dtspass"},
+ {"DTS-HD Passthru", "dtshdpass", HB_ACODEC_DCA_HD_PASS, "dtshdpass"},
+ {"Auto Passthru", "auto", HB_ACODEC_ANY, "auto"},
};
combo_opts_t acodec_opts =
{
@@ -267,6 +269,20 @@ combo_opts_t acodec_opts =
d_acodec_opts
};
+static options_map_t d_acodec_fallback_opts[] =
+{
+ {"AAC (faac)", "faac", HB_ACODEC_FAAC, "faac"},
+ {"AAC (ffmpeg)", "ffaac", HB_ACODEC_FFAAC, "ffaac"},
+ {"MP3 (lame)", "lame", HB_ACODEC_LAME, "lame"},
+ {"Vorbis", "vorbis", HB_ACODEC_VORBIS, "vorbis"},
+ {"AC3 (ffmpeg)", "ac3", HB_ACODEC_AC3, "ac3"},
+};
+combo_opts_t acodec_fallback_opts =
+{
+ sizeof(d_acodec_fallback_opts)/sizeof(options_map_t),
+ d_acodec_fallback_opts
+};
+
static options_map_t d_direct_opts[] =
{
{"None", "none", 0, "none"},
@@ -418,6 +434,7 @@ combo_name_map_t combo_name_map[] =
{"VideoEncoder", &vcodec_opts},
{"AudioEncoder", &acodec_opts},
{"AudioEncoderActual", &acodec_opts},
+ {"AudioEncoderFallback", &acodec_fallback_opts},
{"x264_direct", &direct_opts},
{"x264_b_adapt", &badapt_opts},
{"x264_bpyramid", &bpyramid_opts},
@@ -1535,71 +1552,75 @@ grey_combo_box_item(GtkBuilder *builder, const gchar *name, gint value, gboolean
}
void
-ghb_grey_combo_options(GtkBuilder *builder)
+ghb_grey_combo_options(signal_user_data_t *ud)
{
GtkWidget *widget;
- gint mux, track, titleindex, acodec;
- hb_audio_config_t *aconfig = NULL;
+ gint mux, track, titleindex, acodec, fallback;
+ hb_audio_config_t *aconfig = NULL;
GValue *gval;
- widget = GHB_WIDGET (builder, "title");
+ widget = GHB_WIDGET (ud->builder, "title");
gval = ghb_widget_value(widget);
titleindex = ghb_lookup_combo_int("title", gval);
ghb_value_free(gval);
- widget = GHB_WIDGET (builder, "AudioTrack");
+ widget = GHB_WIDGET (ud->builder, "AudioTrack");
gval = ghb_widget_value(widget);
track = ghb_lookup_combo_int("AudioTrack", gval);
ghb_value_free(gval);
aconfig = get_hb_audio(h_scan, titleindex, track);
- widget = GHB_WIDGET (builder, "FileFormat");
+ widget = GHB_WIDGET (ud->builder, "FileFormat");
gval = ghb_widget_value(widget);
mux = ghb_lookup_combo_int("FileFormat", gval);
ghb_value_free(gval);
- grey_combo_box_item(builder, "x264_analyse", 4, TRUE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_FFAAC, FALSE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_FAAC, FALSE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_LAME, FALSE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_VORBIS, FALSE);
-
- gboolean allow_dca = TRUE;
- allow_dca = (mux != HB_MUX_MP4);
+ grey_combo_box_item(ud->builder, "x264_analyse", 4, TRUE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_FFAAC, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_FAAC, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_LAME, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_VORBIS, FALSE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_AC3_PASS, FALSE);
- if (allow_dca)
- {
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, FALSE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_HD_PASS, FALSE);
- }
- else
- {
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_HD_PASS, TRUE);
- }
+ grey_combo_box_item(ud->builder, "AudioEncoderFallback", HB_ACODEC_FFAAC, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoderFallback", HB_ACODEC_FAAC, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoderFallback", HB_ACODEC_LAME, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoderFallback", HB_ACODEC_VORBIS, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_MP3_PASS, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AAC_PASS, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AC3_PASS, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_PASS, FALSE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_HD_PASS, FALSE);
+ if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_MP3)
+ {
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_MP3_PASS, TRUE);
+ }
+ if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_FFAAC)
+ {
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AAC_PASS, TRUE);
+ }
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_AC3)
{
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_AC3_PASS, TRUE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AC3_PASS, TRUE);
}
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_DCA)
{
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
}
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_DCA_HD)
{
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_HD_PASS, TRUE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_HD_PASS, TRUE);
}
- grey_combo_box_item(builder, "VideoEncoder", HB_VCODEC_THEORA, FALSE);
+ grey_combo_box_item(ud->builder, "VideoEncoder", HB_VCODEC_THEORA, FALSE);
- widget = GHB_WIDGET (builder, "AudioEncoder");
+ widget = GHB_WIDGET (ud->builder, "AudioEncoder");
gval = ghb_widget_value(widget);
acodec = ghb_lookup_combo_int("AudioEncoder", gval);
ghb_value_free(gval);
- grey_combo_box_item(builder, "AudioMixdown", 0, TRUE);
+ grey_combo_box_item(ud->builder, "AudioMixdown", 0, TRUE);
if (mux == HB_MUX_MP4)
{
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_VORBIS, TRUE);
- grey_combo_box_item(builder, "VideoEncoder", HB_VCODEC_THEORA, TRUE);
+ grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_VORBIS, TRUE);
+ grey_combo_box_item(ud->builder, "AudioEncoderFallback", HB_ACODEC_VORBIS, TRUE);
+ grey_combo_box_item(ud->builder, "VideoEncoder", HB_VCODEC_THEORA, TRUE);
}
gboolean allow_mono = TRUE;
@@ -1610,7 +1631,9 @@ ghb_grey_combo_options(GtkBuilder *builder)
allow_6ch = acodec & ~HB_ACODEC_LAME;
if (aconfig)
{
- acodec = ghb_select_audio_codec(mux, aconfig, acodec);
+ acodec = ghb_allowed_passthru_mask(ud->settings, acodec);
+ fallback = ghb_settings_combo_int(ud->settings, "AudioEncoderFallback");
+ acodec = ghb_select_audio_codec(mux, aconfig, acodec, fallback);
gint best = hb_get_best_mixdown(acodec, aconfig->in.channel_layout, 0);
allow_stereo = best >= HB_AMIXDOWN_STEREO;
@@ -1619,17 +1642,17 @@ ghb_grey_combo_options(GtkBuilder *builder)
allow_6ch = best >= HB_AMIXDOWN_6CH;
allow_mono = best >= HB_AMIXDOWN_MONO;
}
- grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_MONO, !allow_mono);
- grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_STEREO, !allow_stereo);
- grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_DOLBY, !allow_dolby);
- grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_DOLBYPLII, !allow_dpl2);
- grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_6CH, !allow_6ch);
+ grey_combo_box_item(ud->builder, "AudioMixdown", HB_AMIXDOWN_MONO, !allow_mono);
+ grey_combo_box_item(ud->builder, "AudioMixdown", HB_AMIXDOWN_STEREO, !allow_stereo);
+ grey_combo_box_item(ud->builder, "AudioMixdown", HB_AMIXDOWN_DOLBY, !allow_dolby);
+ grey_combo_box_item(ud->builder, "AudioMixdown", HB_AMIXDOWN_DOLBYPLII, !allow_dpl2);
+ grey_combo_box_item(ud->builder, "AudioMixdown", HB_AMIXDOWN_6CH, !allow_6ch);
}
gint
ghb_get_best_mix(hb_audio_config_t *aconfig, gint acodec, gint mix)
{
- int layout;
+ gint layout;
layout = aconfig ? aconfig->in.channel_layout :
HB_INPUT_CH_LAYOUT_3F2R | HB_INPUT_CH_LAYOUT_HAS_LFE;
return hb_get_best_mixdown( acodec, layout, mix );
@@ -2780,6 +2803,7 @@ ghb_update_ui_combo_box(
generic_opts_set(ud->builder, "PictureDenoise", &denoise_opts);
generic_opts_set(ud->builder, "VideoEncoder", &vcodec_opts);
small_opts_set(ud->builder, "AudioEncoder", &acodec_opts);
+ small_opts_set(ud->builder, "AudioEncoderFallback", &acodec_fallback_opts);
small_opts_set(ud->builder, "x264_direct", &direct_opts);
small_opts_set(ud->builder, "x264_b_adapt", &badapt_opts);
small_opts_set(ud->builder, "x264_bpyramid", &bpyramid_opts);
@@ -4135,70 +4159,6 @@ ghb_validate_subtitles(signal_user_data_t *ud)
return TRUE;
}
-gint
-ghb_select_audio_codec(gint mux, hb_audio_config_t *aconfig, gint acodec)
-{
- guint32 in_codec = aconfig ? aconfig->in.codec : HB_ACODEC_MASK;
- if (mux == HB_MUX_MP4)
- {
- if ((acodec & in_codec & HB_ACODEC_AC3))
- {
- return acodec & (in_codec | HB_ACODEC_PASS_FLAG);
- }
- else if (acodec & HB_ACODEC_AC3)
- {
- return HB_ACODEC_AC3;
- }
- else if (acodec & HB_ACODEC_LAME)
- {
- return HB_ACODEC_LAME;
- }
- else if (acodec & HB_ACODEC_FAAC)
- {
- return HB_ACODEC_FAAC;
- }
- else if (acodec & HB_ACODEC_FFAAC)
- {
- return HB_ACODEC_FFAAC;
- }
- else
- {
- return HB_ACODEC_FAAC;
- }
- }
- else
- {
- if ((acodec & in_codec & HB_ACODEC_PASS_MASK))
- {
- return acodec & (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 if (acodec & HB_ACODEC_FAAC)
- {
- return HB_ACODEC_FAAC;
- }
- else if (acodec & HB_ACODEC_FFAAC)
- {
- return HB_ACODEC_FFAAC;
- }
- else
- {
- return HB_ACODEC_LAME;
- }
- }
-}
-
gboolean
ghb_validate_audio(signal_user_data_t *ud)
{
@@ -4283,11 +4243,6 @@ ghb_validate_audio(signal_user_data_t *ud)
a_unsup = "Vorbis";
codec = HB_ACODEC_FAAC;
}
- if (codec == HB_ACODEC_DCA)
- {
- a_unsup = "DTS";
- codec = HB_ACODEC_AC3;
- }
}
if (a_unsup)
{
@@ -4711,7 +4666,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
GValue *asettings;
hb_audio_config_t audio;
hb_audio_config_t *aconfig;
- gint acodec;
+ gint acodec, fallback;
hb_audio_config_init(&audio);
asettings = ghb_array_get_nth(audio_list, ii);
@@ -4735,7 +4690,9 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
acodec = ghb_settings_combo_int(asettings, "AudioEncoder");
- audio.out.codec = ghb_select_audio_codec(job->mux, aconfig, acodec);
+ acodec = ghb_allowed_passthru_mask(js, acodec);
+ fallback = ghb_settings_combo_int(js, "AudioEncoderFallback");
+ audio.out.codec = ghb_select_audio_codec(job->mux, aconfig, acodec, fallback);
audio.out.gain =
ghb_settings_get_double(asettings, "AudioTrackGain");
diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h
index 6733ad306..f59d821a6 100644
--- a/gtk/src/hb-backend.h
+++ b/gtk/src/hb-backend.h
@@ -137,7 +137,7 @@ hb_audio_config_t* ghb_get_scan_audio_info(gint titleindex, gint audioindex);
void ghb_set_passthru_bitrate_opts(GtkBuilder *builder, gint bitrate);
void ghb_set_default_bitrate_opts(
GtkBuilder *builder, gint first_rate, gint last_rate);
-void ghb_grey_combo_options(GtkBuilder *builder);
+void ghb_grey_combo_options(signal_user_data_t *ud);
void ghb_update_ui_combo_box(
signal_user_data_t *ud, const gchar *name, gint user_data, gboolean all);
gchar* ghb_get_source_audio_lang(gint titleindex, gint track);
@@ -175,7 +175,6 @@ 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(gint mux, hb_audio_config_t *aconfig, gint acodec);
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 e4a4a72b6..b4d06694d 100644
--- a/gtk/src/internal_defaults.xml
+++ b/gtk/src/internal_defaults.xml
@@ -295,6 +295,18 @@
<true />
<key>Mp4LargeFile</key>
<false />
+ <key>AudioAllowMP3Pass</key>
+ <true />
+ <key>AudioAllowAACPass</key>
+ <true />
+ <key>AudioAllowAC3Pass</key>
+ <true />
+ <key>AudioAllowDTSPass</key>
+ <true />
+ <key>AudioAllowDTSHDPass</key>
+ <true />
+ <key>AudioEncoderFallback</key>
+ <string>ac3</string>
<key>AudioList</key>
<array>
<dict>
diff --git a/gtk/src/makedeps.py b/gtk/src/makedeps.py
index a16b28ca5..65d398eca 100644
--- a/gtk/src/makedeps.py
+++ b/gtk/src/makedeps.py
@@ -49,13 +49,18 @@ dep_map = (
DepEntry("VideoEncoder", "x264_tab", "x264", False, True),
DepEntry("VideoEncoder", "lavc_mpeg4_tab", "ffmpeg|ffmpeg2", False, True),
DepEntry("VideoEncoder", "Mp4iPodCompatible", "x264", False, 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("AudioEncoderActual", "AudioTrackGain", "ac3pass|dtspass", True, False),
- DepEntry("AudioEncoderActual", "gain_label", "ac3pass|dtspass", True, False),
+ DepEntry("AudioEncoderActual", "AudioBitrate", "mp3pass|aacpass|ac3pass|dtspass|dtshdpass", True, False),
+ DepEntry("AudioEncoderActual", "AudioSamplerate", "mp3pass|aacpass|ac3pass|dtspass|dtshdpass", True, False),
+ DepEntry("AudioEncoderActual", "AudioMixdown", "mp3pass|aacpass|ac3pass|dtspass|dtshdpass", True, False),
+ DepEntry("AudioEncoderActual", "AudioTrackDRCSlider", "mp3pass|aacpass|ac3pass|dtspass|dtshdpass", True, False),
+ DepEntry("AudioEncoderActual", "drc_label", "mp3pass|aacpass|ac3pass|dtspass|dtshdpass", True, False),
+ DepEntry("AudioEncoderActual", "AudioTrackGain", "mp3pass|aacpass|ac3pass|dtspass|dtshdpass", True, False),
+ DepEntry("AudioEncoderActual", "gain_label", "mp3pass|aacpass|ac3pass|dtspass|dtshdpass", True, False),
+ DepEntry("AudioEncoder", "AudioAllowMP3Pass", "auto", False, False),
+ DepEntry("AudioEncoder", "AudioAllowAACPass", "auto", False, False),
+ DepEntry("AudioEncoder", "AudioAllowAC3Pass", "auto", False, False),
+ DepEntry("AudioEncoder", "AudioAllowDTSPass", "auto", False, False),
+ DepEntry("AudioEncoder", "AudioAllowDTSHDPass", "auto", False, 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 064d27323..0a4d46745 100644
--- a/gtk/src/presets.c
+++ b/gtk/src/presets.c
@@ -2004,6 +2004,8 @@ static value_map_t acodec_xlat[] =
{"HE-AAC (CoreAudio)", "faac"},
{"AC3", "ac3"}, // Backwards compatibility with mac ui
{"AC3 (ffmpeg)", "ac3"},
+ {"MP3 Passthru", "mp3pass"},
+ {"AAC Passthru", "aacpass"},
{"AC3 Passthru", "ac3pass"},
{"DTS Passthru", "dtspass"},
{"DTS-HD Passthru", "dtshdpass"},
@@ -2055,10 +2057,10 @@ value_map_t mix_xlat[] =
{"Dolby Surround", "dpl1"},
{"Dolby Pro Logic II", "dpl2"},
{"6-channel discrete", "6ch"},
- {"AC3 Passthru", "none"},
- {"DTS Passthru", "none"},
- {"DTS-HD Passthru", "none"},
{"None", "none"},
+ {"AC3 Passthru", "none"}, // Backwards compatibility with mac ui
+ {"DTS Passthru", "none"}, // Backwards compatibility with mac ui
+ {"DTS-HD Passthru", "none"}, // Backwards compatibility with mac ui
{NULL, NULL}
};
diff --git a/libhb/common.h b/libhb/common.h
index 48a4812bb..88bb8389d 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -321,9 +321,12 @@ struct hb_job_s
#define HB_ACODEC_FFAAC 0x00010000
#define HB_ACODEC_FFMPEG 0x00020000
#define HB_ACODEC_DCA_HD 0x00040000
-#define HB_ACODEC_FF_MASK 0x00060000
+#define HB_ACODEC_MP3 0x00080000
+#define HB_ACODEC_FF_MASK 0x000f0000
#define HB_ACODEC_PASS_FLAG 0x40000000
-#define HB_ACODEC_PASS_MASK (HB_ACODEC_DCA_HD | HB_ACODEC_AC3 | HB_ACODEC_DCA)
+#define HB_ACODEC_PASS_MASK (HB_ACODEC_MP3 | HB_ACODEC_FFAAC | HB_ACODEC_DCA_HD | HB_ACODEC_AC3 | HB_ACODEC_DCA)
+#define HB_ACODEC_MP3_PASS (HB_ACODEC_MP3 | HB_ACODEC_PASS_FLAG)
+#define HB_ACODEC_AAC_PASS (HB_ACODEC_FFAAC | HB_ACODEC_PASS_FLAG)
#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_DCA_HD_PASS (HB_ACODEC_DCA_HD | HB_ACODEC_PASS_FLAG)
@@ -404,6 +407,7 @@ struct hb_audio_config_s
* are ignored.
*/
int samplerate; /* Output sample rate (Hz) */
+ int samples_per_frame; /* Number of samples per frame */
int bitrate; /* Output bitrate (kbps) */
int mixdown; /* The mixdown format to be used for this audio track (see HB_AMIXDOWN_*) */
double dynamic_range_compression; /* Amount of DRC that gets applied to this track */
@@ -423,6 +427,7 @@ struct hb_audio_config_s
PRIVATE uint32_t version; /* Bitsream version */
PRIVATE uint32_t mode; /* Bitstream mode, codec dependent encoding */
PRIVATE int samplerate; /* Input sample rate (Hz) */
+ PRIVATE int samples_per_frame; /* Number of samples per frame */
PRIVATE int bitrate; /* Input bitrate (kbps) */
PRIVATE int channel_layout; /* channel_layout is the channel layout of this audio this is used to
* provide a common way of describing the source audio */
@@ -714,6 +719,7 @@ typedef struct hb_work_info_s
struct { // info only valid for audio decoders
int channel_layout;
hb_chan_map_t * channel_map;
+ int samples_per_frame;
};
};
} hb_work_info_t;
diff --git a/libhb/deca52.c b/libhb/deca52.c
index 2771eda55..a8d537d52 100644
--- a/libhb/deca52.c
+++ b/libhb/deca52.c
@@ -414,6 +414,7 @@ static int deca52BSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->flags = flags;
info->version = raw >> 3; /* bsid is the first 5 bits */
info->mode = raw & 0x7; /* bsmod is the following 3 bits */
+ info->samples_per_frame = 1536;
if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY )
{
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index e52021655..f67850d86 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -439,6 +439,7 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
&out_size, &avp );
if ( len > 0 && context->sample_rate > 0 )
{
+ int isamp = av_get_bytes_per_sample( context->sample_fmt );
info->bitrate = context->bit_rate;
info->rate = context->sample_rate;
info->rate_base = 1;
@@ -446,6 +447,11 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
hb_ff_layout_xlat(context->channel_layout,
context->channels);
ret = 1;
+ if ( context->channels && isamp )
+ {
+ info->samples_per_frame = out_size /
+ (isamp * context->channels);
+ }
break;
}
}
diff --git a/libhb/decdca.c b/libhb/decdca.c
index 138024a6d..4f5ee3929 100644
--- a/libhb/decdca.c
+++ b/libhb/decdca.c
@@ -311,6 +311,7 @@ static int decdcaBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->rate_base = 1;
info->bitrate = bitrate;
info->flags = flags;
+ info->samples_per_frame = frame_length;
if ( ( flags & DCA_CHANNEL_MASK) == DCA_DOLBY )
{
diff --git a/libhb/declpcm.c b/libhb/declpcm.c
index 3dd1f7366..62eb563e8 100644
--- a/libhb/declpcm.c
+++ b/libhb/declpcm.c
@@ -259,6 +259,7 @@ static int declpcmBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
int rate = hdr2samplerate[ ( b->data[4] >> 4 ) & 0x3 ];
int bitrate = rate * sample_size * nchannels;
+ int64_t duration = b->data[0] * 150;
memset( info, 0, sizeof(*info) );
@@ -269,6 +270,7 @@ static int declpcmBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->flags = ( b->data[3] << 16 ) | ( b->data[4] << 8 ) | b->data[5];
info->channel_layout = hdr2layout[nchannels - 1];
info->channel_map = &hb_qt_chan_map;
+ info->samples_per_frame = ( duration * rate ) / 90000;
return 1;
}
diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c
index 9239c519a..ebf2fd8f2 100644
--- a/libhb/encavcodecaudio.c
+++ b/libhb/encavcodecaudio.c
@@ -103,7 +103,7 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
}
pv->context = context;
- pv->samples_per_frame = context->frame_size;
+ audio->config.out.samples_per_frame = pv->samples_per_frame = context->frame_size;
pv->input_samples = pv->samples_per_frame * pv->out_discrete_channels;
// Set a reasonable maximum output size
diff --git a/libhb/encfaac.c b/libhb/encfaac.c
index fe1a1f55b..0ab9124c8 100644
--- a/libhb/encfaac.c
+++ b/libhb/encfaac.c
@@ -99,6 +99,7 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
pv->obuf = malloc( pv->output_bytes );
pv->framedur = 90000.0 * pv->input_samples /
( audio->config.out.samplerate * pv->out_discrete_channels );
+ audio->config.out.samples_per_frame = pv->input_samples / pv->out_discrete_channels;
cfg = faacEncGetCurrentConfiguration( pv->faac );
cfg->mpegVersion = MPEG4;
diff --git a/libhb/enclame.c b/libhb/enclame.c
index ba05e1fc0..434aa185e 100644
--- a/libhb/enclame.c
+++ b/libhb/enclame.c
@@ -76,6 +76,7 @@ int enclameInit( hb_work_object_t * w, hb_job_t * job )
pv->input_samples = 1152 * pv->out_discrete_channels;
pv->output_bytes = LAME_MAXMP3BUFFER;
pv->buf = malloc( pv->input_samples * sizeof( float ) );
+ audio->config.out.samples_per_frame = 1152;
pv->list = hb_list_init();
pv->pts = -1;
diff --git a/libhb/encvorbis.c b/libhb/encvorbis.c
index 01bd216e8..fc186e089 100644
--- a/libhb/encvorbis.c
+++ b/libhb/encvorbis.c
@@ -111,6 +111,7 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
}
pv->input_samples = pv->out_discrete_channels * OGGVORBIS_FRAME_SIZE;
+ audio->config.out.samples_per_frame = OGGVORBIS_FRAME_SIZE;
pv->buf = malloc( pv->input_samples * sizeof( float ) );
pv->list = hb_list_init();
diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c
index f73139b98..2ec32139d 100644
--- a/libhb/muxmkv.c
+++ b/libhb/muxmkv.c
@@ -187,23 +187,21 @@ static int MKVInit( hb_mux_object_t * m )
mux_data->codec = audio->config.out.codec;
- switch (audio->config.out.codec)
+ switch (audio->config.out.codec & HB_ACODEC_MASK)
{
case HB_ACODEC_DCA:
- case HB_ACODEC_DCA_PASS:
case HB_ACODEC_DCA_HD:
- case HB_ACODEC_DCA_HD_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;
break;
case HB_ACODEC_LAME:
+ case HB_ACODEC_MP3:
track->codecPrivate = NULL;
track->codecPrivateSize = 0;
track->codecID = MK_ACODEC_MP3;
@@ -259,8 +257,7 @@ static int MKVInit( hb_mux_object_t * m )
lang = lang_for_code2( audio->config.lang.iso639_2 );
track->language = lang->iso639_2b ? lang->iso639_2b : lang->iso639_2;
track->extra.audio.samplingFreq = (float)audio->config.out.samplerate;
- if (audio->config.out.codec == HB_ACODEC_AC3_PASS ||
- audio->config.out.codec == HB_ACODEC_DCA_PASS)
+ if (audio->config.out.codec & HB_ACODEC_PASS_FLAG)
{
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 b9c7637e8..05bce561a 100644
--- a/libhb/muxmp4.c
+++ b/libhb/muxmp4.c
@@ -257,228 +257,206 @@ static int MP4Init( hb_mux_object_t * m )
MP4SetTrackFloatProperty(m->file, mux_data->track, "tkhd.width", job->width * (width / height));
}
- /* add the audio tracks */
+ /* add the audio tracks */
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
audio = hb_list_item( title->list_audio, i );
mux_data = calloc(1, sizeof( hb_mux_data_t ) );
audio->priv.mux_data = mux_data;
- if( audio->config.out.codec == HB_ACODEC_AC3_PASS )
+ switch ( audio->config.out.codec & HB_ACODEC_MASK )
{
- 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;
-
- for (ii = 0; ii < 3; ii++)
+ case HB_ACODEC_AC3:
{
- for (jj = 0; jj < 3; jj++)
+ uint8_t bsid;
+ uint8_t bsmod;
+ uint8_t acmod;
+ uint8_t lfeon;
+ uint8_t bit_rate_code = 0;
+ int ii, jj;
+ int freq;
+ int bitrate;
+ int sr_shift, sr_code;
+
+ if ( audio->config.out.codec & HB_ACODEC_PASS_FLAG )
{
- if ((ac3_sample_rate_tab[jj] >> ii) == freq)
+ bsmod = audio->config.in.mode;
+ acmod = audio->config.flags.ac3 & 0x7;
+ lfeon = (audio->config.flags.ac3 & A52_LFE) ? 1 : 0;
+ freq = audio->config.in.samplerate;
+ bitrate = audio->config.in.bitrate;
+ }
+ else
+ {
+ bsmod = 0;
+ freq = audio->config.out.samplerate;
+ bitrate = audio->config.out.bitrate * 1000;
+ switch( audio->config.out.mixdown )
{
- goto rate_found1;
+ case HB_AMIXDOWN_MONO:
+ acmod = 1;
+ lfeon = 0;
+ break;
+
+ case HB_AMIXDOWN_STEREO:
+ case HB_AMIXDOWN_DOLBY:
+ case HB_AMIXDOWN_DOLBYPLII:
+ acmod = 2;
+ lfeon = 0;
+ break;
+
+ case HB_AMIXDOWN_6CH:
+ acmod = 7;
+ lfeon = 1;
+ break;
+
+ default:
+ hb_log(" MP4Init: bad mixdown" );
+ acmod = 2;
+ lfeon = 0;
+ break;
}
}
- }
- hb_error("Unknown AC3 samplerate");
- ii = jj = 0;
-rate_found1:
- 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 );
-
- 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++)
+ for (ii = 0; ii < 3; ii++)
{
- if ((ac3_sample_rate_tab[jj] >> ii) == freq)
+ for (jj = 0; jj < 3; jj++)
{
- goto rate_found2;
+ if ((ac3_sample_rate_tab[jj] >> ii) == freq)
+ {
+ goto rate_found1;
+ }
}
}
- }
- hb_error("Unknown AC3 samplerate");
- ii = jj = 0;
-rate_found2:
- sr_shift = ii;
- sr_code = jj;
- bsid = 8 + ii;
- for (ii = 0; ii < 19; ii++)
- {
- if ((ac3_bitrate_tab[ii] >> sr_shift) == bitrate)
- break;
- }
- if ( ii >= 19 )
- {
- hb_error("Unknown AC3 bitrate");
- ii = 0;
- }
- bit_rate_code = ii;
-
- switch( audio->config.out.mixdown )
+ hb_error("Unknown AC3 samplerate");
+ ii = jj = 0;
+ rate_found1:
+ 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 )
+ {
+ hb_error("Unknown AC3 bitrate");
+ ii = 0;
+ }
+ bit_rate_code = ii;
+
+ mux_data->track = MP4AddAC3AudioTrack(
+ m->file,
+ freq,
+ sr_code,
+ bsid,
+ bsmod,
+ acmod,
+ lfeon,
+ bit_rate_code);
+
+ /* Tune track chunk duration */
+ MP4TuneTrackDurationPerChunk( m, mux_data->track );
+
+ 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));
+ }
+ } break;
+
+ case HB_ACODEC_FAAC:
+ case HB_ACODEC_FFAAC:
+ case HB_ACODEC_CA_AAC:
+ case HB_ACODEC_CA_HAAC:
+ case HB_ACODEC_LAME:
+ case HB_ACODEC_MP3:
+ case HB_ACODEC_DCA_HD:
+ case HB_ACODEC_DCA:
{
- case HB_AMIXDOWN_MONO:
- acmod = 1;
- break;
-
- case HB_AMIXDOWN_STEREO:
- case HB_AMIXDOWN_DOLBY:
- case HB_AMIXDOWN_DOLBYPLII:
- acmod = 2;
- break;
+ uint8_t audio_type;
+ int samplerate, samples_per_frame, channels, config_len;
+ uint8_t *config_bytes = NULL;
- 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,
- sr_code,
- bsid,
- bsmod,
- acmod,
- lfeon,
- bit_rate_code);
-
- /* Tune track chunk duration */
- MP4TuneTrackDurationPerChunk( m, mux_data->track );
-
- 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_FAAC ||
- audio->config.out.codec == HB_ACODEC_FFAAC ||
- audio->config.out.codec == HB_ACODEC_CA_AAC ||
- audio->config.out.codec == HB_ACODEC_CA_HAAC )
- {
- int samples_per_frame = ( audio->config.out.codec == HB_ACODEC_CA_HAAC ) ? 2048 : 1024;
- mux_data->track = MP4AddAudioTrack(
- m->file,
- audio->config.out.samplerate, samples_per_frame, MP4_MPEG4_AUDIO_TYPE );
-
- /* Tune track chunk duration */
- MP4TuneTrackDurationPerChunk( m, mux_data->track );
-
- if (audio->config.out.name == NULL) {
- MP4SetTrackBytesProperty(
- m->file, mux_data->track,
- "udta.name.value",
- (const uint8_t*)"Stereo", strlen("Stereo"));
- }
- else {
- MP4SetTrackBytesProperty(
- m->file, mux_data->track,
- "udta.name.value",
- (const uint8_t*)(audio->config.out.name),
- strlen(audio->config.out.name));
- }
-
- MP4SetAudioProfileLevel( m->file, 0x0F );
- MP4SetTrackESConfiguration(
- m->file, mux_data->track,
- audio->priv.config.aac.bytes, audio->priv.config.aac.length );
-
- /* Set the correct number of channels for this track */
- MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.mp4a.channels", (uint16_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown));
- } else if( audio->config.out.codec == HB_ACODEC_LAME ) {
- mux_data->track = MP4AddAudioTrack(
- m->file,
- audio->config.out.samplerate, 1152, MP4_MPEG2_AUDIO_TYPE );
+ switch ( audio->config.out.codec & HB_ACODEC_MASK )
+ {
+ case HB_ACODEC_FAAC:
+ case HB_ACODEC_FFAAC:
+ case HB_ACODEC_CA_AAC:
+ case HB_ACODEC_CA_HAAC:
+ {
+ audio_type = MP4_MPEG4_AUDIO_TYPE;
+ config_bytes = audio->priv.config.aac.bytes;
+ config_len = audio->priv.config.aac.length;
+ } break;
+ case HB_ACODEC_LAME:
+ case HB_ACODEC_MP3:
+ {
+ audio_type = MP4_MPEG2_AUDIO_TYPE;
+ } break;
+ case HB_ACODEC_DCA:
+ case HB_ACODEC_DCA_HD:
+ {
+ audio_type = 0xA9;
+ } break;
+ }
+ if( audio->config.out.codec & HB_ACODEC_PASS_FLAG )
+ {
+ samplerate = audio->config.in.samplerate;
+ samples_per_frame = audio->config.in.samples_per_frame;
+ channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(
+ audio->config.in.channel_layout );
+ }
+ else
+ {
+ samplerate = audio->config.out.samplerate;
+ samples_per_frame = audio->config.out.samples_per_frame;
+ channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
+ audio->config.out.mixdown );
+ }
+ mux_data->track = MP4AddAudioTrack( m->file, samplerate,
+ samples_per_frame, audio_type );
- /* Tune track chunk duration */
- MP4TuneTrackDurationPerChunk( m, mux_data->track );
+ /* Tune track chunk duration */
+ MP4TuneTrackDurationPerChunk( m, mux_data->track );
- if (audio->config.out.name == NULL) {
- MP4SetTrackBytesProperty(
- m->file, mux_data->track,
- "udta.name.value",
- (const uint8_t*)"Stereo", strlen("Stereo"));
- }
- else {
- MP4SetTrackBytesProperty(
- m->file, mux_data->track,
- "udta.name.value",
- (const uint8_t*)(audio->config.out.name),
- strlen(audio->config.out.name));
- }
+ if (audio->config.out.name == NULL) {
+ MP4SetTrackBytesProperty(
+ m->file, mux_data->track,
+ "udta.name.value",
+ (const uint8_t*)"Stereo", strlen("Stereo"));
+ }
+ else {
+ MP4SetTrackBytesProperty(
+ m->file, mux_data->track,
+ "udta.name.value",
+ (const uint8_t*)(audio->config.out.name),
+ strlen(audio->config.out.name));
+ }
- MP4SetAudioProfileLevel( m->file, 0x0F );
+ MP4SetAudioProfileLevel( m->file, 0x0F );
+ if ( config_bytes )
+ {
+ MP4SetTrackESConfiguration( m->file, mux_data->track,
+ config_bytes, config_len );
+ }
+ /* Set the correct number of channels for this track */
+ MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.*.channels", channels);
+ } break;
- /* Set the correct number of channels for this track */
- MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.mp4a.channels", (uint16_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown));
+ default:
+ {
+ hb_log("MP4Mux: Unsupported audio codec %x", audio->config.out.codec);
+ } break;
}
/* Set the language for this track */
diff --git a/libhb/platform/macosx/encca_aac.c b/libhb/platform/macosx/encca_aac.c
index 1bca23910..35b737e79 100644
--- a/libhb/platform/macosx/encca_aac.c
+++ b/libhb/platform/macosx/encca_aac.c
@@ -241,7 +241,7 @@ int encCoreAudioInit( hb_work_object_t * w, hb_job_t * job, enum AAC_MODE mode )
// set sizes
pv->isamplesiz = input.mBytesPerPacket;
- pv->isamples = output.mFramesPerPacket;
+ pv->isamples = audio->config.out.samples_per_frame = output.mFramesPerPacket;
pv->osamplerate = output.mSampleRate;
// set channel map and layout (for remapping)
diff --git a/libhb/scan.c b/libhb/scan.c
index 8999dc15c..43b4825bc 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -1030,6 +1030,7 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
hb_fifo_close( &audio->priv.scan_cache );
audio->config.in.samplerate = info.rate;
+ audio->config.in.samples_per_frame = info.samples_per_frame;
audio->config.in.bitrate = info.bitrate;
audio->config.in.channel_layout = info.channel_layout;
audio->config.in.channel_map = info.channel_map;
diff --git a/libhb/stream.c b/libhb/stream.c
index 84d31fe0b..d4f810c99 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -57,7 +57,7 @@ static const stream2codec_t st2codec[256] = {
st(0x0c, N, 0, 0, "ISO 13818-6 Stream descriptors"),
st(0x0d, N, 0, 0, "ISO 13818-6 Sections"),
st(0x0e, N, 0, 0, "ISO 13818-1 auxiliary"),
- st(0x0f, A, HB_ACODEC_FFMPEG, CODEC_ID_AAC, "AAC"),
+ st(0x0f, A, HB_ACODEC_FFAAC, CODEC_ID_AAC, "AAC"),
st(0x10, V, WORK_DECAVCODECV, CODEC_ID_MPEG4, "MPEG4"),
st(0x11, A, HB_ACODEC_FFMPEG, CODEC_ID_AAC_LATM, "LATM AAC"),
st(0x12, U, 0, 0, "MPEG4 generic"),
@@ -1984,7 +1984,7 @@ static void add_audio_to_title(hb_title_t *title, int id)
switch ( id >> 12 )
{
case 0x0:
- audio->config.in.codec = HB_ACODEC_FFMPEG;
+ audio->config.in.codec = HB_ACODEC_MP3;
hb_log("add_audio_to_title: added MPEG audio stream 0x%x", id);
break;
case 0x2:
@@ -3204,6 +3204,17 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
{
audio->config.in.codec = HB_ACODEC_DCA_HD;
}
+ else if ( codec->codec_id == CODEC_ID_AAC )
+ {
+ int len = MIN(codec->extradata_size, HB_CONFIG_MAX_SIZE);
+ memcpy(audio->priv.config.aac.bytes, codec->extradata, len);
+ audio->priv.config.aac.length = len;
+ audio->config.in.codec = HB_ACODEC_FFAAC;
+ }
+ else if ( codec->codec_id == CODEC_ID_MP3 )
+ {
+ audio->config.in.codec = HB_ACODEC_MP3;
+ }
else
{
audio->config.in.codec = HB_ACODEC_FFMPEG;
@@ -3212,6 +3223,7 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
audio->config.in.bitrate = codec->bit_rate? codec->bit_rate : 1;
audio->config.in.samplerate = codec->sample_rate;
+ audio->config.in.samples_per_frame = codec->frame_size;
audio->config.in.channel_layout = layout;
audio->config.in.channel_map = &hb_smpte_chan_map;
}
@@ -3698,7 +3710,7 @@ hb_buffer_t * hb_ffmpeg_read( hb_stream_t *stream )
{
buf->renderOffset = buf->start;
}
-
+
/*
* Fill out buf->stop for subtitle packets
*
diff --git a/libhb/sync.c b/libhb/sync.c
index b754a54cc..b1ec99619 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -14,8 +14,6 @@
#endif
#define INT64_MIN (-9223372036854775807LL-1)
-#define AC3_SAMPLES_PER_FRAME 1536
-
typedef struct
{
hb_lock_t * mutex;
@@ -44,9 +42,10 @@ typedef struct
SRC_STATE * state;
SRC_DATA data;
- /* AC-3 */
- int ac3_size;
- uint8_t * ac3_buf;
+ int silence_size;
+ uint8_t * silence_buf;
+
+ int drop_video_to_sync;
double gain_factor;
} hb_sync_audio_t;
@@ -261,7 +260,7 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_subtitle_t * subtitle;
hb_sync_video_t * sync = &pv->type.video;
int i;
- int64_t start, next_start;
+ int64_t next_start;
*buf_out = NULL;
next = *buf_in;
@@ -456,16 +455,12 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
return HB_WORK_DONE;
}
- hb_lock( pv->common->mutex );
- start = cur->start - pv->common->video_pts_slip;
- hb_unlock( pv->common->mutex );
-
/* Check for end of point-to-point pts encoding */
if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
{
// Drop an empty buffer into our output to ensure that things
// get flushed all the way out.
- hb_log( "sync: reached pts %"PRId64", exiting early", start );
+ hb_log( "sync: reached pts %"PRId64", exiting early", cur->start );
hb_buffer_close( &sync->cur );
hb_buffer_close( &next );
*buf_out = hb_buffer_init( 0 );
@@ -487,7 +482,7 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
if( sync->first_frame )
{
/* This is our first frame */
- if ( start > 0 )
+ if ( cur->start > 0 )
{
/*
* The first pts from a dvd should always be zero but
@@ -497,8 +492,8 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
* as if it started at zero so that our audio timing will
* be in sync.
*/
- hb_log( "sync: first pts is %"PRId64, start );
- start = 0;
+ hb_log( "sync: first pts is %"PRId64, cur->start );
+ cur->start = 0;
}
sync->first_frame = 0;
}
@@ -514,7 +509,7 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
* can deal with overlaps of up to a frame time but anything larger
* we handle by dropping frames here.
*/
- if ( next_start - start <= 0 )
+ if ( next_start - cur->start <= 0 )
{
if ( sync->first_drop == 0 )
{
@@ -533,8 +528,8 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
{
hb_log( "sync: video time didn't advance - dropped %d frames "
"(delta %d ms, current %"PRId64", next %"PRId64", dur %d)",
- sync->drop_count, (int)( start - sync->first_drop ) / 90,
- start, next_start, (int)( next_start - start ) );
+ sync->drop_count, (int)( cur->start - sync->first_drop ) / 90,
+ cur->start, next_start, (int)( next_start - cur->start ) );
sync->first_drop = 0;
sync->drop_count = 0;
}
@@ -766,14 +761,16 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
* explicit stop time from the start time of the next frame.
*/
*buf_out = cur;
+ int64_t duration = next_start - cur->start;
sync->cur = cur = next;
cur->sub = NULL;
- int64_t duration = next_start - start;
+ cur->start -= pv->common->video_pts_slip;
+ cur->stop -= pv->common->video_pts_slip;
sync->pts_skip = 0;
if ( duration <= 0 )
{
hb_log( "sync: invalid video duration %"PRId64", start %"PRId64", next %"PRId64"",
- duration, start, next_start );
+ duration, cur->start, next_start );
}
(*buf_out)->start = sync->next_start;
@@ -837,11 +834,11 @@ 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_PASS )
+ if( sync->silence_buf )
{
- free( sync->ac3_buf );
+ free( sync->silence_buf );
}
- else
+ if ( sync->state )
{
src_delete( sync->state );
}
@@ -985,29 +982,26 @@ static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
return HB_WORK_DONE;
}
- if ( start - sync->next_start < 0 )
+ // audio time went backwards.
+ // If our output clock is more than a half frame ahead of the
+ // input clock drop this frame to move closer to sync.
+ // Otherwise drop frames until the input clock matches the output clock.
+ if ( sync->next_start - start > 90*15 )
{
- // audio time went backwards.
- // If our output clock is more than a half frame ahead of the
- // input clock drop this frame to move closer to sync.
- // Otherwise drop frames until the input clock matches the output clock.
- if ( sync->first_drop || sync->next_start - start > 90*15 )
+ // Discard data that's in the past.
+ if ( sync->first_drop == 0 )
{
- // Discard data that's in the past.
- if ( sync->first_drop == 0 )
- {
- sync->first_drop = sync->next_start;
- }
- ++sync->drop_count;
- hb_buffer_close( &buf );
- return HB_WORK_OK;
+ sync->first_drop = start;
}
+ ++sync->drop_count;
+ hb_buffer_close( &buf );
+ return HB_WORK_OK;
}
if ( sync->first_drop )
{
// we were dropping old data but input buf time is now current
hb_log( "sync: audio 0x%x time went backwards %d ms, dropped %d frames "
- "(next %"PRId64", current %"PRId64")", w->audio->id,
+ "(start %"PRId64", next %"PRId64")", w->audio->id,
(int)( sync->next_start - sync->first_drop ) / 90,
sync->drop_count, sync->first_drop, (int64_t)sync->next_start );
sync->first_drop = 0;
@@ -1033,8 +1027,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_PASS ||
- w->audio->config.out.codec == HB_ACODEC_DCA_HD_PASS )
+ if ( sync->drop_video_to_sync )
{
hb_log( "sync: audio gap %d ms. Skipping frames. Audio 0x%x"
" start %"PRId64", next %"PRId64,
@@ -1103,21 +1096,41 @@ 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_PASS )
+ if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
+ w->audio->config.out.codec == HB_ACODEC_AAC_PASS )
{
- /* Have a silent AC-3 frame ready in case we have to fill a
+ /* Have a silent AC-3/AAC frame ready in case we have to fill a
gap */
AVCodec * codec;
AVCodecContext * c;
short * zeros;
- codec = avcodec_find_encoder( CODEC_ID_AC3 );
+ switch ( w->audio->config.out.codec )
+ {
+ case HB_ACODEC_AC3_PASS:
+ {
+ codec = avcodec_find_encoder( CODEC_ID_AC3 );
+ } break;
+ case HB_ACODEC_AAC_PASS:
+ {
+ codec = avcodec_find_encoder( CODEC_ID_AAC );
+ } break;
+ case HB_ACODEC_MP3_PASS:
+ {
+ codec = avcodec_find_encoder( CODEC_ID_MP3 );
+ } break;
+ default:
+ {
+ // Never gets here
+ } break;
+ }
+
c = avcodec_alloc_context3( codec );
c->bit_rate = w->audio->config.in.bitrate;
c->sample_rate = w->audio->config.in.samplerate;
c->channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( w->audio->config.in.channel_layout );
- c->sample_fmt = AV_SAMPLE_FMT_FLT;
+ hb_ff_set_sample_fmt( c, codec );
switch( w->audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK )
{
@@ -1167,14 +1180,26 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
return;
}
- zeros = calloc( AC3_SAMPLES_PER_FRAME *
- sizeof( float ) * c->channels, 1 );
- sync->ac3_size = w->audio->config.in.bitrate * AC3_SAMPLES_PER_FRAME /
- w->audio->config.in.samplerate / 8;
- sync->ac3_buf = malloc( sync->ac3_size );
+ int input_size = c->frame_size * av_get_bytes_per_sample( c->sample_fmt ) * c->channels;
+ zeros = calloc( 1, input_size );
+ // Allocate enough space for the encoded silence
+ // The output should be < the input
+ sync->silence_buf = malloc( input_size );
+
+ // There is some delay in getting output from some audio encoders.
+ // So encode a few packets till we get output.
+ int ii;
+ for ( ii = 0; ii < 10; ii++ )
+ {
+ sync->silence_size = avcodec_encode_audio( c, sync->silence_buf,
+ input_size, zeros );
- if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
- zeros ) != sync->ac3_size )
+ if (sync->silence_size)
+ {
+ break;
+ }
+ }
+ if (!sync->silence_size)
{
hb_log( "sync: avcodec_encode_audio failed" );
}
@@ -1185,12 +1210,19 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
}
else
{
- /* Initialize libsamplerate */
- int error;
- sync->state = src_new( SRC_SINC_MEDIUM_QUALITY,
- HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
- w->audio->config.out.mixdown), &error );
- sync->data.end_of_input = 0;
+ if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
+ {
+ sync->drop_video_to_sync = 1;
+ }
+ else
+ {
+ /* Not passthru, Initialize libsamplerate */
+ int error;
+ sync->state = src_new( SRC_SINC_MEDIUM_QUALITY,
+ HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
+ w->audio->config.out.mixdown), &error );
+ sync->data.end_of_input = 0;
+ }
}
sync->gain_factor = pow(LVL_PLUS1DB, w->audio->config.out.gain);
@@ -1293,29 +1325,39 @@ static void InsertSilence( hb_work_object_t * w, int64_t duration )
hb_sync_audio_t *sync = &pv->type.audio;
hb_buffer_t *buf;
hb_fifo_t *fifo;
+ int frame_dur, frame_count;
// to keep pass-thru and regular audio in sync we generate silence in
- // AC3 frame-sized units. If the silence duration isn't an integer multiple
- // of the AC3 frame duration we will truncate or round up depending on
+ // frame-sized units. If the silence duration isn't an integer multiple
+ // of the frame duration we will truncate or round up depending on
// which minimizes the timing error.
- const int frame_dur = ( 90000 * AC3_SAMPLES_PER_FRAME ) /
- w->audio->config.in.samplerate;
- int frame_count = ( duration + (frame_dur >> 1) ) / frame_dur;
+ if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
+ {
+ frame_dur = ( 90000 * w->audio->config.in.samples_per_frame ) /
+ w->audio->config.in.samplerate;
+ }
+ else
+ {
+ frame_dur = ( 90000 * w->audio->config.out.samples_per_frame ) /
+ w->audio->config.in.samplerate;
+ }
+ frame_count = ( duration + (frame_dur >> 1) ) / frame_dur;
while ( --frame_count >= 0 )
{
- if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS )
+ if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
{
- buf = hb_buffer_init( sync->ac3_size );
+ buf = hb_buffer_init( sync->silence_size );
buf->start = sync->next_start;
buf->stop = buf->start + frame_dur;
- memcpy( buf->data, sync->ac3_buf, buf->size );
+ memcpy( buf->data, sync->silence_buf, buf->size );
fifo = w->audio->priv.fifo_out;
}
else
{
- buf = hb_buffer_init( AC3_SAMPLES_PER_FRAME * sizeof( float ) *
- HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
+ buf = hb_buffer_init( w->audio->config.out.samples_per_frame *
+ sizeof( float ) *
+ HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(
w->audio->config.out.mixdown) );
buf->start = sync->next_start;
buf->stop = buf->start + frame_dur;
diff --git a/libhb/work.c b/libhb/work.c
index ffd48ec4b..222ae240f 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -378,6 +378,8 @@ void hb_display_job_info( hb_job_t * job )
if( audio->config.out.codec & HB_ACODEC_PASS_FLAG )
{
hb_log( " + %s passthrough",
+ (audio->config.out.codec == HB_ACODEC_MP3_PASS) ? "MP3" :
+ (audio->config.out.codec == HB_ACODEC_AAC_PASS) ? "AAC" :
(audio->config.out.codec == HB_ACODEC_AC3_PASS) ? "AC3" :
(audio->config.out.codec == HB_ACODEC_DCA_PASS) ? "DTS" :
"DTS-HD");
diff --git a/macosx/HBAudio.m b/macosx/HBAudio.m
index e92e578e4..b7fdbcc85 100644
--- a/macosx/HBAudio.m
+++ b/macosx/HBAudio.m
@@ -107,41 +107,55 @@ static NSMutableArray *masterBitRateArray = nil;
[NSNumber numberWithBool: NO], keyAudioMustMatchTrack,
nil]];
[masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
- NSLocalizedString(@"MP3 (lame)", @"MP3 (lame)"), keyAudioCodecName,
- [NSNumber numberWithInt: HB_ACODEC_LAME], keyAudioCodec,
+ NSLocalizedString(@"AAC Passthru", @"AAC Passthru"), keyAudioCodecName,
+ [NSNumber numberWithInt: HB_ACODEC_AAC_PASS], keyAudioCodec,
[NSNumber numberWithBool: YES], keyAudioMP4,
[NSNumber numberWithBool: YES], keyAudioMKV,
- [NSNumber numberWithBool: NO], keyAudioMustMatchTrack,
+ [NSNumber numberWithInt: HB_ACODEC_FFAAC], keyAudioMustMatchTrack,
nil]];
[masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
- NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioCodecName,
- [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioCodec,
+ NSLocalizedString(@"AC3 (ffmpeg)", @"AC3 (ffmpeg)"), keyAudioCodecName,
+ [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioCodec,
[NSNumber numberWithBool: YES], keyAudioMP4,
[NSNumber numberWithBool: YES], keyAudioMKV,
- [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioMustMatchTrack,
+ [NSNumber numberWithBool: NO], keyAudioMustMatchTrack,
nil]];
[masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
- NSLocalizedString(@"AC3 (ffmpeg)", @"AC3 (ffmpeg)"), keyAudioCodecName,
- [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioCodec,
+ NSLocalizedString(@"AC3 Passthru", @"AC3 Passthru"), keyAudioCodecName,
+ [NSNumber numberWithInt: HB_ACODEC_AC3_PASS], keyAudioCodec,
[NSNumber numberWithBool: YES], keyAudioMP4,
[NSNumber numberWithBool: YES], keyAudioMKV,
- [NSNumber numberWithBool: NO], keyAudioMustMatchTrack,
+ [NSNumber numberWithInt: HB_ACODEC_AC3], keyAudioMustMatchTrack,
nil]];
[masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(@"DTS Passthru", @"DTS Passthru"), keyAudioCodecName,
[NSNumber numberWithInt: HB_ACODEC_DCA_PASS], keyAudioCodec,
- [NSNumber numberWithBool: NO], keyAudioMP4,
+ [NSNumber numberWithBool: YES], keyAudioMP4,
[NSNumber numberWithBool: YES], keyAudioMKV,
[NSNumber numberWithInt: HB_ACODEC_DCA], keyAudioMustMatchTrack,
nil]];
[masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(@"DTS-HD Passthru", @"DTS-HD Passthru"), keyAudioCodecName,
[NSNumber numberWithInt: HB_ACODEC_DCA_HD_PASS], keyAudioCodec,
- [NSNumber numberWithBool: NO], keyAudioMP4,
+ [NSNumber numberWithBool: YES], keyAudioMP4,
[NSNumber numberWithBool: YES], keyAudioMKV,
[NSNumber numberWithInt: HB_ACODEC_DCA_HD], keyAudioMustMatchTrack,
nil]];
[masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
+ NSLocalizedString(@"MP3 (lame)", @"MP3 (lame)"), keyAudioCodecName,
+ [NSNumber numberWithInt: HB_ACODEC_LAME], keyAudioCodec,
+ [NSNumber numberWithBool: YES], keyAudioMP4,
+ [NSNumber numberWithBool: YES], keyAudioMKV,
+ [NSNumber numberWithBool: NO], keyAudioMustMatchTrack,
+ nil]];
+ [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
+ NSLocalizedString(@"MP3 Passthru", @"MP3 Passthru"), keyAudioCodecName,
+ [NSNumber numberWithInt: HB_ACODEC_MP3_PASS], keyAudioCodec,
+ [NSNumber numberWithBool: YES], keyAudioMP4,
+ [NSNumber numberWithBool: YES], keyAudioMKV,
+ [NSNumber numberWithInt: HB_ACODEC_MP3], keyAudioMustMatchTrack,
+ nil]];
+ [masterCodecArray addObject: [NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(@"Vorbis (vorbis)", @"Vorbis (vorbis)"), keyAudioCodecName,
[NSNumber numberWithInt: HB_ACODEC_VORBIS], keyAudioCodec,
[NSNumber numberWithBool: NO], keyAudioMP4,
diff --git a/macosx/HBAudioController.m b/macosx/HBAudioController.m
index ec9314697..b2de10c98 100644
--- a/macosx/HBAudioController.m
+++ b/macosx/HBAudioController.m
@@ -299,6 +299,13 @@ NSString *HBMixdownChangedNotification = @"HBMixdownChangedNotification";
{
[dict setObject: @"AAC (CoreAudio)" forKey: @"AudioEncoder"];
}
+ // Auto Passthru not yet implemented - fallback to AC3 Passthru as it is
+ // compatible with all source codecs (via the AC3 encoder fallback)
+ if ([key isEqualToString: @"Auto Passthru"])
+ {
+ [dict setObject: @"AC3 Passthru" forKey: @"AudioEncoder"];
+ key = @"AC3 Passthru";
+ }
if ([[NSUserDefaults standardUserDefaults] boolForKey: @"AC3PassthruDefaultsToAC3"] &&
[key isEqualToString: @"AC3 Passthru"])
{
diff --git a/test/test.c b/test/test.c
index d9f360dec..4fd728537 100644
--- a/test/test.c
+++ b/test/test.c
@@ -2563,17 +2563,39 @@ static void ShowHelp()
#ifdef __APPLE_CC__
fprintf( out,
" -E, --aencoder <string> Audio encoder(s)\n"
- " (ca_aac/ca_haac/faac/lame/vorbis/ac3/copy/copy:ac3/copy:dts)\n"
- " copy, copy:ac3 and copy:dts meaning passthrough.\n"
- " copy will passthrough either ac3 or dts.\n"
+ " ca_aac\n"
+ " ca_haac\n"
+ " faac\n"
+ " lame\n"
+ " vorbis\n"
+ " ac3\n"
+ " copy\n"
+ " copy:aac\n"
+ " copy:ac3\n"
+ " copy:dts\n"
+ " copy:dtshd\n"
+ " copy:mp3\n"
+ " copy* will passthrough the corresponding\n"
+ " audio unmodified to the muxer if it is a\n"
+ " supported passthrough audio type.\n"
" Separated by commas for more than one audio track.\n"
" (default: ca_aac)\n" );
#else
fprintf( out,
" -E, --aencoder <string> Audio encoder(s):\n"
- " (faac/lame/vorbis/ac3/copy/copy:ac3/copy:dts)\n"
- " copy, copy:ac3 and copy:dts meaning passthrough.\n"
- " copy will passthrough either ac3 or dts.\n"
+ " faac\n"
+ " lame\n"
+ " vorbis\n"
+ " ac3\n"
+ " copy\n"
+ " copy:aac\n"
+ " copy:ac3\n"
+ " copy:dts\n"
+ " copy:dtshd\n"
+ " copy:mp3\n"
+ " copy* will passthrough the corresponding\n"
+ " audio unmodified to the muxer if it is a\n"
+ " supported passthrough audio type.\n"
" Separated by commas for more than one audio track.\n"
" (default: faac for mp4, lame for mkv)\n" );
#endif
@@ -3427,6 +3449,10 @@ static int ParseOptions( int argc, char ** argv )
allowed_audio_copy |= HB_ACODEC_DCA;
if ( !strcmp( allowed[i], "dtshd" ) )
allowed_audio_copy |= HB_ACODEC_DCA_HD;
+ if ( !strcmp( allowed[i], "mp3" ) )
+ allowed_audio_copy |= HB_ACODEC_MP3;
+ if ( !strcmp( allowed[i], "aac" ) )
+ allowed_audio_copy |= HB_ACODEC_FFAAC;
}
str_vfree( allowed );
} break;
@@ -3600,6 +3626,10 @@ static int get_acodec_for_string( char *codec )
{
return (HB_ACODEC_PASS_MASK & allowed_audio_copy) | HB_ACODEC_PASS_FLAG;
}
+ else if( !strcasecmp( codec, "copy:aac" ) )
+ {
+ return HB_ACODEC_AAC_PASS;
+ }
else if( !strcasecmp( codec, "copy:ac3" ) )
{
return HB_ACODEC_AC3_PASS;
@@ -3612,6 +3642,10 @@ static int get_acodec_for_string( char *codec )
{
return HB_ACODEC_DCA_HD_PASS;
}
+ else if( !strcasecmp( codec, "copy:mp3" ) )
+ {
+ return HB_ACODEC_MP3_PASS;
+ }
else if( !strcasecmp( codec, "lame" ) )
{
return HB_ACODEC_LAME;