]> granicus.if.org Git - handbrake/commitdiff
add more audio passthru options
authorjstebbins <jstebbins.hb@gmail.com>
Mon, 1 Aug 2011 18:06:22 +0000 (18:06 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Mon, 1 Aug 2011 18:06:22 +0000 (18:06 +0000)
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

29 files changed:
contrib/ffmpeg/A04-dca-frame-size.patch [new file with mode: 0644]
gtk/src/audiohandler.c
gtk/src/audiohandler.h
gtk/src/callbacks.c
gtk/src/ghb.ui
gtk/src/hb-backend.c
gtk/src/hb-backend.h
gtk/src/internal_defaults.xml
gtk/src/makedeps.py
gtk/src/presets.c
libhb/common.h
libhb/deca52.c
libhb/decavcodec.c
libhb/decdca.c
libhb/declpcm.c
libhb/encavcodecaudio.c
libhb/encfaac.c
libhb/enclame.c
libhb/encvorbis.c
libhb/muxmkv.c
libhb/muxmp4.c
libhb/platform/macosx/encca_aac.c
libhb/scan.c
libhb/stream.c
libhb/sync.c
libhb/work.c
macosx/HBAudio.m
macosx/HBAudioController.m
test/test.c

diff --git a/contrib/ffmpeg/A04-dca-frame-size.patch b/contrib/ffmpeg/A04-dca-frame-size.patch
new file mode 100644 (file)
index 0000000..5af1040
--- /dev/null
@@ -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;
index 54cd1a4960bd962e8ccbebc1c5ea9df78ba59676..ee84a798fbc5e39ce5164b2da8241f94dcabe5c4 100644 (file)
@@ -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)
 {
index 87b9612f76fab1f995cd42faf450f145a88c7910..74df87a3df504137588117d93854e0d1d6d88009 100644 (file)
@@ -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_
index 0fd92a9e6d7cfc6ec7d02e64e89b78daff5e48d2..03d5766035c95511007b7351e08b554b72198de8 100644 (file)
@@ -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
index 999f3c6211fd1da74c91e9e493be430217500be2..7d037434b3cc7a56ba9fe3df00a6cb462cc999b5 100644 (file)
                                   <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>
index 8a90d4ece63f900986385c915c04b360bb26e9bd..a3b9e51061198d551ec85d74355b2d1236e171d2 100644 (file)
@@ -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");
index 6733ad30690b94d991e205faa2b11cfeff55afb1..f59d821a6ed1f03ab28a2d3ad2e7898cf215ea05 100644 (file)
@@ -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);
 
index e4a4a72b6a42ae831bfcc3c9dbf1cdd1b3755a7c..b4d06694d0804cab2648323bc86315d16fc1363c 100644 (file)
                <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>
index a16b28ca55107fd1fde5dccc03525adda677291a..65d398eca4dbc19c7fc395cb5542e32d35177541 100644 (file)
@@ -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),
index 064d27323d6482761ea985fbaaa98d26c03b5360..0a4d46745524d90830f1da71c7355047a59d86a9 100644 (file)
@@ -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}
 };
 
index 48a4812bbb96f4c6f656f928b9e0548590643925..88bb8389dcd7506839d256aeb92d2d5c5310447c 100644 (file)
@@ -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;
index 2771eda554c330a7b25d04a8530d304fb19ded79..a8d537d524b944bfab3474f976a2482d2de0c1be 100644 (file)
@@ -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 )
     {
index e520216555fb78641841428023e46b4f7f508c0d..f67850d862a8c46cc0bea4367f5d061790882e79 100644 (file)
@@ -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;
                 }
             }
index 138024a6d6fa678c5ee5e65636d3d3d7046f3f72..4f5ee3929238034b76fb2025203a3b1ee7b0e31b 100644 (file)
@@ -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 )
     {
index 3dd1f736652ebfbb26f6b4bf86ae1207e70e420b..62eb563e85eb0c3b24f98bb0fda7ba7115a3a195 100644 (file)
@@ -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;
 }
index 9239c519a03777993c539e1c29219eab2228a977..ebf2fd8f20c17c15071138cc20cb2ae52496ff2f 100644 (file)
@@ -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
index fe1a1f55badb04949269068401f7d3d19b5a93f9..0ab9124c8db9a676667cf214a4df4998d768ea8b 100644 (file)
@@ -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;
index ba05e1fc06db43ad3ef4cc17d46b658e8c54fa2c..434aa185ec1f464f6ea9b09aba1063cba95a61a6 100644 (file)
@@ -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;
index 01bd216e8bcc7ccaa5117b55cd584a21c6b8cdbd..fc186e089ea85d4e3a84dd28ebc882a8f90d1647 100644 (file)
@@ -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();
index f73139b98a1cc4ec1d124bf883e99505be7bec0f..2ec32139d7a9d68dbbe4c16ad3b4076904735cb4 100644 (file)
@@ -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);
         }
index b9c7637e8daca39e2515fe48f0544df03e748113..05bce561a27a30338c760b7273ee39acf419b87c 100644 (file)
@@ -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 */
index 1bca2391085b68051eee2a4670b08f73906534b5..35b737e793a6a8d7ac4d5301a345fb6084783f77 100644 (file)
@@ -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)
index 8999dc15ca4f6998493764b5e3ade3bd668f02ea..43b4825bcb2586e0db76ee74dc45b34b8a7cbec9 100644 (file)
@@ -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;
index 84d31fe0b16a98c4bbe525e56594cecb5113bb77..d4f810c99e8a053ffe7ba26393ec9ac3607c8990 100644 (file)
@@ -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
      * 
index b754a54cc7d3e95fad907b26703e5111cce2eda7..b1ec99619d19e439d2384c3c887f9c578528fccc 100644 (file)
@@ -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;
index ffd48ec4b8cae819457e1c797cbb6b3469564e58..222ae240f1d436961ce79355ac8e0133b22ee927 100644 (file)
@@ -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");
index e92e578e4b9daa5d4f1bef739e564a11d665a3a9..b7fdbcc858470161093eab5b6abf30e60dfb1b97 100644 (file)
@@ -107,40 +107,54 @@ 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,
index ec931469733537747f11260c71ea0b16a36121aa..b2de10c9864d0343c64b0c95794244e3999ecb2d 100644 (file)
@@ -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"])
             {
index d9f360dec81f02fb68ffa55b06ff778c0a08c4b1..4fd7285376840a98ae7f30d77b38fd2242bf7e6e 100644 (file)
@@ -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;