OSDN Git Service

New internal audio handling.
authorsaintdev <saintdev@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 1 Apr 2008 21:25:54 +0000 (21:25 +0000)
committersaintdev <saintdev@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 1 Apr 2008 21:25:54 +0000 (21:25 +0000)
Each audio track contains it's own settings for codec, bitrate, samplerate, etc.
This allows for very complex combinations of audio tracks if desired.

git-svn-id: svn://localhost/HandBrake/trunk@1365 b64f7644-9d1e-0410-96f1-a4d463321fa5

19 files changed:
libhb/common.c
libhb/common.h
libhb/deca52.c
libhb/decdca.c
libhb/dvd.c
libhb/encfaac.c
libhb/enclame.c
libhb/encvorbis.c
libhb/hb.c
libhb/muxavi.c
libhb/muxcommon.c
libhb/muxmkv.c
libhb/muxmp4.c
libhb/muxogm.c
libhb/reader.c
libhb/scan.c
libhb/stream.c
libhb/sync.c
libhb/work.c

index d802f41..247d15e 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdarg.h>
 #include <time.h>
 #include <sys/time.h>
+#include <assert.h>
 
 #include "common.h"
 
@@ -43,9 +44,7 @@ hb_mixdown_t hb_audio_mixdowns[] =
   { "Stereo",             "HB_AMIXDOWN_STEREO",    "stereo", HB_AMIXDOWN_STEREO    },
   { "Dolby Surround",     "HB_AMIXDOWN_DOLBY",     "dpl1",   HB_AMIXDOWN_DOLBY     },
   { "Dolby Pro Logic II", "HB_AMIXDOWN_DOLBYPLII", "dpl2",   HB_AMIXDOWN_DOLBYPLII },
-  { "6-channel discrete", "HB_AMIXDOWN_6CH",       "6ch",    HB_AMIXDOWN_6CH       },
-  { "AC-3 Pass-through",  "HB_AMIXDOWN_AC3",       "ac-3",   HB_AMIXDOWN_AC3       },
-  { "Dolby Pro Logic II + AC-3",  "HB_AMIXDOWN_DOLBYPLII_AC3", "dpl2+ac3", HB_AMIXDOWN_DOLBYPLII_AC3 },
+  { "6-channel discrete", "HB_AMIXDOWN_6CH",       "6ch",    HB_AMIXDOWN_6CH       }
 };
 int hb_audio_mixdowns_count = sizeof( hb_audio_mixdowns ) /
                               sizeof( hb_mixdown_t );
@@ -115,7 +114,7 @@ void hb_fix_aspect( hb_job_t * job, int keep )
     if ( title->height == 0 || title->width == 0 || title->aspect == 0 )
     {
         hb_log( "hb_fix_aspect: incomplete info for title %d: "
-                "height = %d, width = %d, aspect = %d", 
+                "height = %d, width = %d, aspect = %d",
                 title->height, title->width, title->aspect );
         return;
     }
@@ -202,23 +201,6 @@ int hb_calc_bitrate( hb_job_t * job, int size )
             return 0;
     }
 
-    /* How many audio samples we put in each frame */
-    switch( job->acodec )
-    {
-        case HB_ACODEC_FAAC:
-        case HB_ACODEC_VORBIS:
-            samples_per_frame = 1024;
-            break;
-        case HB_ACODEC_LAME:
-            samples_per_frame = 1152;
-            break;
-        case HB_ACODEC_AC3:
-            samples_per_frame = 1536;
-            break;
-        default:
-            return 0;
-    }
-
     /* Get the duration in seconds */
     length = 0;
     for( i = job->chapter_start; i <= job->chapter_end; i++ )
@@ -232,19 +214,37 @@ int hb_calc_bitrate( hb_job_t * job, int size )
     /* Video overhead */
     avail -= length * job->vrate * overhead / job->vrate_base;
 
-    for( i = 0; job->audios[i] >= 0; i++ )
+    for( i = 0; i < hb_list_count(job->list_audio); i++ )
     {
         /* Audio data */
         int abitrate;
-        if( job->acodec & HB_ACODEC_AC3 ||
-            job->audio_mixdowns[i] == HB_AMIXDOWN_AC3)
+        audio = hb_list_item( job->list_audio, i);
+
+        /* How many audio samples we put in each frame */
+        switch( audio->config.out.codec )
+        {
+            case HB_ACODEC_FAAC:
+            case HB_ACODEC_VORBIS:
+                samples_per_frame = 1024;
+                break;
+            case HB_ACODEC_LAME:
+                samples_per_frame = 1152;
+                break;
+            case HB_ACODEC_AC3:
+                samples_per_frame = 1536;
+                break;
+            default:
+                return 0;
+        }
+
+        if( audio->config.out.codec == HB_ACODEC_AC3 ||
+            audio->config.out.codec == HB_ACODEC_DCA)
         {
             /*
-             * For AC-3 we take the bitrate from the input audio
+             * For pass through we take the bitrate from the input audio
              * bitrate as we are simply passing it through.
              */
-            audio = hb_list_item( title->list_audio, job->audios[i] );
-            abitrate = audio->bitrate / 8;
+            abitrate = audio->config.in.bitrate / 8;
         }
         else
         {
@@ -252,12 +252,12 @@ int hb_calc_bitrate( hb_job_t * job, int size )
              * Where we are transcoding the audio we use the destination
              * bitrate.
              */
-            abitrate = job->abitrate * 1000 / 8;
+            abitrate = audio->config.out.bitrate * 1000 / 8;
         }
         avail -= length * abitrate;
 
         /* Audio overhead */
-        avail -= length * job->arate * overhead / samples_per_frame;
+        avail -= length * audio->config.out.samplerate * overhead / samples_per_frame;
     }
 
     if( avail < 0 )
@@ -654,3 +654,93 @@ void hb_filter_close( hb_filter_object_t ** _f )
     *_f = NULL;
 }
 
+/**********************************************************************
+ * hb_audio_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_audio_t *hb_audio_copy(const hb_audio_t *src)
+{
+    hb_audio_t *audio = calloc(1, sizeof(*audio));
+    memcpy(audio, src, sizeof(*audio));
+    return audio;
+}
+
+/**********************************************************************
+ * hb_audio_new
+ **********************************************************************
+ *
+ *********************************************************************/
+void hb_audio_config_init(hb_audio_config_t * audiocfg)
+{
+    assert(audiocfg != NULL);
+
+    /* Set read only paramaters to invalid values */
+    audiocfg->in.codec = 0xDEADBEEF;
+    audiocfg->in.bitrate = -1;
+    audiocfg->in.samplerate = -1;
+    audiocfg->in.channel_layout = 0;
+    audiocfg->flags.ac3 = 0;
+    audiocfg->lang.description[0] = 0;
+    audiocfg->lang.simple[0] = 0;
+    audiocfg->lang.iso639_2[0] = 0;
+
+    /* Initalize some sensable defaults */
+    audiocfg->in.track = audiocfg->out.track = 0;
+    audiocfg->out.codec = HB_ACODEC_FAAC;
+    audiocfg->out.bitrate = 128;
+    audiocfg->out.samplerate = 44100;
+    audiocfg->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
+    audiocfg->out.dynamic_range_compression = 0;
+}
+
+/**********************************************************************
+ * hb_audio_add
+ **********************************************************************
+ *
+ *********************************************************************/
+int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg)
+{
+    assert(job != NULL);
+    assert(audiocfg != NULL);
+
+    hb_title_t *title = job->title;
+    hb_audio_t *audio;
+
+    audio = hb_audio_copy( hb_list_item( title->list_audio, audiocfg->in.track ) );
+    if( audio == NULL )
+    {
+        /* We fail! */
+        return 0;
+    }
+
+    if( (audiocfg->in.bitrate != -1) && (audiocfg->in.codec != 0xDEADBEEF) )
+    {
+        /* This most likely means the client didn't call hb_audio_config_init
+         * so bail.
+         */
+        return 0;
+    }
+
+    /* Really shouldn't ignore the passed out track, but there is currently no
+     * way to handle duplicates or out-of-order track numbers.
+     */
+    audio->config.out.track = hb_list_count(job->list_audio) + 1;
+    audio->config.out.codec = audiocfg->out.codec;
+    audio->config.out.samplerate = audiocfg->out.samplerate;
+    audio->config.out.bitrate = audiocfg->out.bitrate;
+    audio->config.out.mixdown = audiocfg->out.mixdown;
+    audio->config.out.dynamic_range_compression = audiocfg->out.dynamic_range_compression;
+
+    hb_list_add(job->list_audio, audio);
+    return 1;
+}
+
+hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i)
+{
+    assert(list != NULL);
+
+    hb_audio_t *audio = hb_list_item(list, i);
+
+    return &(audio->config);
+}
index 4758d9c..1eef164 100644 (file)
@@ -39,6 +39,7 @@ typedef struct hb_job_s  hb_job_t;
 typedef struct hb_title_s hb_title_t;
 typedef struct hb_chapter_s hb_chapter_t;
 typedef struct hb_audio_s hb_audio_t;
+typedef struct hb_audio_config_s hb_audio_config_t;
 typedef struct hb_subtitle_s hb_subtitle_t;
 typedef struct hb_state_s hb_state_t;
 typedef union  hb_esconfig_u     hb_esconfig_t;
@@ -53,6 +54,9 @@ typedef struct hb_lock_s hb_lock_t;
 #include "ports.h"
 #ifdef __LIBHB__
 #include "internal.h"
+#define PRIVATE
+#else
+#define PRIVATE const
 #endif
 
 hb_list_t * hb_list_init();
@@ -70,6 +74,11 @@ void hb_fix_aspect( hb_job_t * job, int keep );
 
 int hb_calc_bitrate( hb_job_t *, int size );
 
+hb_audio_t *hb_audio_copy(const hb_audio_t *src);
+void hb_audio_config_init(hb_audio_config_t * audiocfg);
+int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg);
+hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i);
+
 struct hb_rate_s
 {
     char * string;
@@ -175,76 +184,8 @@ struct hb_job_s
     int             areBframes;
     int             vfr;
 
-    /* Audio tracks:
-         audios:          Indexes in hb_title_t's audios list, starting from 0.
-                          -1 indicates the end of the list
-        audio_mixdowns:  The mixdown to be used for each audio track in audios[] */
-
-/* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
-#define HB_AMIXDOWN_DCA_FORMAT_MASK             0x00FFF000
-#define HB_AMIXDOWN_A52_FORMAT_MASK             0x00000FF0
-#define HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK 0x0000000F
-
-/* define the HB_AMIXDOWN_XXXX values */
-
-#define HB_AMIXDOWN_MONO                        0x01000001
-// DCA_FORMAT of DCA_MONO                  = 0    = 0x000
-// A52_FORMAT of A52_MONO                  = 1    = 0x01
-// discrete channel count of 1
-
-#define HB_AMIXDOWN_STEREO                      0x02002022
-// DCA_FORMAT of DCA_STEREO                = 2    = 0x002
-// A52_FORMAT of A52_STEREO                = 2    = 0x02
-// discrete channel count of 2
-
-#define HB_AMIXDOWN_DOLBY                       0x042070A2
-// DCA_FORMAT of DCA_3F1R | DCA_OUT_DPLI   = 519  = 0x207
-// A52_FORMAT of A52_DOLBY                 = 10   = 0x0A
-// discrete channel count of 2
-
-#define HB_AMIXDOWN_DOLBYPLII                   0x084094A2
-// DCA_FORMAT of DCA_3F2R | DCA_OUT_DPLII  = 1033 = 0x409
-// A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74   = 0x4A
-// discrete channel count of 2
-
-#define HB_AMIXDOWN_6CH                         0x10089176
-// DCA_FORMAT of DCA_3F2R | DCA_LFE        = 137  = 0x089
-// A52_FORMAT of A52_3F2R | A52_LFE        = 23   = 0x17
-// discrete channel count of 6
-
-#define HB_AMIXDOWN_AC3                         0x20000000
-
-#define HB_AMIXDOWN_DOLBYPLII_AC3               0x404094A2
-// DCA_FORMAT of DCA_3F2R | DCA_OUT_DPLII  = 1033 = 0x409
-// A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74   = 0x4A
-// discrete channel count of 2
-
-/* define some macros to extract the various information from the HB_AMIXDOWN_XXXX values */
-#define HB_AMIXDOWN_GET_DCA_FORMAT( a ) ( ( a & HB_AMIXDOWN_DCA_FORMAT_MASK ) >> 12 )
-#define HB_AMIXDOWN_GET_A52_FORMAT( a ) ( ( a & HB_AMIXDOWN_A52_FORMAT_MASK ) >> 4 )
-#define HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK ) )
-
-    int             audios[8];
-       int             audio_mixdowns[8];
-
-    /* Audio settings:
-         acodec:   output codec
-         abitrate: output bitrate (kbps)
-         arate:    output samplerate (Hz)
-       HB_ACODEC_AC3 means pass-through, then abitrate and arate are
-       ignored */
-#define HB_ACODEC_MASK   0x00FF00
-#define HB_ACODEC_FAAC   0x000100
-#define HB_ACODEC_LAME   0x000200
-#define HB_ACODEC_VORBIS 0x000400
-#define HB_ACODEC_AC3    0x000800
-#define HB_ACODEC_MPGA   0x001000
-#define HB_ACODEC_LPCM   0x002000
-#define HB_ACODEC_DCA    0x004000
-    int             acodec;
-    int             abitrate;
-    int             arate;
-    float           dynamic_range_compression;
+    /* List of audio settings. */
+    hb_list_t     * list_audio;
 
     /* Subtitle settings:
          subtitle: index in hb_title_t's subtitles list, starting
@@ -300,22 +241,49 @@ struct hb_job_s
 #endif
 };
 
-struct hb_audio_s
-{
-    int  id;
-    char lang[1024];
-    char lang_simple[1024];
-    char iso639_2[4];
-    int  codec;
-    int  rate;
-    int  bitrate;
-
-    /* ac3flags is only set when the source audio format is HB_ACODEC_AC3 */
-    int ac3flags;
+/* Audio starts here */
+/* Audio Codecs */
+#define HB_ACODEC_MASK   0x00FF00
+#define HB_ACODEC_FAAC   0x000100
+#define HB_ACODEC_LAME   0x000200
+#define HB_ACODEC_VORBIS 0x000400
+#define HB_ACODEC_AC3    0x000800
+#define HB_ACODEC_MPGA   0x001000
+#define HB_ACODEC_LPCM   0x002000
+#define HB_ACODEC_DCA    0x004000
 
-    /* dcaflags is only set when the source audio format is HB_ACODEC_DCA */
-    int dcaflags;
+/* Audio Mixdown */
+/* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
+#define HB_AMIXDOWN_DCA_FORMAT_MASK             0x00FFF000
+#define HB_AMIXDOWN_A52_FORMAT_MASK             0x00000FF0
+#define HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK 0x0000000F
+/* define the HB_AMIXDOWN_XXXX values */
+#define HB_AMIXDOWN_MONO                        0x01000001
+// DCA_FORMAT of DCA_MONO                  = 0    = 0x000
+// A52_FORMAT of A52_MONO                  = 1    = 0x01
+// discrete channel count of 1
+#define HB_AMIXDOWN_STEREO                      0x02002022
+// DCA_FORMAT of DCA_STEREO                = 2    = 0x002
+// A52_FORMAT of A52_STEREO                = 2    = 0x02
+// discrete channel count of 2
+#define HB_AMIXDOWN_DOLBY                       0x042070A2
+// DCA_FORMAT of DCA_3F1R | DCA_OUT_DPLI   = 519  = 0x207
+// A52_FORMAT of A52_DOLBY                 = 10   = 0x0A
+// discrete channel count of 2
+#define HB_AMIXDOWN_DOLBYPLII                   0x084094A2
+// DCA_FORMAT of DCA_3F2R | DCA_OUT_DPLII  = 1033 = 0x409
+// A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74   = 0x4A
+// discrete channel count of 2
+#define HB_AMIXDOWN_6CH                         0x10089176
+// DCA_FORMAT of DCA_3F2R | DCA_LFE        = 137  = 0x089
+// A52_FORMAT of A52_3F2R | A52_LFE        = 23   = 0x17
+// discrete channel count of 6
+/* define some macros to extract the various information from the HB_AMIXDOWN_XXXX values */
+#define HB_AMIXDOWN_GET_DCA_FORMAT( a ) ( ( a & HB_AMIXDOWN_DCA_FORMAT_MASK ) >> 12 )
+#define HB_AMIXDOWN_GET_A52_FORMAT( a ) ( ( a & HB_AMIXDOWN_A52_FORMAT_MASK ) >> 4 )
+#define HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK ) )
 
+/* Input Channel Layout */
 /* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
 #define HB_INPUT_CH_LAYOUT_DISCRETE_FRONT_MASK  0x00F0000
 #define HB_INPUT_CH_LAYOUT_DISCRETE_REAR_MASK   0x000F000
@@ -323,7 +291,6 @@ struct hb_audio_s
 #define HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK 0xFFFF0FF
 #define HB_INPUT_CH_LAYOUT_ENCODED_FRONT_MASK   0x00000F0
 #define HB_INPUT_CH_LAYOUT_ENCODED_REAR_MASK    0x000000F
-
 /* define the input channel layouts used to describe the channel layout of this audio */
 #define HB_INPUT_CH_LAYOUT_MONO    0x0110010
 #define HB_INPUT_CH_LAYOUT_STEREO  0x0220020
@@ -335,7 +302,6 @@ struct hb_audio_s
 #define HB_INPUT_CH_LAYOUT_3F2R    0x0832032
 #define HB_INPUT_CH_LAYOUT_4F2R    0x0942042
 #define HB_INPUT_CH_LAYOUT_HAS_LFE 0x0000100
-
 /* define some macros to extract the various information from the HB_AMIXDOWN_XXXX values */
 #define HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT( a ) ( ( a & HB_INPUT_CH_LAYOUT_DISCRETE_FRONT_MASK ) >> 16 )
 #define HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT( a )  ( ( a & HB_INPUT_CH_LAYOUT_DISCRETE_REAR_MASK ) >> 12 )
@@ -344,24 +310,68 @@ struct hb_audio_s
 #define HB_INPUT_CH_LAYOUT_GET_ENCODED_FRONT_COUNT( a )   ( ( a & HB_INPUT_CH_LAYOUT_ENCODED_FRONT_MASK ) >> 4 )
 #define HB_INPUT_CH_LAYOUT_GET_ENCODED_REAR_COUNT( a )   ( ( a & HB_INPUT_CH_LAYOUT_ENCODED_REAR_MASK ) )
 
-       /* input_channel_layout is the channel layout of this audio */
-       /* this is used to provide a common way of describing the source audio */
-       int input_channel_layout;
+struct hb_audio_config_s
+{
+    /* Output */
+    struct
+    {
+            int track;      /* Output track number */
+            uint32_t codec;  /* Output audio codec.
+                                 * HB_ACODEC_AC3 means pass-through, then bitrate and samplerate
+                                 * are ignored.
+                                 */
+            int samplerate; /* Output sample rate (Hz) */
+            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 */
+    } out;
+
+    /* Input */
+    struct
+    {
+                int track;      /* Input track number */
+        PRIVATE uint32_t codec;      /* Input audio codec */
+        PRIVATE int samplerate; /* Input sample rate (Hz) */
+        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
+        */
+    } in;
+
+    /* Misc. */
+    union
+    {
+        PRIVATE int ac3;    /* flags.ac3 is only set when the source audio format is HB_ACODEC_AC3 */
+        PRIVATE int dca;    /* flags.dca is only set when the source audio format is HB_ACODEC_DCA */
+    } flags;
+
+    struct
+    {
+        PRIVATE char description[1024];
+        PRIVATE char simple[1024];
+        PRIVATE char iso639_2[4];
+    } lang;
+};
 
 #ifdef __LIBHB__
-    /* Internal data */
-    hb_fifo_t * fifo_in;   /* AC3/MPEG/LPCM ES */
-    hb_fifo_t * fifo_raw;  /* Raw audio */
-    hb_fifo_t * fifo_sync; /* Resampled, synced raw audio */
-    hb_fifo_t * fifo_out;  /* MP3/AAC/Vorbis ES */
+struct hb_audio_s
+{
+    int id;
 
-    hb_esconfig_t config;
-    hb_mux_data_t * mux_data;
+    hb_audio_config_t config;
 
-       /* amixdown is the mixdown format to be used for this audio track */
-       int amixdown;
-#endif
+    struct {
+        hb_fifo_t * fifo_in;   /* AC3/MPEG/LPCM ES */
+        hb_fifo_t * fifo_raw;  /* Raw audio */
+        hb_fifo_t * fifo_sync; /* Resampled, synced raw audio */
+        hb_fifo_t * fifo_out;  /* MP3/AAC/Vorbis ES */
+
+        hb_esconfig_t config;
+        hb_mux_data_t * mux_data;
+    } priv;
 };
+#endif
 
 struct hb_chapter_s
 {
@@ -506,10 +516,8 @@ struct hb_work_object_s
     hb_fifo_t         * fifo_out;
     hb_esconfig_t     * config;
 
-       /* amixdown is the mixdown format to be used if the work object is an audio track */
-       int               amixdown;
-    /* source_acodec is the source audio codec if the work object is an audio track */
-    int               source_acodec;
+    /* Pointer hb_audio_t so we have access to the info in the audio worker threads. */
+    hb_audio_t *audio;
 
     hb_work_private_t * private_data;
 
index e38ce9c..421c973 100644 (file)
@@ -88,6 +88,7 @@ static sample_t dynrng_call (sample_t c, void *data)
 int deca52Init( hb_work_object_t * w, hb_job_t * job )
 {
     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+    hb_audio_t * audio = w->audio;
     w->private_data = pv;
 
     pv->job   = job;
@@ -98,14 +99,14 @@ int deca52Init( hb_work_object_t * w, hb_job_t * job )
        /* Decide what format we want out of a52dec
        work.c has already done some of this deduction for us in do_job() */
 
-       pv->flags_out = HB_AMIXDOWN_GET_A52_FORMAT(w->amixdown);
+       pv->flags_out = HB_AMIXDOWN_GET_A52_FORMAT(audio->config.out.mixdown);
 
        /* pass the number of channels used into the private work data */
        /* will only be actually used if we're not doing AC3 passthru */
-       pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
 
     pv->level     = 32768.0;
-    pv->dynamic_range_compression = job->dynamic_range_compression;
+    pv->dynamic_range_compression = audio->config.out.dynamic_range_compression;
 
     pv->next_expected_pts = 0;
     pv->sequence = 0;
@@ -168,6 +169,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
 {
     hb_work_private_t * pv = w->private_data;
     hb_buffer_t * buf;
+    hb_audio_t  * audio = w->audio;
     int           i, j, k;
     uint64_t      pts, pos;
 
@@ -219,8 +221,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
     }
 
     /* AC3 passthrough: don't decode the AC3 frame */
-    if( pv->job->acodec & HB_ACODEC_AC3 ||
-        w->amixdown == HB_AMIXDOWN_AC3 )
+    if( audio->config.out.codec == HB_ACODEC_AC3 )
     {
         buf = hb_buffer_init( pv->size );
         memcpy( buf->data, pv->frame, pv->size );
index d84a6ca..ec6dedd 100644 (file)
@@ -61,6 +61,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w );
 int decdcaInit( hb_work_object_t * w, hb_job_t * job )
 {
     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+    hb_audio_t * audio = w->audio;
     w->private_data = pv;
 
     pv->job   = job;
@@ -71,11 +72,11 @@ int decdcaInit( hb_work_object_t * w, hb_job_t * job )
        /* Decide what format we want out of libdca
        work.c has already done some of this deduction for us in do_job() */
 
-       pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT(w->amixdown);
+       pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT(audio->config.out.mixdown);
 
        /* pass the number of channels used into the private work data */
        /* will only be actually used if we're not doing AC3 passthru */
-       pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
 
     pv->level     = 32768.0;
 
index 1c4eb60..3c78e2c 100644 (file)
@@ -257,28 +257,28 @@ hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
         {
             case 0x00:
                 audio->id    = ( ( 0x80 + position ) << 8 ) | 0xbd;
-                audio->codec = HB_ACODEC_AC3;
+                audio->config.in.codec = HB_ACODEC_AC3;
                 break;
 
             case 0x02:
             case 0x03:
                 audio->id    = 0xc0 + position;
-                audio->codec = HB_ACODEC_MPGA;
+                audio->config.in.codec = HB_ACODEC_MPGA;
                 break;
 
             case 0x04:
                 audio->id    = ( ( 0xa0 + position ) << 8 ) | 0xbd;
-                audio->codec = HB_ACODEC_LPCM;
+                audio->config.in.codec = HB_ACODEC_LPCM;
                 break;
 
             case 0x06:
                 audio->id    = ( ( 0x88 + position ) << 8 ) | 0xbd;
-                audio->codec = HB_ACODEC_DCA;
+                audio->config.in.codec = HB_ACODEC_DCA;
                 break;
 
             default:
                 audio->id    = 0;
-                audio->codec = 0;
+                audio->config.in.codec = 0;
                 hb_log( "scan: unknown audio codec (%x)",
                         audio_format );
                 break;
@@ -308,19 +308,20 @@ hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
 
         lang = lang_for_code( vts->vtsi_mat->vts_audio_attr[i].lang_code );
 
-        snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)",
+        snprintf( audio->config.lang.description, sizeof( audio->config.lang.description ), "%s (%s)",
             strlen(lang->native_name) ? lang->native_name : lang->eng_name,
-            audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec ==
-                HB_ACODEC_DCA ? "DTS" : ( audio->codec ==
+            audio->config.in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->config.in.codec ==
+                HB_ACODEC_DCA ? "DTS" : ( audio->config.in.codec ==
                 HB_ACODEC_MPGA ? "MPEG" : "LPCM" ) ) );
-        snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s",
+        snprintf( audio->config.lang.simple, sizeof( audio->config.lang.simple ), "%s",
                   strlen(lang->native_name) ? lang->native_name : lang->eng_name );
-        snprintf( audio->iso639_2, sizeof( audio->iso639_2 ), "%s",
+        snprintf( audio->config.lang.iso639_2, sizeof( audio->config.lang.iso639_2 ), "%s",
                   lang->iso639_2);
 
         hb_log( "scan: id=%x, lang=%s, 3cc=%s", audio->id,
-                audio->lang, audio->iso639_2 );
+                audio->config.lang.description, audio->config.lang.iso639_2 );
 
+        audio->config.in.track = i;
         hb_list_add( title->list_audio, audio );
     }
 
index b54b799..7303a3f 100644 (file)
@@ -45,6 +45,7 @@ hb_work_object_t hb_encfaac =
 int encfaacInit( hb_work_object_t * w, hb_job_t * job )
 {
     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+    hb_audio_t * audio = w->audio;
     faacEncConfigurationPtr cfg;
     uint8_t * bytes;
     unsigned long length;
@@ -54,9 +55,9 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
     pv->job   = job;
 
        /* pass the number of channels used into the private work data */
-       pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
 
-    pv->faac = faacEncOpen( job->arate, pv->out_discrete_channels, &pv->input_samples,
+    pv->faac = faacEncOpen( audio->config.out.samplerate, pv->out_discrete_channels, &pv->input_samples,
                            &pv->output_bytes );
     pv->buf  = malloc( pv->input_samples * sizeof( float ) );
 
@@ -74,12 +75,12 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
        }
 
     cfg->useTns        = 0;
-    cfg->bitRate       = job->abitrate * 1000 / pv->out_discrete_channels; /* Per channel */
+    cfg->bitRate       = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; /* Per channel */
     cfg->bandWidth     = 0;
     cfg->outputFormat  = 0;
     cfg->inputFormat   =  FAAC_INPUT_FLOAT;
 
-       if (w->amixdown == HB_AMIXDOWN_6CH && w->source_acodec == HB_ACODEC_AC3)
+    if (audio->config.out.mixdown == HB_AMIXDOWN_6CH && audio->config.in.codec == HB_ACODEC_AC3)
     {
         /* we are preserving 5.1 AC-3 audio into 6-channel AAC, and need to
         re-map the output of deca52 into our own mapping - the mapping
@@ -140,6 +141,7 @@ void encfaacClose( hb_work_object_t * w )
 static hb_buffer_t * Encode( hb_work_object_t * w )
 {
     hb_work_private_t * pv = w->private_data;
+    hb_audio_t * audio = w->audio;
     hb_buffer_t * buf;
     uint64_t      pts, pos;
 
@@ -153,8 +155,8 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
                       &pts, &pos );
 
     buf        = hb_buffer_init( pv->output_bytes );
-    buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / pv->job->arate;
-    buf->stop  = buf->start + 90000 * pv->input_samples / pv->job->arate / pv->out_discrete_channels;
+    buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
+    buf->stop  = buf->start + 90000 * pv->input_samples / audio->config.out.samplerate / pv->out_discrete_channels;
     buf->size  = faacEncEncode( pv->faac, (int32_t *) pv->buf,
             pv->input_samples, buf->data, pv->output_bytes );
     buf->frametype   = HB_FRAME_AUDIO;
index 35b35ff..6b31a11 100644 (file)
@@ -39,6 +39,7 @@ struct hb_work_private_s
 int enclameInit( hb_work_object_t * w, hb_job_t * job )
 {
     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+    hb_audio_t * audio = w->audio;
     w->private_data = pv;
 
     pv->job   = job;
@@ -46,9 +47,9 @@ int enclameInit( hb_work_object_t * w, hb_job_t * job )
     hb_log( "enclame: opening libmp3lame" );
 
     pv->lame = lame_init();
-    lame_set_brate( pv->lame, job->abitrate );
-    lame_set_in_samplerate( pv->lame, job->arate );
-    lame_set_out_samplerate( pv->lame, job->arate );
+    lame_set_brate( pv->lame, audio->config.out.bitrate );
+    lame_set_in_samplerate( pv->lame, audio->config.out.samplerate );
+    lame_set_out_samplerate( pv->lame, audio->config.out.samplerate );
     lame_init_params( pv->lame );
 
     pv->input_samples = 1152 * 2;
@@ -85,6 +86,7 @@ void enclameClose( hb_work_object_t * w )
 static hb_buffer_t * Encode( hb_work_object_t * w )
 {
     hb_work_private_t * pv = w->private_data;
+    hb_audio_t * audio = w->audio;
     hb_buffer_t * buf;
     int16_t samples_s16[1152 * 2];
     uint64_t pts, pos;
@@ -104,8 +106,8 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
     }
 
     buf        = hb_buffer_init( pv->output_bytes );
-    buf->start = pts + 90000 * pos / 2 / sizeof( float ) / pv->job->arate;
-    buf->stop  = buf->start + 90000 * 1152 / pv->job->arate;
+    buf->start = pts + 90000 * pos / 2 / sizeof( float ) / audio->config.out.samplerate;
+    buf->stop  = buf->start + 90000 * 1152 / audio->config.out.samplerate;
     buf->size  = lame_encode_buffer_interleaved( pv->lame, samples_s16,
             1152, buf->data, LAME_MAXMP3BUFFER );
     buf->frametype   = HB_FRAME_AUDIO;
index b94366e..136096a 100644 (file)
@@ -44,13 +44,14 @@ struct hb_work_private_s
 
 int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
 {
+    hb_audio_t * audio = w->audio;
     int i;
     ogg_packet header[3];
     struct ovectl_ratemanage2_arg  ctl_rate_arg;
 
     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
     w->private_data = pv;
-    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+    pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
 
     pv->job   = job;
 
@@ -58,17 +59,18 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
 
     /* 28kbps/channel seems to be the minimum for 6ch vorbis. */
     int min_bitrate = 28 * pv->out_discrete_channels;
-    if (pv->out_discrete_channels > 2 && job->abitrate < min_bitrate)
+    if (pv->out_discrete_channels > 2 && audio->config.out.bitrate < min_bitrate)
     {
-        hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", job->abitrate, pv->out_discrete_channels);
+        hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", audio->config.out.bitrate, pv->out_discrete_channels);
         hb_log( "encvorbis: Resetting bitrate to %d kbps", min_bitrate);
-        job->abitrate = min_bitrate;
+        /* Naughty! We shouldn't modify the audio from here. */
+        audio->config.out.bitrate = min_bitrate;
     }
 
     /* init */
     vorbis_info_init( &pv->vi );
     if( vorbis_encode_setup_managed( &pv->vi, pv->out_discrete_channels,
-          job->arate, -1, 1000 * job->abitrate, -1 ) )
+          audio->config.out.samplerate, -1, 1000 * audio->config.out.bitrate, -1 ) )
     {
         hb_error( "encvorbis: vorbis_encode_setup_managed failed.\n" );
         *job->die = 1;
@@ -80,7 +82,7 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
         hb_log( "encvorbis: vorbis_encode_ctl( ratemanage2_get ) failed" );
     }
 
-    ctl_rate_arg.bitrate_average_kbps = job->abitrate;
+    ctl_rate_arg.bitrate_average_kbps = audio->config.out.bitrate;
     ctl_rate_arg.management_active = 1;
 
     if( vorbis_encode_ctl( &pv->vi, OV_ECTL_RATEMANAGE2_SET, &ctl_rate_arg ) ||
index fd3cd45..5f176f1 100644 (file)
@@ -453,7 +453,7 @@ int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, i
     cc_1 = 0; cc_2 = 0;
 
     int offset = 0;
-    
+
     for( k = 0; k < 3; k++ )
     {
         /* One pas for Y, one pass for Cb, one pass for Cr */
@@ -476,14 +476,14 @@ int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, i
                so it's width*height + (width / 2) * (height / 2)  */
             offset *= 5/4;
         }
-        
+
         /* Look at one horizontal line at a time */
         block = width;
-        
+
         for( j = 0; j < block; ++j )
         {
             off = 0;
-            
+
             for( n = 0; n < ( height - 4 ); n = n + 2 )
             {
                 /* Look at groups of 4 sequential horizontal lines */
@@ -491,29 +491,29 @@ int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, i
                 s2 = ( ( buf->data + offset )[ off + j + block     ] & 0xff );
                 s3 = ( ( buf->data + offset )[ off + j + 2 * block ] & 0xff );
                 s4 = ( ( buf->data + offset )[ off + j + 3 * block ] & 0xff );
-                
+
                 /* Note if the 1st and 2nd lines are more different in
                    color than the 1st and 3rd lines are similar in color.*/
-                if ( ( abs( s1 - s3 ) < color_equal ) && 
+                if ( ( abs( s1 - s3 ) < color_equal ) &&
                      ( abs( s1 - s2 ) > color_diff ) )
                         ++cc_1;
-    
+
                 /* Note if the 2nd and 3rd lines are more different in
                    color than the 2nd and 4th lines are similar in color.*/
                 if ( ( abs( s2 - s4 ) < color_equal ) &&
                      ( abs( s2 - s3 ) > color_diff) )
                         ++cc_2;
-                
+
                 /* Now move down 2 horizontal lines before starting over.*/
                 off += 2 * block;
             }
         }
-        
+
         // compare results
         /* The final metric seems to be doing some kind of bits per pixel style calculation
            to decide whether or not enough lines showed alternating colors for the frame size. */
         cc[k] = (int)( ( cc_1 + cc_2 ) * 1000.0 / ( width * height ) );
-        
+
         /* If the plane's cc score meets the threshold, flag it as combed. */
         flag[k] = 0;
         if ( cc[k] > threshold )
@@ -521,13 +521,13 @@ int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, i
             flag[k] = 1;
         }
     }
-    
+
 #if 0
 /* Debugging info */
 //    if(flag)
         hb_log("flags: %i/%i/%i | cc0: %i | cc1: %i | cc2: %i", flag[0], flag[1], flag[2], cc[0], cc[1], cc[2]);
 #endif
-    
+
     /* When more than one plane shows combing, tell the caller. */
     if (flag[0] || flag[1] || flag[2] )
     {
@@ -834,7 +834,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
     hb_job_t      * job_copy;
     hb_title_t    * title,    * title_copy;
     hb_chapter_t  * chapter,  * chapter_copy;
-    hb_audio_t    * audio,    * audio_copy;
+    hb_audio_t    * audio;
     hb_subtitle_t * subtitle, * subtitle_copy;
     int             i;
     char            audio_lang[4];
@@ -859,17 +859,11 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
     /* Do nothing about audio during first pass */
     if( job->pass == 0 || job->pass == 2 )
     {
-        for( i = 0; i < 8; i++ )
+        for( i = 0; i < hb_list_count(job->list_audio); i++ )
         {
-            if( job->audios[i] < 0 )
-            {
-                break;
-            }
-            if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
+            if( ( audio = hb_list_item( job->list_audio, i ) ) )
             {
-                audio_copy = malloc( sizeof( hb_audio_t ) );
-                memcpy( audio_copy, audio, sizeof( hb_audio_t ) );
-                hb_list_add( title_copy->list_audio, audio_copy );
+                hb_list_add( title_copy->list_audio, hb_audio_copy(audio) );
             }
         }
     }
@@ -900,15 +894,11 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
         /*
          * Find the first audio language that is being encoded
          */
-        for( i = 0; i < 8; i++ )
+        for( i = 0; i < hb_list_count(job->list_audio); i++ )
         {
-            if( job->audios[i] < 0 )
-            {
-                break;
-            }
-            if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
+            if( ( audio = hb_list_item( job->list_audio, i ) ) )
             {
-                strncpy(audio_lang, audio->iso639_2, sizeof(audio_lang));
+                strncpy(audio_lang, audio->config.lang.iso639_2, sizeof(audio_lang));
                 break;
             }
         }
@@ -1035,6 +1025,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
     memcpy( job_copy, job, sizeof( hb_job_t ) );
     title_copy->job = job_copy;
     job_copy->title = title_copy;
+    job_copy->list_audio = title_copy->list_audio;
     job_copy->file  = strdup( job->file );
     job_copy->h     = h;
     job_copy->pause = h->pause_lock;
index 0370c88..632f246 100644 (file)
@@ -281,7 +281,7 @@ static int AVIInit( hb_mux_object_t * m )
     hb_mux_data_t * mux_data;
 
     int audio_count = hb_list_count( title->list_audio );
-    int is_ac3      = ( job->acodec & HB_ACODEC_AC3 );
+    int is_ac3      = 0;
     int hdrl_bytes;
     int i;
 
@@ -346,8 +346,10 @@ static int AVIInit( hb_mux_object_t * m )
     {
         audio = hb_list_item( title->list_audio, i );
 
+        is_ac3 = (audio->config.out.codec == HB_ACODEC_AC3);
+
         mux_data = calloc( sizeof( hb_mux_data_t ), 1 );
-        audio->mux_data = mux_data;
+        audio->priv.mux_data = mux_data;
 
 #define h mux_data->header
 #define f mux_data->format.a.f
@@ -358,8 +360,8 @@ static int AVIInit( hb_mux_object_t * m )
         h.Type          = FOURCC( "auds" );
         h.InitialFrames = 1;
         h.Scale         = 1;
-        h.Rate          = is_ac3 ? ( audio->bitrate / 8 ) :
-                                   ( job->abitrate * 1000 / 8 );
+        h.Rate          = is_ac3 ? ( audio->config.in.bitrate / 8 ) :
+                                   ( audio->config.out.bitrate * 1000 / 8 );
         h.Quality       = 0xFFFFFFFF;
         h.SampleSize    = 1;
 
@@ -369,16 +371,16 @@ static int AVIInit( hb_mux_object_t * m )
         {
             f.BytesCount     = sizeof( hb_wave_formatex_t ) - 8;
             f.FormatTag      = 0x2000;
-            f.Channels       = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout);
-            f.SamplesPerSec  = audio->rate;
+            f.Channels       = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->config.in.channel_layout);
+            f.SamplesPerSec  = audio->config.in.samplerate;
         }
         else
         {
             f.BytesCount     = sizeof( hb_wave_formatex_t ) +
                                sizeof( hb_wave_mp3_t ) - 8;
             f.FormatTag      = 0x55;
-            f.Channels       = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(job->audio_mixdowns[i]);
-            f.SamplesPerSec  = job->arate;
+            f.Channels       = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
+            f.SamplesPerSec  = audio->config.out.samplerate;
         }
         f.AvgBytesPerSec = h.Rate;
         f.BlockAlign     = 1;
@@ -391,7 +393,7 @@ static int AVIInit( hb_mux_object_t * m )
             f.Size           = sizeof( hb_wave_mp3_t );
             m.Id             = 1;
             m.Flags          = 2;
-            m.BlockSize      = 1152 * f.AvgBytesPerSec / job->arate;
+            m.BlockSize      = 1152 * f.AvgBytesPerSec / audio->config.out.samplerate;
             m.FramesPerBlock = 1;
             m.CodecDelay     = 1393;
         }
@@ -439,7 +441,7 @@ static int AVIInit( hb_mux_object_t * m )
         char fourcc[4] = "00wb";
 
         audio    = hb_list_item( title->list_audio, i );
-        mux_data = audio->mux_data;
+        mux_data = audio->priv.mux_data;
 
         fourcc[1] = '1' + i; /* This is fine as we don't allow more
                                 than 8 tracks */
@@ -513,9 +515,9 @@ static int AVIMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
     {
         audio = hb_list_item( title->list_audio, i );
         fseek( m->file, 264 + i *
-               ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 :
+               ( 102 + ( ( audio->config.out.codec == HB_ACODEC_AC3 ) ? 0 :
                  sizeof( hb_wave_mp3_t ) ) ), SEEK_SET );
-        WriteInt32( m->file, audio->mux_data->header.Length );
+        WriteInt32( m->file, audio->priv.mux_data->header.Length );
     }
 
     /* movi size */
index d6a8270..c4f3a89 100644 (file)
@@ -98,7 +98,7 @@ static void MuxerFunc( void * _mux )
         for( i = 0; i < hb_list_count( title->list_audio ); i++ )
         {
             audio = hb_list_item( title->list_audio, i );
-            if( !hb_fifo_size( audio->fifo_out ) )
+            if( !hb_fifo_size( audio->priv.fifo_out ) )
             {
                 ready = 0;
                 break;
@@ -131,8 +131,8 @@ static void MuxerFunc( void * _mux )
     {
         audio           = hb_list_item( title->list_audio, i );
         track           = calloc( sizeof( hb_track_t ), 1 );
-        track->fifo     = audio->fifo_out;
-        track->mux_data = audio->mux_data;
+        track->fifo     = audio->priv.fifo_out;
+        track->mux_data = audio->priv.mux_data;
         hb_list_add( list, track );
     }
 
index 6ed6a6d..76fc48b 100644 (file)
@@ -29,6 +29,7 @@ struct hb_mux_data_s
     mk_Track  * track;
     uint64_t  prev_chapter_tc;
     uint16_t  current_chapter;
+    int       codec;
 };
 
 /**********************************************************************
@@ -158,9 +159,11 @@ static int MKVInit( hb_mux_object_t * m )
     {
         audio = hb_list_item( title->list_audio, i );
         mux_data = malloc( sizeof( hb_mux_data_t ) );
-        audio->mux_data = mux_data;
+        audio->priv.mux_data = mux_data;
 
-        switch (job->acodec)
+        mux_data->codec = audio->config.out.codec;
+
+        switch (audio->config.out.codec)
         {
             case HB_ACODEC_AC3:
                 track->codecPrivate = NULL;
@@ -180,8 +183,8 @@ static int MKVInit( hb_mux_object_t * m )
                     uint64_t  header_sizes[3];
                     for (i = 0; i < 3; ++i)
                     {
-                        ogg_headers[i] = (ogg_packet *)audio->config.vorbis.headers[i];
-                        ogg_headers[i]->packet = (unsigned char *)&audio->config.vorbis.headers[i] + sizeof( ogg_packet );
+                        ogg_headers[i] = (ogg_packet *)audio->priv.config.vorbis.headers[i];
+                        ogg_headers[i]->packet = (unsigned char *)&audio->priv.config.vorbis.headers[i] + sizeof( ogg_packet );
                         header_sizes[i] = ogg_headers[i]->bytes;
                     }
                     track->codecPrivate = mk_laceXiph(header_sizes, 2, &cp_size);
@@ -195,22 +198,13 @@ static int MKVInit( hb_mux_object_t * m )
                 }
                 break;
             case HB_ACODEC_FAAC:
-                if( job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
-                {
-                    track->codecPrivate = NULL;
-                    track->codecPrivateSize = 0;
-                    track->codecID = MK_ACODEC_AC3;
-                }
-                else
-                {
-                    track->codecPrivate = audio->config.aac.bytes;
-                    track->codecPrivateSize = audio->config.aac.length;
-                    track->codecID = MK_ACODEC_AAC;
-                }
+                track->codecPrivate = audio->priv.config.aac.bytes;
+                track->codecPrivateSize = audio->priv.config.aac.length;
+                track->codecID = MK_ACODEC_AAC;
                 break;
             default:
                 *job->die = 1;
-                hb_error("muxmkv: Unknown audio codec: %x", job->acodec);
+                hb_error("muxmkv: Unknown audio codec: %x", audio->config.out.codec);
                 return 0;
         }
 
@@ -221,12 +215,12 @@ static int MKVInit( hb_mux_object_t * m )
         }
         track->flagEnabled = 1;
         track->trackType = MK_TRACK_AUDIO;
-        track->language = audio->iso639_2;
-        track->extra.audio.samplingFreq = (float)job->arate;
-        track->extra.audio.channels = (job->acodec == HB_ACODEC_AC3 || job->audio_mixdowns[i] == HB_AMIXDOWN_AC3  ) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown);
+        track->language = audio->config.lang.iso639_2;
+        track->extra.audio.samplingFreq = (float)audio->config.out.samplerate;
+        track->extra.audio.channels = (audio->config.out.codec == HB_ACODEC_AC3 ) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->config.in.channel_layout) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
 //        track->defaultDuration = job->arate * 1000;
         mux_data->track = mk_createTrack(m->file, track);
-        if (job->acodec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)
+        if (audio->config.out.codec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)
           free(track->codecPrivate);
     }
 
@@ -308,7 +302,7 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
     {
         /* Audio */
         timecode = buf->start * TIMECODE_SCALE;
-        if (job->acodec == HB_ACODEC_VORBIS)
+        if (mux_data->codec == HB_ACODEC_VORBIS)
         {
             /* ughhh, vorbis is a pain :( */
             op = (ogg_packet *)buf->data;
index d4681c6..59c228f 100644 (file)
@@ -27,6 +27,11 @@ struct hb_mux_object_s
     MP4TrackId chapter_track;
     int current_chapter;
     uint64_t chapter_duration;
+
+    /* Sample rate of the first audio track.
+     * Used for the timescale
+     */
+    int samplerate;
 };
 
 struct hb_mux_data_s
@@ -137,6 +142,10 @@ static int MP4Init( hb_mux_object_t * m )
     /* Flags for enabling/disabling tracks in an MP4. */
     typedef enum { TRACK_DISABLED = 0x0, TRACK_ENABLED = 0x1, TRACK_IN_MOVIE = 0x2, TRACK_IN_PREVIEW = 0x4, TRACK_IN_POSTER = 0x8}  track_header_flags;
 
+    /* Need the sample rate of the first audio track to use as the timescale. */
+    audio = hb_list_item(title->list_audio, 0);
+    m->samplerate = audio->config.out.samplerate;
+    audio = NULL;
 
     /* Create an empty mp4 file */
     if (job->largeFileSize)
@@ -166,7 +175,7 @@ static int MP4Init( hb_mux_object_t * m )
        synchronization issues (audio not playing at the correct speed).
        To workaround this, we use the audio samplerate as the
        timescale */
-    if (!(MP4SetTimeScale( m->file, job->arate )))
+    if (!(MP4SetTimeScale( m->file, m->samplerate )))
     {
         hb_error("muxmp4.c: MP4SetTimeScale failed!");
         *job->die = 1;
@@ -183,7 +192,7 @@ static int MP4Init( hb_mux_object_t * m )
             return 0;
         }
 
-               mux_data->track = MP4AddH264VideoTrack( m->file, job->arate,
+               mux_data->track = MP4AddH264VideoTrack( m->file, m->samplerate,
                        MP4_INVALID_DURATION, job->width, job->height,
                        job->config.h264.sps[1], /* AVCProfileIndication */
                        job->config.h264.sps[2], /* profile_compat */
@@ -211,7 +220,7 @@ static int MP4Init( hb_mux_object_t * m )
             *job->die = 1;
             return 0;
         }
-        mux_data->track = MP4AddVideoTrack( m->file, job->arate,
+        mux_data->track = MP4AddVideoTrack( m->file, m->samplerate,
                 MP4_INVALID_DURATION, job->width, job->height,
                 MP4_MPEG4_VIDEO_TYPE );
         if (mux_data->track == MP4_INVALID_TRACK_ID)
@@ -261,14 +270,13 @@ static int MP4Init( hb_mux_object_t * m )
 
         audio = hb_list_item( title->list_audio, i );
         mux_data = malloc( sizeof( hb_mux_data_t ) );
-        audio->mux_data = mux_data;
+        audio->priv.mux_data = mux_data;
 
-        if( job->acodec & HB_ACODEC_AC3 ||
-            job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+        if( audio->config.out.codec == HB_ACODEC_AC3 )
         {
             mux_data->track = MP4AddAC3AudioTrack(
                 m->file,
-                job->arate, 1536, MP4_MPEG4_AUDIO_TYPE );
+                m->samplerate, 1536, MP4_MPEG4_AUDIO_TYPE );
             MP4SetTrackBytesProperty(
                 m->file, mux_data->track,
                 "udta.name.value",
@@ -276,7 +284,7 @@ static int MP4Init( hb_mux_object_t * m )
         } else {
             mux_data->track = MP4AddAudioTrack(
                 m->file,
-                job->arate, 1024, MP4_MPEG4_AUDIO_TYPE );
+                m->samplerate, 1024, MP4_MPEG4_AUDIO_TYPE );
             MP4SetTrackBytesProperty(
                 m->file, mux_data->track,
                 "udta.name.value",
@@ -285,18 +293,18 @@ static int MP4Init( hb_mux_object_t * m )
             MP4SetAudioProfileLevel( m->file, 0x0F );
             MP4SetTrackESConfiguration(
                 m->file, mux_data->track,
-                audio->config.aac.bytes, audio->config.aac.length );
+                audio->priv.config.aac.bytes, audio->priv.config.aac.length );
 
             /* Set the correct number of channels for this track */
-            reserved2[9] = (u_int8_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown);
+            reserved2[9] = (u_int8_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
             MP4SetTrackBytesProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.mp4a.reserved2", reserved2, sizeof(reserved2));
 
         }
         /* Set the language for this track */
         /* The language is stored as 5-bit text - 0x60 */
-        language_code = audio->iso639_2[0] - 0x60;   language_code <<= 5;
-        language_code |= audio->iso639_2[1] - 0x60;  language_code <<= 5;
-        language_code |= audio->iso639_2[2] - 0x60;
+        language_code = audio->config.lang.iso639_2[0] - 0x60;   language_code <<= 5;
+        language_code |= audio->config.lang.iso639_2[1] - 0x60;  language_code <<= 5;
+        language_code |= audio->config.lang.iso639_2[2] - 0x60;
         MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.mdhd.language", language_code);
 
 
@@ -372,7 +380,7 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
 
             if ( job->areBframes )
             {
-                duration += buf->renderOffset * job->arate / 90000;
+                duration += buf->renderOffset * m->samplerate / 90000;
             }
 
             sample = MP4GenerateChapterSample( m, duration );
@@ -396,8 +404,8 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
         /* Because we use the audio samplerate as the timescale,
            we have to use potentially variable durations so the video
            doesn't go out of sync */
-        int64_t bias = ( buf->start * job->arate / 90000 ) - m->sum_dur;
-        duration = ( buf->stop - buf->start ) * job->arate / 90000 + bias;
+        int64_t bias = ( buf->start * m->samplerate / 90000 ) - m->sum_dur;
+        duration = ( buf->stop - buf->start ) * m->samplerate / 90000 + bias;
         if ( duration <= 0 )
         {
             /* We got an illegal mp4/h264 duration. This shouldn't
@@ -406,14 +414,14 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
                try to fix the error so that the file will still be playable. */
             hb_log("MP4Mux: illegal duration %lld, bias %lld, start %lld (%lld),"
                    "stop %lld (%lld), sum_dur %lld",
-                   duration, bias, buf->start * job->arate / 90000, buf->start,
-                   buf->stop * job->arate / 90000, buf->stop, m->sum_dur );
+                   duration, bias, buf->start * m->samplerate / 90000, buf->start,
+                   buf->stop * m->samplerate / 90000, buf->stop, m->sum_dur );
             /* we don't know when the next frame starts so we can't pick a
                valid duration for this one so we pick something "short"
                (roughly 1/3 of an NTSC frame time) and rely on the bias calc
                for the next frame to correct things (a duration underestimate
                just results in a large bias on the next frame). */
-            duration = 1000 * job->arate / 90000;
+            duration = 1000 * m->samplerate / 90000;
         }
         m->sum_dur += duration;
     }
@@ -436,7 +444,7 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
                          duration,
                          ((mux_data->track != 1) ||
                           (job->areBframes==0) ||
-                          (job->vcodec != HB_VCODEC_X264)) ? 0 : (  buf->renderOffset * job->arate / 90000),
+                          (job->vcodec != HB_VCODEC_X264)) ? 0 : (  buf->renderOffset * m->samplerate / 90000),
                          ((buf->frametype & HB_FRAME_KEY) != 0) ) )
     {
         hb_error("Failed to write to output file, disk full?");
index 4331224..a7b72d5 100644 (file)
@@ -135,9 +135,9 @@ static int OGMInit( hb_mux_object_t * m )
     {
         audio                 = hb_list_item( title->list_audio, i );
         mux_data              = malloc( sizeof( hb_mux_data_t ) );
-        mux_data->codec       = job->acodec;
+        mux_data->codec       = audio->config.out.codec;
         mux_data->i_packet_no = 0;
-        audio->mux_data       = mux_data;
+        audio->priv.mux_data       = mux_data;
         ogg_stream_init( &mux_data->os, i + 1 );
     }
 
@@ -200,9 +200,9 @@ static int OGMInit( hb_mux_object_t * m )
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio   = hb_list_item( title->list_audio, i );
-        mux_data = audio->mux_data;
+        mux_data = audio->priv.mux_data;
         memset( &h, 0, sizeof( ogg_stream_header_t ) );
-        switch( job->acodec )
+        switch( audio->config.out.codec )
         {
             case HB_ACODEC_LAME:
             {
@@ -212,7 +212,7 @@ static int OGMInit( hb_mux_object_t * m )
 
                 SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
                 SetQWLE( &h.i_time_unit, 0 );
-                SetQWLE( &h.i_samples_per_unit, job->arate );
+                SetQWLE( &h.i_samples_per_unit, audio->config.out.samplerate );
                 SetDWLE( &h.i_default_len, 1 );
                 SetDWLE( &h.i_buffer_size, 30 * 1024 );
                 SetWLE ( &h.i_bits_per_sample, 0 );
@@ -220,7 +220,7 @@ static int OGMInit( hb_mux_object_t * m )
                 SetDWLE( &h.header.audio.i_channels, 2 );
                 SetDWLE( &h.header.audio.i_block_align, 0 );
                 SetDWLE( &h.header.audio.i_avgbytespersec,
-                         job->abitrate / 8 );
+                         audio->config.out.bitrate / 8 );
 
                 op.packet   = (unsigned char*) &h;
                 op.bytes    = sizeof( ogg_stream_header_t );
@@ -233,9 +233,9 @@ static int OGMInit( hb_mux_object_t * m )
             }
             case HB_ACODEC_VORBIS:
             {
-                memcpy( &op, audio->config.vorbis.headers[0],
+                memcpy( &op, audio->priv.config.vorbis.headers[0],
                         sizeof( ogg_packet ) );
-                op.packet = audio->config.vorbis.headers[0] +
+                op.packet = audio->priv.config.vorbis.headers[0] +
                                 sizeof( ogg_packet );
                 ogg_stream_packetin( &mux_data->os, &op );
                 break;
@@ -275,16 +275,16 @@ static int OGMInit( hb_mux_object_t * m )
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
-        if( job->acodec == HB_ACODEC_VORBIS )
+        if( audio->config.out.codec == HB_ACODEC_VORBIS )
         {
             int       j;
-            mux_data = audio->mux_data;
+            mux_data = audio->priv.mux_data;
 
             for( j = 1; j < 3; j++ )
             {
-                memcpy( &op, audio->config.vorbis.headers[j],
+                memcpy( &op, audio->priv.config.vorbis.headers[j],
                         sizeof( ogg_packet ) );
-                op.packet = audio->config.vorbis.headers[j] +
+                op.packet = audio->priv.config.vorbis.headers[j] +
                                 sizeof( ogg_packet );
                 ogg_stream_packetin( &mux_data->os, &op );
 
@@ -387,7 +387,7 @@ static int OGMEnd( hb_mux_object_t * m )
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
-        mux_data = audio->mux_data;
+        mux_data = audio->priv.mux_data;
         if( OGMFlush( m, mux_data ) < 0 )
         {
             return -1;
index db1c7af..823dfbe 100644 (file)
@@ -358,7 +358,7 @@ static hb_fifo_t ** GetFifoForId( hb_job_t * job, int id )
             audio = hb_list_item( title->list_audio, i );
             if( id == audio->id )
             {
-                fifos[n++] = audio->fifo_in;
+                fifos[n++] = audio->priv.fifo_in;
             }
         }
 
index 4aee25b..6c97920 100644 (file)
@@ -147,8 +147,8 @@ static void ScanFunc( void * _data )
                        for( j = 0; j < hb_list_count( title->list_audio ); )
                        {
                                audio = hb_list_item( title->list_audio, j );
-                               if( audio->codec == HB_ACODEC_AC3 &&
-                                       !audio->bitrate )
+                               if( audio->config.in.codec == HB_ACODEC_AC3 &&
+                    !audio->config.in.bitrate )
                                {
                                        hb_list_rem( title->list_audio, audio );
                                        free( audio );
@@ -162,11 +162,11 @@ static void ScanFunc( void * _data )
         for( j = 0; j < hb_list_count( title->list_audio ); )
         {
             audio = hb_list_item( title->list_audio, j );
-            if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
-                !audio->bitrate )
+            if( ( audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA ) &&
+                !audio->config.in.bitrate )
             {
                 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
-                    audio->codec );
+                        audio->config.in.codec );
                 hb_list_rem( title->list_audio, audio );
                 free( audio );
                 continue;
@@ -188,9 +188,9 @@ static void ScanFunc( void * _data )
         for( j = 0; j < hb_list_count( title->list_audio ); j++ )
         {
             audio = hb_list_item( title->list_audio, j );
-            if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )
+            if( audio->config.in.codec == HB_ACODEC_LPCM || audio->config.in.codec == HB_ACODEC_MPGA )
             {
-                audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
             }
         }
 
@@ -247,12 +247,7 @@ static void ScanFunc( void * _data )
         job->vrate      = title->rate;
         job->vrate_base = title->rate_base;
 
-        job->audios[0] = 0;
-        job->audios[1] = -1;
-
-        job->acodec   = HB_ACODEC_FAAC;
-        job->abitrate = 128;
-        job->arate    = 44100;
+        job->list_audio = hb_list_init();
 
         job->subtitle = -1;
 
@@ -451,14 +446,14 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
         }
 
         buf_raw = hb_list_item( list_raw, 0 );
-        
+
         /* Check preview for interlacing artifacts */
         if( hb_detect_comb( buf_raw, title->width, title->height, 10, 30, 9 ) )
         {
             hb_log("Interlacing detected in preview frame %i", i);
             interlaced_preview_count++;
         }
-        
+
         hb_get_tempory_filename( data->h, filename, "%x%d",
                                  (intptr_t)title, i );
 
@@ -584,7 +579,7 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
     {
         audio = hb_list_item( title->list_audio, i );
         /* check if we have an AC3 or DCA which we recognise */
-        if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
+        if( ( audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA ) &&
             audio->id    == b->id )
         {
             break;
@@ -599,7 +594,7 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
         return;
     }
 
-    if( audio->bitrate )
+    if( audio->config.in.bitrate )
     {
         /* Already done for this track */
         return;
@@ -608,78 +603,77 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
     for( i = 0; i < b->size - 7; i++ )
     {
 
-        if ( audio->codec == HB_ACODEC_AC3 )
+        if ( audio->config.in.codec == HB_ACODEC_AC3 )
         {
 
             /* check for a52 */
             if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
             {
                 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
-                audio->rate    = rate;
-                audio->bitrate = bitrate;
+                audio->config.in.samplerate = rate;
+                audio->config.in.bitrate = bitrate;
                 switch( flags & A52_CHANNEL_MASK )
                 {
                     /* mono sources */
                     case A52_MONO:
                     case A52_CHANNEL1:
                     case A52_CHANNEL2:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_MONO;
                         break;
                     /* stereo input */
                     case A52_CHANNEL:
                     case A52_STEREO:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
                         break;
                     /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
                     case A52_DOLBY:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
                         break;
                     /* 3F/2R input */
                     case A52_3F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
                         break;
                     /* 3F/1R input */
                     case A52_3F1R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
                         break;
                     /* other inputs */
                     case A52_3F:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
                         break;
                     case A52_2F1R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
                         break;
                     case A52_2F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
                         break;
                     /* unknown */
                     default:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
                 }
 
                 /* add in our own LFE flag if the source has LFE */
                 if (flags & A52_LFE)
                 {
-                    audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
+                    audio->config.in.channel_layout = audio->config.in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
                 }
 
                 /* store the AC3 flags for future reference
-                This enables us to find out if we had a stereo or Dolby source later on */
-                audio->config.a52.ac3flags = flags;
-
-                /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
-                audio->ac3flags = audio->config.a52.ac3flags;
+                 * This enables us to find out if we had a stereo or Dolby source later on
+                 * Store the ac3 flags in the public ac3flags property too, so we can access it from the GUI
+                 */
+                audio->config.flags.ac3 = audio->priv.config.a52.ac3flags = flags;
 
                 /* XXX */
                 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->config.lang.description + strlen( audio->config.lang.description ),
                          " (Dolby Surround)" );
                 } else {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->config.lang.description + strlen( audio->config.lang.description ),
                          " (%d.%d ch)",
-                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
-                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
-                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->config.in.channel_layout) +
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->config.in.channel_layout),
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->config.in.channel_layout));
                 }
 
                 break;
@@ -687,7 +681,7 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
             }
 
         }
-        else if ( audio->codec == HB_ACODEC_DCA )
+        else if ( audio->config.in.codec == HB_ACODEC_DCA )
         {
 
             hb_log( "scan: checking for DCA syncinfo" );
@@ -697,70 +691,69 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
             if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
             {
                 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
-                audio->rate    = rate;
-                audio->bitrate = bitrate;
+                audio->config.in.samplerate    = rate;
+                audio->config.in.bitrate = bitrate;
                 switch( flags & DCA_CHANNEL_MASK )
                 {
                     /* mono sources */
                     case DCA_MONO:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_MONO;
                         break;
                     /* stereo input */
                     case DCA_CHANNEL:
                     case DCA_STEREO:
                     case DCA_STEREO_SUMDIFF:
                     case DCA_STEREO_TOTAL:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
                         break;
                     /* 3F/2R input */
                     case DCA_3F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
                         break;
                     /* 3F/1R input */
                     case DCA_3F1R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
                         break;
                     /* other inputs */
                     case DCA_3F:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
                         break;
                     case DCA_2F1R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
                         break;
                     case DCA_2F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
                         break;
                     case DCA_4F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
                         break;
                     /* unknown */
                     default:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                        audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
                 }
 
                 /* add in our own LFE flag if the source has LFE */
                 if (flags & DCA_LFE)
                 {
-                    audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
+                    audio->config.in.channel_layout = audio->config.in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
                 }
 
                 /* store the DCA flags for future reference
-                This enables us to find out if we had a stereo or Dolby source later on */
-                audio->config.dca.dcaflags = flags;
-
-                /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
-                audio->dcaflags = audio->config.dca.dcaflags;
+                 * This enables us to find out if we had a stereo or Dolby source later on
+                 * store the dca flags in the public dcaflags property too, so we can access it from the GUI
+                 */
+                audio->config.flags.dca = audio->priv.config.dca.dcaflags = flags;
 
                 /* XXX */
                 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->config.lang.description + strlen( audio->config.lang.description ),
                          " (Dolby Surround)" );
                 } else {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->config.lang.description + strlen( audio->config.lang.description ),
                          " (%d.%d ch)",
-                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
-                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
-                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->config.in.channel_layout) +
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->config.in.channel_layout),
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->config.in.channel_layout));
                 }
 
                 break;
@@ -778,8 +771,8 @@ static int  AllAC3AndDCAOK( hb_title_t * title )
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
-        if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
-            !audio->bitrate )
+        if( ( audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA ) &&
+            !audio->config.in.bitrate )
         {
             return 0;
         }
index e376c69..fe2c962 100755 (executable)
@@ -340,7 +340,7 @@ void hb_stream_close( hb_stream_t ** _d )
     if ( stream->frames )
     {
         hb_log( "stream: %d good frames, %d errors (%.0f%%)", stream->frames,
-                stream->errors, (double)stream->errors * 100. / 
+                stream->errors, (double)stream->errors * 100. /
                 (double)stream->frames );
     }
     /*
@@ -444,7 +444,7 @@ hb_title_t * hb_stream_title_scan(hb_stream_t *stream)
         for (i=0; i < stream->ts_number_audio_pids; i++)
         {
             hb_audio_t *audio = hb_ts_stream_set_audio_id_and_codec(stream, i);
-            if (audio->codec)
+            if (audio->config.in.codec)
                 hb_list_add( aTitle->list_audio, audio );
             else
             {
@@ -773,7 +773,7 @@ static hb_audio_t *hb_ts_stream_set_audio_id_and_codec(hb_stream_t *stream,
         if (buf[3] == 0xbd)
         {
             audio->id = 0x80bd | (aud_pid_index << 8);
-            audio->codec = HB_ACODEC_AC3;
+            audio->config.in.codec = HB_ACODEC_AC3;
             hb_log("transport stream pid 0x%x (type 0x%x) is AC-3 audio id 0x%x",
                    stream->ts_audio_pids[aud_pid_index],
                    stream->ts_audio_stream_type[1 + aud_pid_index],
@@ -784,7 +784,7 @@ static hb_audio_t *hb_ts_stream_set_audio_id_and_codec(hb_stream_t *stream,
         else if ((buf[3] & 0xe0) == 0xc0)
         {
             audio->id = buf[3] | aud_pid_index;
-            audio->codec = HB_ACODEC_MPGA;
+            audio->config.in.codec = HB_ACODEC_MPGA;
             hb_log("transport stream pid 0x%x (type 0x%x) is MPEG audio id 0x%x",
                    stream->ts_audio_pids[aud_pid_index],
                    stream->ts_audio_stream_type[1 + aud_pid_index],
@@ -794,7 +794,7 @@ static hb_audio_t *hb_ts_stream_set_audio_id_and_codec(hb_stream_t *stream,
         }
     }
     fseeko(stream->file_handle, cur_pos, SEEK_SET);
-    if (! audio->codec)
+    if (! audio->config.in.codec)
     {
         hb_log("transport stream pid 0x%x (type 0x%x) isn't audio",
                 stream->ts_audio_pids[aud_pid_index],
@@ -811,7 +811,7 @@ static void add_audio_to_title(hb_title_t *title, int id)
     switch ( id >> 12 )
     {
         case 0x0:
-            audio->codec = HB_ACODEC_MPGA;
+            audio->config.in.codec = HB_ACODEC_MPGA;
             hb_log("add_audio_to_title: added MPEG audio stream 0x%x", id);
             break;
         case 0x2:
@@ -819,11 +819,11 @@ static void add_audio_to_title(hb_title_t *title, int id)
             free( audio );
             return;
         case 0x8:
-            audio->codec = HB_ACODEC_AC3;
+            audio->config.in.codec = HB_ACODEC_AC3;
             hb_log("add_audio_to_title: added AC3 audio stream 0x%x", id);
             break;
         case 0xa:
-            audio->codec = HB_ACODEC_LPCM;
+            audio->config.in.codec = HB_ACODEC_LPCM;
             hb_log("add_audio_to_title: added LPCM audio stream 0x%x", id);
             break;
         default:
@@ -913,12 +913,12 @@ void hb_stream_update_audio(hb_stream_t *stream, hb_audio_t *audio)
         }
 
                lang = lang_for_code(stream->a52_info[i].lang_code);
-               if (!audio->rate)
-                       audio->rate = stream->a52_info[i].rate;
-               if (!audio->bitrate)
-                       audio->bitrate = stream->a52_info[i].bitrate;
-               if (!audio->config.a52.ac3flags)
-                       audio->config.a52.ac3flags = audio->ac3flags = stream->a52_info[i].flags;
+        if (!audio->config.in.samplerate)
+            audio->config.in.samplerate = stream->a52_info[i].rate;
+        if (!audio->config.in.bitrate)
+            audio->config.in.bitrate = stream->a52_info[i].bitrate;
+        if (!audio->priv.config.a52.ac3flags)
+            audio->priv.config.a52.ac3flags = audio->config.flags.ac3 = stream->a52_info[i].flags;
 
        }
     else
@@ -927,74 +927,74 @@ void hb_stream_update_audio(hb_stream_t *stream, hb_audio_t *audio)
         lang = lang_for_code(0x0000);
     }
 
-       if (!audio->input_channel_layout)
+       if (!audio->config.in.channel_layout)
        {
-               switch( audio->ac3flags & A52_CHANNEL_MASK )
+               switch( audio->config.flags.ac3 & A52_CHANNEL_MASK )
                {
                        /* mono sources */
                        case A52_MONO:
                        case A52_CHANNEL1:
                        case A52_CHANNEL2:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_MONO;
                                break;
                        /* stereo input */
                        case A52_CHANNEL:
                        case A52_STEREO:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
                                break;
                        /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
                        case A52_DOLBY:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
                                break;
                        /* 3F/2R input */
                        case A52_3F2R:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
                                break;
                        /* 3F/1R input */
                        case A52_3F1R:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
                                break;
                        /* other inputs */
                        case A52_3F:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
                                break;
                        case A52_2F1R:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
                                break;
                        case A52_2F2R:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
                                break;
                        /* unknown */
                        default:
-                               audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                               audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
                }
 
                /* add in our own LFE flag if the source has LFE */
-               if (audio->ac3flags & A52_LFE)
+               if (audio->config.flags.ac3 & A52_LFE)
                {
-                       audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
+                       audio->config.in.channel_layout = audio->config.in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
                }
        }
 
-       snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,
-         audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->codec == HB_ACODEC_DCA ? "DTS" : "LPCM" ) ) );
-       snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );
-       snprintf( audio->iso639_2, sizeof( audio->iso639_2 ), "%s", lang->iso639_2);
+    snprintf( audio->config.lang.description, sizeof( audio->config.lang.description ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,
+         audio->config.in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->config.in.codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->config.in.codec == HB_ACODEC_DCA ? "DTS" : "LPCM" ) ) );
+       snprintf( audio->config.lang.simple, sizeof( audio->config.lang.simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );
+       snprintf( audio->config.lang.iso639_2, sizeof( audio->config.lang.iso639_2 ), "%s", lang->iso639_2);
 
-       if ( (audio->ac3flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
-               sprintf( audio->lang + strlen( audio->lang ),
+       if ( (audio->config.flags.ac3 & A52_CHANNEL_MASK) == A52_DOLBY ) {
+        sprintf( audio->config.lang.description + strlen( audio->config.lang.description ),
                         " (Dolby Surround)" );
        } else {
-               sprintf( audio->lang + strlen( audio->lang ),
+        sprintf( audio->config.lang.description + strlen( audio->config.lang.description ),
                         " (%d.%d ch)",
-                       HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
-                       HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
-                       HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
+                       HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->config.in.channel_layout) +
+                       HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->config.in.channel_layout),
+                       HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->config.in.channel_layout));
        }
 
        hb_log( "stream: audio %x: lang %s, rate %d, bitrate %d, "
-            "flags = 0x%x", audio->id, audio->lang, audio->rate,
-            audio->bitrate, audio->ac3flags );
+            "flags = 0x%x", audio->id, audio->config.lang.description, audio->config.in.samplerate,
+            audio->config.in.bitrate, audio->config.flags.ac3 );
 
 }
 
@@ -1879,7 +1879,7 @@ static int hb_ts_stream_decode( hb_stream_t *stream, uint8_t *obuf )
             // remember the pcr across calls to this routine
             stream->ts_lastpcr = pcr;
         }
-               
+
                if ( pcr == -1 )
                {
             // don't accumulate data until we get a pcr
@@ -1903,7 +1903,7 @@ static int hb_ts_stream_decode( hb_stream_t *stream, uint8_t *obuf )
                 // so ignore the rest.
                 continue;
             }
-            if ( !start && (stream->ts_streamcont[curstream] != -1) && 
+            if ( !start && (stream->ts_streamcont[curstream] != -1) &&
                  (continuity != ( (stream->ts_streamcont[curstream] + 1) & 0xf ) ) )
                        {
                                ts_err( stream, curstream,  "continuity error: got %d expected %d",
@@ -1933,7 +1933,7 @@ static int hb_ts_stream_decode( hb_stream_t *stream, uint8_t *obuf )
                                stream->ts_skipbad[curstream] = 0;
                        }
 
-                       // If we don't have video yet, check to see if this is an 
+                       // If we don't have video yet, check to see if this is an
             // i_frame (group of picture start)
                        if ( curstream == 0 )
             {
index 2a4818a..5b4891b 100644 (file)
@@ -130,6 +130,7 @@ void syncClose( hb_work_object_t * w )
     hb_work_private_t * pv = w->private_data;
     hb_job_t          * job   = pv->job;
     hb_title_t        * title = job->title;
+    hb_audio_t        * audio = NULL;
 
     int i;
 
@@ -144,8 +145,8 @@ void syncClose( hb_work_object_t * w )
                               pv->sync_audio[i].start_silence) / 90), i );
         }
 
-        if( job->acodec & HB_ACODEC_AC3 ||
-            job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+        audio = hb_list_item( title->list_audio, i );
+        if( audio->config.out.codec == HB_ACODEC_AC3 )
         {
             free( pv->sync_audio[i].ac3_buf );
         }
@@ -207,8 +208,7 @@ static void InitAudio( hb_work_object_t * w, int i )
     sync        = &pv->sync_audio[i];
     sync->audio = hb_list_item( title->list_audio, i );
 
-    if( job->acodec & HB_ACODEC_AC3 ||
-        job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+    if( sync->audio->config.out.codec == HB_ACODEC_AC3 )
     {
         /* Have a silent AC-3 frame ready in case we have to fill a
            gap */
@@ -219,9 +219,9 @@ static void InitAudio( hb_work_object_t * w, int i )
         codec = avcodec_find_encoder( CODEC_ID_AC3 );
         c     = avcodec_alloc_context();
 
-        c->bit_rate    = sync->audio->bitrate;
-        c->sample_rate = sync->audio->rate;
-        c->channels    = 2;
+        c->bit_rate    = sync->audio->config.in.bitrate;
+        c->sample_rate = sync->audio->config.in.samplerate;
+        c->channels    = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( sync->audio->config.in.channel_layout );
 
         if( avcodec_open( c, codec ) < 0 )
         {
@@ -231,8 +231,8 @@ static void InitAudio( hb_work_object_t * w, int i )
 
         zeros          = calloc( AC3_SAMPLES_PER_FRAME *
                                  sizeof( short ) * c->channels, 1 );
-        sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
-                             sync->audio->rate / 8;
+        sync->ac3_size = sync->audio->config.in.bitrate * AC3_SAMPLES_PER_FRAME /
+                             sync->audio->config.in.samplerate / 8;
         sync->ac3_buf  = malloc( sync->ac3_size );
 
         if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
@@ -249,7 +249,7 @@ static void InitAudio( hb_work_object_t * w, int i )
     {
         /* Initialize libsamplerate */
         int error;
-        sync->state             = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown), &error );
+        sync->state             = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->config.out.mixdown), &error );
         sync->data.end_of_input = 0;
     }
 }
@@ -432,9 +432,9 @@ static int SyncVideo( hb_work_object_t * w )
                              * Subtitle is on for less than three seconds, extend
                              * the time that it is displayed to make it easier
                              * to read. Make it 3 seconds or until the next
-                             * subtitle is displayed. 
+                             * subtitle is displayed.
                              *
-                             * This is in response to Indochine which only 
+                             * This is in response to Indochine which only
                              * displays subs for 1 second - too fast to read.
                              */
                             sub->stop = sub->start + ( 3 * 90000 );
@@ -558,22 +558,22 @@ static void OutputAudioFrame( hb_job_t *job, hb_audio_t *audio, hb_buffer_t *buf
 {
     int64_t start = sync->next_start;
     int64_t duration = buf->stop - buf->start;
-    if (duration <= 0 || 
-        duration > ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->rate )
+    if (duration <= 0 ||
+        duration > ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->config.out.samplerate )
     {
         hb_log("sync: audio %d weird duration %lld, start %lld, stop %lld, next %lld",
                i, duration, buf->start, buf->stop, sync->next_pts);
         if ( duration <= 0 )
         {
-            duration = ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->rate;
+            duration = ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->config.out.samplerate;
             buf->stop = buf->start + duration;
         }
     }
     sync->next_pts += duration;
 
     if( /* audio->rate == job->arate || This should work but doesn't */
-        job->acodec & HB_ACODEC_AC3 ||
-        job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+        audio->config.out.codec == HB_ACODEC_AC3 ||
+        audio->config.out.codec == HB_ACODEC_DCA )
     {
         /*
          * If we don't have to do sample rate conversion or this audio is AC3
@@ -586,11 +586,11 @@ static void OutputAudioFrame( hb_job_t *job, hb_audio_t *audio, hb_buffer_t *buf
         /* Not pass-thru - do sample rate conversion */
         int count_in, count_out;
         hb_buffer_t * buf_raw = buf;
-        int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) *
+        int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown) *
                             sizeof( float );
 
         count_in  = buf_raw->size / channel_count;
-        count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
+        count_out = ( buf_raw->stop - buf_raw->start ) * audio->config.out.samplerate / 90000;
 
         sync->data.input_frames = count_in;
         sync->data.output_frames = count_out;
@@ -630,19 +630,18 @@ static void SyncAudio( hb_work_object_t * w, int i )
     hb_fifo_t       * fifo;
     int               rate;
 
-    if( job->acodec & HB_ACODEC_AC3 ||
-        job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+    if( audio->config.out.codec == HB_ACODEC_AC3 )
     {
-        fifo = audio->fifo_out;
-        rate = audio->rate;
+        fifo = audio->priv.fifo_out;
+        rate = audio->config.in.samplerate;
     }
     else
     {
-        fifo = audio->fifo_sync;
-        rate = job->arate;
+        fifo = audio->priv.fifo_sync;
+        rate = audio->config.out.samplerate;
     }
 
-    while( !hb_fifo_is_full( fifo ) && ( buf = hb_fifo_see( audio->fifo_raw ) ) )
+    while( !hb_fifo_is_full( fifo ) && ( buf = hb_fifo_see( audio->priv.fifo_raw ) ) )
     {
         if ( sync->next_pts - buf->start > 500 )
         {
@@ -656,7 +655,7 @@ static void SyncAudio( hb_work_object_t * w, int i )
                 sync->first_drop = buf->start;
             }
             ++sync->drop_count;
-            buf = hb_fifo_get( audio->fifo_raw );
+            buf = hb_fifo_get( audio->priv.fifo_raw );
             hb_buffer_close( &buf );
             continue;
         }
@@ -711,13 +710,13 @@ static void SyncAudio( hb_work_object_t * w, int i )
          * audio stream and are ready to inject the next input frame into
          * the output stream.
          */
-        buf = hb_fifo_get( audio->fifo_raw );
+        buf = hb_fifo_get( audio->priv.fifo_raw );
         OutputAudioFrame( job, audio, buf, sync, fifo, i );
     }
 
     if( NeedSilence( w, audio, i ) )
     {
-        InsertSilence( w, i, (90000 * AC3_SAMPLES_PER_FRAME) / sync->audio->rate );
+        InsertSilence( w, i, (90000 * AC3_SAMPLES_PER_FRAME) / sync->audio->config.out.samplerate );
     }
 }
 
@@ -727,10 +726,10 @@ static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio, int i )
     hb_job_t * job = pv->job;
     hb_sync_audio_t * sync = &pv->sync_audio[i];
 
-    if( hb_fifo_size( audio->fifo_in ) ||
-        hb_fifo_size( audio->fifo_raw ) ||
-        hb_fifo_size( audio->fifo_sync ) ||
-        hb_fifo_size( audio->fifo_out ) )
+    if( hb_fifo_size( audio->priv.fifo_in ) ||
+        hb_fifo_size( audio->priv.fifo_raw ) ||
+        hb_fifo_size( audio->priv.fifo_sync ) ||
+        hb_fifo_size( audio->priv.fifo_out ) )
     {
         /* We have some audio, we are fine */
         return 0;
@@ -759,22 +758,22 @@ static void InsertSilence( hb_work_object_t * w, int i, int64_t duration )
     hb_sync_audio_t *sync = &pv->sync_audio[i];
     hb_buffer_t     *buf;
 
-    if( job->acodec & HB_ACODEC_AC3 || job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+    if( sync->audio->config.out.codec == HB_ACODEC_AC3 )
     {
         buf        = hb_buffer_init( sync->ac3_size );
         buf->start = sync->next_pts;
         buf->stop  = buf->start + duration;
         memcpy( buf->data, sync->ac3_buf, buf->size );
-        OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->fifo_out, i );
+        OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->priv.fifo_out, i );
     }
     else
     {
         buf = hb_buffer_init( duration * sizeof( float ) *
-                    HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown) );
+                    HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->config.out.mixdown) );
         buf->start = sync->next_pts;
         buf->stop  = buf->start + duration;
         memset( buf->data, 0, buf->size );
-        OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->fifo_sync, i );
+        OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->priv.fifo_sync, i );
     }
 }
 
index 9ebc33b..e867a2b 100644 (file)
@@ -337,57 +337,55 @@ static void do_job( hb_job_t * job, int cpu_count )
         }
     }
 
-    if( job->audio_mixdowns[0] == HB_AMIXDOWN_AC3 || job->audio_mixdowns[1] == HB_AMIXDOWN_AC3 )
-    {
-        /* Hard set correct sample rate for AC3 when libhb
-           mistakenly thinks the audio codec is AAC */
-        job->arate = 48000;
-    }
-
-    if( job->acodec & HB_ACODEC_AC3 )
-    {
-        hb_log( " + audio AC3 passthrough" );
-
-        /* Hard set correct sample rate for AC3 */
-        job->arate = 48000;
-    }
-    else
-    {
-        hb_log( " + audio %d kbps, %d Hz", job->abitrate, job->arate );
-        hb_log( " + encoder %s", ( job->acodec & HB_ACODEC_FAAC ) ?
-                "faac" : ( ( job->acodec & HB_ACODEC_LAME ) ? "lame" :
-                "vorbis" ) );
-    }
-
-    if ( job->dynamic_range_compression > 1 )
-        hb_log(" + dynamic range compression: %f", job->dynamic_range_compression);
-
-    /* if we are doing AC3 passthru (at the codec level, not pass-through),
-     * then remove any non-AC3 audios from the job */
+    /* if we are doing passthru, and the input codec is not the same as the output
+     * codec, then remove this audio from the job */
     /* otherwise, Bad Things will happen */
     for( i = 0; i < hb_list_count( title->list_audio ); )
     {
         audio = hb_list_item( title->list_audio, i );
-        if( ( job->acodec & HB_ACODEC_AC3 ) && ( audio->codec != HB_ACODEC_AC3 ) )
+        if( ( ( audio->config.out.codec == HB_ACODEC_AC3 ) && ( audio->config.in.codec != HB_ACODEC_AC3 ) ) ||
+            ( ( audio->config.out.codec == HB_ACODEC_DCA ) && ( audio->config.in.codec != HB_ACODEC_DCA ) ) )
         {
+            hb_log( "Passthru requested and input codec is not the same as output codec for track %d",
+                    audio->config.out.track );
             hb_list_rem( title->list_audio, audio );
             free( audio );
             continue;
         }
-        i++;
+        /* Adjust output track number, in case we removed one.
+         * Output tracks sadly still need to be in sequential order.
+         */
+        audio->config.out.track = i++;
     }
 
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
-        hb_log( "   + %x, %s", audio->id, audio->lang );
+        hb_log( " + audio track %d", audio->config.out.track );
+        hb_log( "   + input track %d", audio->config.in.track );
+        if( (audio->config.out.codec == HB_ACODEC_AC3) || (audio->config.out.codec == HB_ACODEC_DCA) )
+        {
+            hb_log( "   + %s passthrough", (audio->config.out.codec == HB_ACODEC_AC3) ?
+                "AC3" : "DCA" );
+        }
+        else
+        {
+            hb_log( "   + audio %d kbps, %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );
+            hb_log( "   + encoder %s", ( audio->config.out.codec == HB_ACODEC_FAAC ) ?
+            "faac" : ( ( audio->config.out.codec == HB_ACODEC_LAME ) ? "lame" :
+            "vorbis" ) );
+            if ( audio->config.out.dynamic_range_compression > 1 )
+                hb_log("   + dynamic range compression: %f", audio->config.out.dynamic_range_compression);
+        }
+
+        hb_log( "     + %x, %s", audio->id, audio->config.lang.description );
 
                /* sense-check the current mixdown options */
 
                /* log the requested mixdown */
                for (j = 0; j < hb_audio_mixdowns_count; j++) {
-                       if (hb_audio_mixdowns[j].amixdown == job->audio_mixdowns[i]) {
-                               hb_log( "     + Requested mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
+                       if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) {
+                               hb_log( "       + Requested mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
                                break;
                        }
                }
@@ -396,33 +394,22 @@ static void do_job( hb_job_t * job, int cpu_count )
 
         /* audioCodecsSupportMono and audioCodecsSupport6Ch are the same for now,
            but this may change in the future, so they are separated for flexibility */
-        int audioCodecsSupportMono = ((audio->codec == HB_ACODEC_AC3 ||
-            audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS));
-        int audioCodecsSupport6Ch =  ((audio->codec == HB_ACODEC_AC3 ||
-            audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS));
+        int audioCodecsSupportMono = ( (audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA) &&
+            (audio->config.out.codec == HB_ACODEC_FAAC || audio->config.out.codec == HB_ACODEC_VORBIS) );
+        int audioCodecsSupport6Ch =  ( (audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA) &&
+            (audio->config.out.codec == HB_ACODEC_FAAC || audio->config.out.codec == HB_ACODEC_VORBIS));
 
-        if( audio->codec != HB_ACODEC_AC3 && job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
-        {
-            /*
-             * Sanity check that we haven't asked for AC3 from a non AC3 track - drop this track
-             * to stereo to avoid a crash later.
-             */
-            job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
-        }
-
-        if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )
-        {
         /* find out what the format of our source audio is */
-        switch (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) {
+        switch (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) {
 
             /* mono sources */
             case HB_INPUT_CH_LAYOUT_MONO:
                 /* regardless of what stereo mixdown we've requested, a mono source always get mixed down
                 to mono if we can, and mixed up to stereo if we can't */
-                if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;
+                if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_MONO;
                 } else {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+                    audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
                 }
                 break;
 
@@ -430,11 +417,11 @@ static void do_job( hb_job_t * job, int cpu_count )
             case HB_INPUT_CH_LAYOUT_STEREO:
                 /* if we've requested a mono mixdown, and it is supported, then do the mix */
                 /* use stereo if not supported */
-                if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+                if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
                 /* otherwise, preserve stereo regardless of if we requested something higher */
-                } else if (job->audio_mixdowns[i] > HB_AMIXDOWN_STEREO) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+                } else if (audio->config.out.mixdown > HB_AMIXDOWN_STEREO) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
                 }
                 break;
 
@@ -444,12 +431,12 @@ static void do_job( hb_job_t * job, int cpu_count )
             case HB_INPUT_CH_LAYOUT_DOLBY:
                 /* if we've requested a mono mixdown, and it is supported, then do the mix */
                 /* preserve dolby if not supported */
-                if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+                if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
                 /* otherwise, preserve dolby even if we requested something higher */
                 /* a stereo mixdown will still be honoured here */
-                } else if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBY) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+                } else if (audio->config.out.mixdown > HB_AMIXDOWN_DOLBY) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
                 }
                 break;
 
@@ -457,21 +444,21 @@ static void do_job( hb_job_t * job, int cpu_count )
             case HB_INPUT_CH_LAYOUT_3F2R:
                 /* if we've requested a mono mixdown, and it is supported, then do the mix */
                 /* use dpl2 if not supported */
-                if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;
+                if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
                 } else {
                     /* check if we have 3F2R input and also have an LFE - i.e. we have a 5.1 source) */
-                    if (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE) {
+                    if (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE) {
                         /* we have a 5.1 source */
                         /* if we requested 6ch, but our audio format doesn't support it, then mix to DPLII instead */
-                        if (job->audio_mixdowns[i] == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {
-                            job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;
+                        if (audio->config.out.mixdown == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {
+                            audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
                         }
                     } else {
                         /* we have a 5.0 source, so we can't do 6ch conversion
                         default to DPL II instead */
-                        if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBYPLII) {
-                            job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;
+                        if (audio->config.out.mixdown > HB_AMIXDOWN_DOLBYPLII) {
+                            audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
                         }
                     }
                 }
@@ -482,13 +469,13 @@ static void do_job( hb_job_t * job, int cpu_count )
             case HB_INPUT_CH_LAYOUT_3F1R:
                 /* if we've requested a mono mixdown, and it is supported, then do the mix */
                 /* use dpl1 if not supported */
-                if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+                if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
                 } else {
                     /* we have a 4.0 or 4.1 source, so we can't do DPLII or 6ch conversion
                     default to DPL I instead */
-                    if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBY) {
-                        job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+                    if (audio->config.out.mixdown > HB_AMIXDOWN_DOLBY) {
+                        audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
                     }
                 }
                 /* all other mixdowns will have been preserved here */
@@ -496,41 +483,37 @@ static void do_job( hb_job_t * job, int cpu_count )
 
             default:
                 /* if we've requested a mono mixdown, and it is supported, then do the mix */
-                if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;
+                if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
+                    audio->config.out.mixdown = HB_AMIXDOWN_MONO;
                 /* mix everything else down to stereo */
                 } else {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+                    audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
                 }
 
         }
-        }
 
                /* log the output mixdown */
                for (j = 0; j < hb_audio_mixdowns_count; j++) {
-                       if (hb_audio_mixdowns[j].amixdown == job->audio_mixdowns[i]) {
-                               hb_log( "     + Actual mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
+                       if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) {
+                               hb_log( "       + Actual mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
                                break;
                        }
                }
 
-               /* we now know we have a valid mixdown for the input source and the audio output format */
-               /* remember the mixdown for this track */
-               audio->amixdown = job->audio_mixdowns[i];
-
-        audio->config.vorbis.language = audio->lang_simple;
+        if (audio->config.out.codec == HB_ACODEC_VORBIS)
+            audio->priv.config.vorbis.language = audio->config.lang.simple;
 
         /* set up the audio work structures */
-        audio->fifo_in   = hb_fifo_init( 2048 );
-        audio->fifo_raw  = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
-        audio->fifo_sync = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
-        audio->fifo_out  = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
+        audio->priv.fifo_in   = hb_fifo_init( 2048 );
+        audio->priv.fifo_raw  = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
+        audio->priv.fifo_sync = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
+        audio->priv.fifo_out  = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
 
 
         /*
          * Audio Decoder Thread
          */
-        switch( audio->codec )
+        switch( audio->config.in.codec )
         {
             case HB_ACODEC_AC3:
                 w = getWork( WORK_DECA52 );
@@ -544,12 +527,16 @@ static void do_job( hb_job_t * job, int cpu_count )
             case HB_ACODEC_LPCM:
                 w = getWork( WORK_DECLPCM );
                 break;
+            default:
+                /* Invalid input codec */
+                hb_error("Invalid input codec: %d", audio->config.in.codec);
+                *job->die = 1;
+                goto cleanup;
         }
-        w->fifo_in       = audio->fifo_in;
-        w->fifo_out      = audio->fifo_raw;
-        w->config        = &audio->config;
-        w->amixdown      = audio->amixdown;
-        w->source_acodec = audio->codec;
+        w->fifo_in       = audio->priv.fifo_in;
+        w->fifo_out      = audio->priv.fifo_raw;
+        w->config        = &audio->priv.config;
+        w->audio         = audio;
 
         /* FIXME: This feels really hackish, anything better? */
         audio_w = calloc( sizeof( hb_work_object_t ), 1 );
@@ -560,10 +547,8 @@ static void do_job( hb_job_t * job, int cpu_count )
         /*
          * Audio Encoder Thread
          */
-        if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )
+        switch( audio->config.out.codec )
         {
-            switch( job->acodec )
-            {
             case HB_ACODEC_FAAC:
                 w = getWork( WORK_ENCFAAC );
                 break;
@@ -573,20 +558,25 @@ static void do_job( hb_job_t * job, int cpu_count )
             case HB_ACODEC_VORBIS:
                 w = getWork( WORK_ENCVORBIS );
                 break;
-            }
+            case HB_ACODEC_AC3:
+                break;
+            case HB_ACODEC_DCA:    /* These are all invalid output codecs. */
+            default:
+                hb_error("Invalid audio codec: %#x", audio->config.out.codec);
+                w = NULL;
+                *job->die = 1;
+                goto cleanup;
         }
 
-        if( job->acodec != HB_ACODEC_AC3 &&
-            job->audio_mixdowns[i] != HB_AMIXDOWN_AC3)
+        if( audio->config.out.codec != HB_ACODEC_AC3 )
         {
             /*
              * Add the encoder thread if not doing AC-3 pass through
              */
-            w->fifo_in       = audio->fifo_sync;
-            w->fifo_out      = audio->fifo_out;
-            w->config        = &audio->config;
-            w->amixdown      = audio->amixdown;
-            w->source_acodec = audio->codec;
+            w->fifo_in       = audio->priv.fifo_sync;
+            w->fifo_out      = audio->priv.fifo_out;
+            w->config        = &audio->priv.config;
+            w->audio         = audio;
 
             /* FIXME: This feels really hackish, anything better? */
             audio_w = calloc( sizeof( hb_work_object_t ), 1 );
@@ -640,12 +630,16 @@ static void do_job( hb_job_t * job, int cpu_count )
     w->close( w );
     job->done = 1;
 
+cleanup:
     /* Close work objects */
     while( ( w = hb_list_item( job->list_work, 0 ) ) )
     {
         hb_list_rem( job->list_work, w );
-        hb_thread_close( &w->thread );
-        w->close( w );
+        if( w != NULL && w->thread != NULL )
+        {
+            hb_thread_close( &w->thread );
+            w->close( w );
+        }
 
         /* FIXME: This feels really hackish, anything better? */
         if ( w->id == WORK_DECA52 ||
@@ -663,8 +657,10 @@ static void do_job( hb_job_t * job, int cpu_count )
     hb_list_close( &job->list_work );
 
     /* Stop read & write threads */
-    hb_thread_close( &job->reader );
-    hb_thread_close( &job->muxer );
+    if( job->reader != NULL )
+        hb_thread_close( &job->reader );
+    if( job->muxer != NULL )
+        hb_thread_close( &job->muxer );
 
     /* Close fifos */
     hb_fifo_close( &job->fifo_mpeg2 );
@@ -684,10 +680,14 @@ static void do_job( hb_job_t * job, int cpu_count )
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
         audio = hb_list_item( title->list_audio, i );
-        hb_fifo_close( &audio->fifo_in );
-        hb_fifo_close( &audio->fifo_raw );
-        hb_fifo_close( &audio->fifo_sync );
-        hb_fifo_close( &audio->fifo_out );
+        if( audio->priv.fifo_in != NULL )
+            hb_fifo_close( &audio->priv.fifo_in );
+        if( audio->priv.fifo_raw != NULL )
+            hb_fifo_close( &audio->priv.fifo_raw );
+        if( audio->priv.fifo_sync != NULL )
+            hb_fifo_close( &audio->priv.fifo_sync );
+        if( audio->priv.fifo_out != NULL )
+            hb_fifo_close( &audio->priv.fifo_out );
     }
 
     if( job->indepth_scan )