All pastes #960330 Raw Edit

Entire saintdev audio with crash

public text v1 · immutable
#960330 ·published 2008-03-28 00:44 UTC
rendered paste body
Index: test/test.c
===================================================================
--- test/test.c	(revision 1364)
+++ test/test.c	(working copy)
@@ -37,22 +37,27 @@
 static int    vcodec      = HB_VCODEC_FFMPEG;
 static int    h264_13     = 0;
 static int    h264_30     = 0;
-static char * audios      = NULL;
-static int    audio_mixdown = HB_AMIXDOWN_DOLBYPLII;
-static float  dynamic_range_compression = 0;
+static hb_list_t * audios = NULL;
+static hb_audio_t * audio = NULL;
+static int    num_audio_tracks = 0;
+static char * mixdowns    = NULL;
+static char * dynamic_range_compression = NULL;
+static char * arates      = NULL;
+static char * abitrates   = NULL;
+static char * acodecs     = NULL;
+static int    default_acodec = HB_ACODEC_FAAC;
+static int    default_arate = 44100;
+static int    default_abitrate = 128;
 static int    sub         = 0;
 static int    width       = 0;
 static int    height      = 0;
 static int    crop[4]     = { -1,-1,-1,-1 };
 static int    cpu         = 0;
 static int    vrate       = 0;
-static int    arate       = 0;
 static float  vquality    = -1.0;
 static int    vbitrate    = 0;
 static int    size        = 0;
-static int    abitrate    = 0;
 static int    mux         = 0;
-static int    acodec      = 0;
 static int    pixelratio  = 0;
 static int    loosePixelratio = 0;
 static int    modulus       = 0;
@@ -87,6 +92,9 @@
 static int  CheckOptions( int argc, char ** argv );
 static int  HandleEvents( hb_handle_t * h );
 
+static int get_acodec_for_string( char *codec );
+static int is_sample_rate_valid(int rate);
+
 /* Only print the "Muxing..." message once */
 static int show_mux_warning = 1;
 
@@ -107,6 +115,8 @@
     int           build;
     char        * version;
 
+    audios = hb_list_init();
+
     /* Parse command line */
     if( ParseOptions( argc, argv ) ||
         CheckOptions( argc, argv ) )
@@ -230,7 +240,20 @@
     if( input )  free( input );
     if( output ) free( output );
     if( format ) free( format );
-    if( audios ) free( audios );
+    if( audios )
+    {
+        while( ( audio = hb_list_item( audios, 0 ) ) )
+        {
+            hb_list_rem( audios, audio );
+            free( audio );
+        }
+        hb_list_close( &audios );
+    }
+    if( mixdowns ) free( mixdowns );
+    if( dynamic_range_compression ) free( dynamic_range_compression );
+    if( arates ) free( arates );
+    if( abitrates ) free( abitrates );
+    if( acodecs ) free( acodecs );
     if (native_language ) free (native_language );
 	if( x264opts ) free (x264opts );
 	if( x264opts2 ) free (x264opts2 );
@@ -283,14 +306,14 @@
     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) )
+        if( ( audio->in.codec == HB_ACODEC_AC3 ) || ( audio->in.codec == HB_ACODEC_DCA) )
         {
             fprintf( stderr, "    + %d, %s, %dHz, %dbps\n", i + 1,
-                     audio->lang, audio->rate, audio->bitrate );
+                     audio->lang.description, audio->in.samplerate, audio->in.bitrate );
         }
         else
         {
-            fprintf( stderr, "    + %d, %s\n", i + 1, audio->lang );
+            fprintf( stderr, "    + %d, %s\n", i + 1, audio->lang.description );
         }
     }
     fprintf( stderr, "  + subtitle tracks:\n" );
@@ -300,13 +323,13 @@
         fprintf( stderr, "    + %d, %s (iso639-2: %s)\n", i + 1, subtitle->lang,
             subtitle->iso639_2);
     }
-    
+
     if(title->detected_interlacing)
     {
         /* Interlacing was found in half or more of the preview frames */
         fprintf( stderr, "  + combing detected, may be interlaced or telecined\n");
     }
-    
+
 }
 
 static int HandleEvents( hb_handle_t * h )
@@ -334,7 +357,16 @@
             hb_list_t  * list;
             hb_title_t * title;
             hb_job_t   * job;
+            int i;
 
+            /* Audio argument string parsing variables */
+            int acodec = 0;
+            int abitrate = 0;
+            int arate = 0;
+            int mixdown = HB_AMIXDOWN_DOLBYPLII;
+            double d_r_c = 0;
+            /* Audio argument string parsing variables */
+
             list = hb_get_titles( h );
 
             if( !hb_list_count( list ) )
@@ -419,9 +451,9 @@
                     mux = HB_MUX_MKV;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 1000;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     x264opts = strdup("ref=5:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2");
                     deinterlace = 1;
                     deinterlace_opt = "0";
@@ -433,15 +465,26 @@
 
                 if (!strcmp(preset_name, "AppleTV"))
                 {
+                    if (hb_list_count(audios) == 0)
+                    {
+                        audio = hb_audio_new();
+                        audio->in.track = audio->out.track = 0;
+                        hb_list_add(audios, audio);
+
+                        audio = hb_audio_new();
+                        audio->in.track = 0;
+                        audio->out.track = 1;
+                        hb_list_add(audios, audio);
+                        if (acodecs) free(acodecs);
+                        acodecs = strdup("faac,ac3");
+                    }
                     mux = HB_MUX_MP4;
                     job->largeFileSize = 1;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 2500;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
-                    audio_mixdown = HB_AMIXDOWN_DOLBYPLII_AC3;
-                    arate = 48000;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     x264opts = strdup("bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0");
                     job->chapter_markers = 1;
                     pixelratio = 1;
@@ -452,7 +495,7 @@
                     mux = HB_MUX_MKV;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 1800;
-                    acodec = HB_ACODEC_AC3;
+                    default_acodec = HB_ACODEC_AC3;
                     x264opts = strdup("ref=16:mixed-refs:bframes=16:bime:weightb:b-rdo:direct=auto:b-pyramid:me=esa:subme=7:me-range=64:analyse=all:8x8dct:trellis=1:no-fast-pskip:no-dct-decimate:filter=-2,-1");
                     job->chapter_markers = 1;
                     pixelratio = 1;
@@ -464,9 +507,9 @@
                 {
                     mux = HB_MUX_MP4;
                     job->vbitrate = 512;
-                    job->abitrate = 128;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 128;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     job->width = 512;
                     job->chapter_markers = 1;
                 }
@@ -476,9 +519,9 @@
                     mux = HB_MUX_MP4;
                     vcodec = HB_VCODEC_X264;
                     size = 695;
-                    job->abitrate = 128;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 128;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     job->width = 640;
                     x264opts = strdup("ref=3:mixed-refs:bframes=16:bime:weightb:b-rdo:b-pyramid:direct=auto:me=umh:subme=6:trellis=1:analyse=all:8x8dct:no-fast-pskip");
                     job->chapter_markers = 1;
@@ -490,9 +533,9 @@
                 {
                     mux = HB_MUX_MP4;
                     job->vbitrate = 1000;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                 }
 
                 if (!strcmp(preset_name, "Constant Quality Rate"))
@@ -501,7 +544,7 @@
                     vcodec = HB_VCODEC_X264;
                     job->vquality = 0.64709997177124023;
                     job->crf = 1;
-                    acodec = HB_ACODEC_AC3;
+                    default_acodec = HB_ACODEC_AC3;
                     x264opts = strdup("ref=3:mixed-refs:bframes=3:b-pyramid:b-rdo:bime:weightb:filter=-2,-1:subme=6:trellis=1:analyse=all:8x8dct:me=umh");
                     job->chapter_markers = 1;
                     pixelratio = 1;
@@ -512,7 +555,7 @@
                     mux = HB_MUX_MKV;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 1600;
-                    acodec = HB_ACODEC_AC3;
+                    default_acodec = HB_ACODEC_AC3;
                     x264opts = strdup("ref=5:mixed-refs:bframes=3:bime:weightb:b-rdo:b-pyramid:me=umh:subme=7:trellis=1:analyse=all:8x8dct:no-fast-pskip");
                     job->chapter_markers = 1;
                     pixelratio = 1;
@@ -525,7 +568,7 @@
                     mux = HB_MUX_MKV;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 1800;
-                    acodec = HB_ACODEC_AC3;
+                    default_acodec = HB_ACODEC_AC3;
                     x264opts = strdup("ref=3:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip");
                     job->chapter_markers = 1;
                     pixelratio = 1;
@@ -539,9 +582,9 @@
                     job->ipod_atom = 1;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 960;
-                    job->abitrate = 128;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 128;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     job->width = 480;
                     x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=1");
                     job->chapter_markers = 1;
@@ -553,9 +596,9 @@
                     job->ipod_atom = 1;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 1500;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     job->width = 640;
                     x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1");
                     job->chapter_markers = 1;
@@ -567,9 +610,9 @@
                     job->ipod_atom = 1;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 700;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     job->width = 320;
                     x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1");
                     job->chapter_markers = 1;
@@ -580,9 +623,9 @@
                     mux = HB_MUX_MP4;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 1500;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     x264opts = strdup("ref=2:bframes=2:subme=5:me=umh");
                     job->chapter_markers = 1;
                     pixelratio = 1;
@@ -595,9 +638,9 @@
                     mux = HB_MUX_MP4;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 2500;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     x264opts = strdup("level=41:subme=5:me=umh");
                     pixelratio = 1;
                 }
@@ -606,9 +649,9 @@
                 {
                     mux = HB_MUX_MP4;
                     job->vbitrate = 1024;
-                    job->abitrate = 128;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 128;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     job->width = 368;
                     job->height = 208;
                     job->chapter_markers = 1;
@@ -619,9 +662,9 @@
                     mux = HB_MUX_MP4;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 2000;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     x264opts = strdup("ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:me=umh:subme=5:analyse=all:trellis=1:no-fast-pskip");
                     job->chapter_markers = 1;
                     pixelratio = 1;
@@ -634,9 +677,9 @@
                     mux = HB_MUX_MKV;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 1300;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     x264opts = strdup("ref=3:mixed-refs:bframes=6:bime:weightb:direct=auto:b-pyramid:me=umh:subme=6:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip");
                     deinterlace = 1;
                     deinterlace_opt = "0";
@@ -652,9 +695,9 @@
                     mux = HB_MUX_MP4;
                     vcodec = HB_VCODEC_X264;
                     job->vbitrate = 2000;
-                    job->abitrate = 160;
-                    job->arate = 48000;
-                    acodec = HB_ACODEC_FAAC;
+                    default_abitrate = 160;
+                    default_arate = 48000;
+                    default_acodec = HB_ACODEC_FAAC;
                     x264opts = strdup("level=40:ref=2:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:no-fast-pskip:filter=-2,-1");
                     pixelratio = 1;
                 }
@@ -732,13 +775,13 @@
             {
                 job->pixel_ratio = pixelratio;
             }
-            
+
             if (vfr)
             {
                 detelecine = 1;
                 job->vfr = 1;
             }
-            
+
             /* Add selected filters */
             job->filters = hb_list_init();
             if( detelecine )
@@ -816,74 +859,228 @@
                 job->vrate = 27000000;
                 job->vrate_base = vrate;
             }
-            if( arate )
+
+            /* Parse audio tracks */
+            if( hb_list_count(audios) == 0 )
             {
-                job->arate = arate;
+                /* Create a new audio track with default settings */
+                audio = hb_audio_new();
+                /* Add it to our audios */
+                hb_list_add(audios, audio);
             }
+            num_audio_tracks = hb_list_count(audios);
 
-            if( audios )
+            for (i = 0; i < num_audio_tracks; i++)
             {
-                if( strcasecmp( audios, "none" ) )
+                audio = hb_list_item(audios, i);
+                if ( (audio->in.track == -1) || (audio->out.track == -1) ||
+                     (audio->out.codec == 0) )
                 {
-                    int    audio_count = 0;
-                    char * tmp         = audios;
-                    while( *tmp )
+                    num_audio_tracks--;
+                    hb_list_rem(audios, audio);
+                    free(audio);
+                    continue;
+                }
+                hb_list_add(job->list_audio, hb_audio_copy( hb_list_item( title->list_audio, audio->in.track ) ) );
+            }
+            /* Audio Tracks */
+
+            /* Audio Codecs */
+            i = 0;
+            if( acodecs )
+            {
+                char * token = strtok(acodecs, ",");
+                if (token == NULL)
+                    token = acodecs;
+                while ( token != NULL )
+                {
+                    if ((acodec = get_acodec_for_string(token)) == -1)
                     {
-                        if( *tmp < '0' || *tmp > '9' )
+                        fprintf(stderr, "Invalid codec %s, using default for container.\n", token);
+                        acodec = default_acodec;
+                    }
+                    audio = hb_list_item(job->list_audio, i);
+                    audio->out.codec = acodec;
+                    if( (++i) >= num_audio_tracks )
+                        break;  /* We have more inputs than audio tracks, oops */
+                    token = strtok(NULL, ",");
+                }
+            }
+            if (i < num_audio_tracks)
+            {
+                /* We have fewer inputs than audio tracks, use the default codec for
+                 * this container for the remaining tracks. Unless we only have one input
+                 * then use that codec instead.
+                 */
+                if (i != 1)
+                    acodec = default_acodec;
+                for ( ; i < num_audio_tracks; i++)
+                {
+                    audio = hb_list_item(job->list_audio, i);
+                    audio->out.codec = acodec;
+                }
+            }
+            /* Audio Codecs */
+
+            /* Sample Rate */
+            i = 0;
+            if( arates )
+            {
+                char * token = strtok(arates, ",");
+                if (token == NULL)
+                    token = arates;
+                while ( token != NULL )
+                {
+                    arate = atoi(token);
+                    audio = hb_list_item(job->list_audio, i);
+                    if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+                    {
+                        /* Would probably be better to have this handled in libhb. */
+                        audio->out.samplerate = audio->in.samplerate;
+                    }
+                    else
+                    {
+                        if (!is_sample_rate_valid(arate))
                         {
-                            /* Skip non numeric char */
-                            tmp++;
-                            continue;
+                            fprintf(stderr, "Invalid sample rate %d, using default\n", arate);
+                            arate = default_arate;
                         }
-						job->audio_mixdowns[audio_count] = audio_mixdown;
-                        job->audios[audio_count++] =
-                            strtol( tmp, &tmp, 0 ) - 1;
+                        audio->out.samplerate = arate;
                     }
-                    job->audios[audio_count] = -1;
+                    if( (++i) >= num_audio_tracks )
+                        break;  /* We have more inputs than audio tracks, oops */
+                    token = strtok(NULL, ",");
                 }
-                else
+            }
+            if (i < num_audio_tracks)
+            {
+                /* We have fewer inputs than audio tracks, use default sample rate.
+                 * Unless we only have one input, then use that for all tracks.
+                 */
+                if (i != 1)
+                    arate = default_arate;
+                for ( ; i < num_audio_tracks; i++)
                 {
-                    job->audios[0] = -1;
+                    audio = hb_list_item(job->list_audio, i);
+                    if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+                    {
+                        audio->out.samplerate = audio->in.samplerate;
+                        continue;
+                    }
+                    audio->out.samplerate = arate;
                 }
             }
-			else
-			{
-			    /* default to the first audio track if none has been specified */
-			    job->audios[0] = 0;
-			    job->audio_mixdowns[0] = audio_mixdown;
-			}
+            /* Sample Rate */
 
-			if( audio_mixdown == HB_AMIXDOWN_DOLBYPLII_AC3)
-			{
-               int i;
-               for( i = 3 ; i > 0; i--)
-               {
-                   job->audios[i*2+1] = job->audios[i];
-                   job->audios[i*2] = job->audios[i];
-                   if(job->audios[i] != -1  )
-                   {
-                       job->audio_mixdowns[i*2+1] = HB_AMIXDOWN_AC3;
-                       job->audio_mixdowns[i*2] = HB_AMIXDOWN_DOLBYPLII;
-                   }
-               }
-
-               job->audios[1] = job->audios[0];
-               job->audio_mixdowns[1] = HB_AMIXDOWN_AC3;
-               job->audio_mixdowns[0] = HB_AMIXDOWN_DOLBYPLII;
+            /* Audio Bitrate */
+            i = 0;
+            if( abitrates )
+            {
+                char * token = strtok(abitrates, ",");
+                if (token == NULL)
+                    token = abitrates;
+                while ( token != NULL )
+                {
+                    abitrate = atoi(token);
+                    audio = hb_list_item(job->list_audio, i);
+                    if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+                    {
+                        audio->out.bitrate = audio->in.bitrate;   /* See note above about arate. */
+                    }
+                    else
+                    {
+                        audio->out.bitrate = abitrate;
+                    }
+                    if( (++i) >= num_audio_tracks )
+                        break;  /* We have more inputs than audio tracks, oops */
+                    token = strtok(NULL, ",");
+                }
             }
+            if (i < num_audio_tracks)
+            {
+                /* We have fewer inputs than audio tracks, use the default bitrate
+                 * for the remaining tracks. Unless we only have one input, then use
+                 * that for all tracks.
+                 */
+                if (i != 1)
+                    abitrate = default_abitrate;
+                for (; i < num_audio_tracks; i++)
+                {
+                    audio = hb_list_item(job->list_audio, i);
+                    if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+                    {
+                        audio->out.bitrate = audio->in.bitrate;
+                        continue;
+                    }
+                    audio->out.bitrate = abitrate;
+                }
+            }
+            /* Audio Bitrate */
 
-            if( abitrate )
+            /* Audio DRC */
+            i = 0;
+            if ( dynamic_range_compression )
             {
-                job->abitrate = abitrate;
+                char * token = strtok(dynamic_range_compression, ",");
+                if (token == NULL)
+                    token = dynamic_range_compression;
+                while ( token != NULL )
+                {
+                    d_r_c = atof(token);
+                    audio = hb_list_item(job->list_audio, i);
+                    audio->out.dynamic_range_compression = d_r_c;
+                    if( (++i) >= num_audio_tracks )
+                        break;  /* We have more inputs than audio tracks, oops */
+                    token = strtok(NULL, ",");
+                }
             }
-            if( acodec )
+            if (i < num_audio_tracks)
             {
-                job->acodec = acodec;
+                /* We have fewer inputs than audio tracks, use no DRC for the remaining
+                 * tracks. Unless we only have one input, then use the same DRC for all
+                 * tracks.
+                 */
+                if (i != 1)
+                    d_r_c = 0;
+                for (; i < num_audio_tracks; i++)
+                {
+                    audio = hb_list_item(job->list_audio, i);
+                    audio->out.dynamic_range_compression = d_r_c;
+                }
             }
-            if ( dynamic_range_compression )
+            /* Audio DRC */
+
+            /* Audio Mixdown */
+            i = 0;
+            if ( mixdowns )
             {
-                job->dynamic_range_compression = dynamic_range_compression;
+                char * token = strtok(mixdowns, ",");
+                if (token == NULL)
+                    token = mixdowns;
+                while ( token != NULL )
+                {
+                    mixdown = hb_mixdown_get_mixdown_from_short_name(token);
+                    audio = hb_list_item(job->list_audio, i);
+                    audio->out.mixdown = mixdown;
+                    if( (++i) >= num_audio_tracks )
+                        break;  /* We have more inputs than audio tracks, oops */
+                    token = strtok(NULL, ",");
+                }
             }
+            if (i < num_audio_tracks)
+            {
+                /* We have fewer inputs than audio tracks, use DPLII for the rest. Unless
+                 * we only have one input, then use that.
+                 */
+                if (i != 1)
+                    mixdown = HB_AMIXDOWN_DOLBYPLII;
+                for (; i < num_audio_tracks; i++)
+                {
+                   audio = hb_list_item(job->list_audio, i);
+                   audio->out.mixdown = mixdown;
+                }
+            }
+            /* Audio Mixdown */
 
             if( size )
             {
@@ -1227,18 +1424,21 @@
 
 
 	"### Audio Options-----------------------------------------------------------\n\n"
-	"    -E, --aencoder <string> Audio encoder (faac/lame/vorbis/ac3/aac+ac3) \n"
-	"                            ac3 meaning passthrough, aac+ac3 meaning an\n"
-	"                            aac dpl2 mixdown paired with ac3 pass-thru\n"
+	"    -a, --audio <string>    Select audio channel(s), separated by commas\n"
+    "                            More than one output track can be used for one\n"
+    "                            input.\n"
+    "                            (\"none\" for no audio, \"1,2,3\" for multiple\n"
+    "                             tracks, default: first one)\n"
+    "    -E, --aencoder <string> Audio encoder(s) (faac/lame/vorbis/ac3) \n"
+	"                            ac3 meaning passthrough\n"
+	"                            Seperated by commas for more than one audio track.\n"
 	"                            (default: guessed)\n"
-	"    -B, --ab <kb/s>         Set audio bitrate (default: 128)\n"
-	"    -a, --audio <string>    Select audio channel(s), separated by commas\n"
-	"                            (\"none\" for no audio, \"1,2,3\" for multiple\n"
-	"                             tracks, default: first one,\n"
-	"                             max 8 normally, max 4 with aac+ac3)\n"
-    "    -6, --mixdown <string>  Format for surround sound downmixing\n"
+	"    -B, --ab <kb/s>         Set audio bitrate(s)  (default: 128)\n"
+    "                            Seperated by commas for more than one audio track.\n"
+	"    -6, --mixdown <string>  Format(s) for surround sound downmixing\n"
+    "                            Seperated by commas for more than one audio track.\n"
     "                            (mono/stereo/dpl1/dpl2/6ch, default: dpl2)\n"
-    "    -R, --arate             Set audio samplerate (" );
+    "    -R, --arate             Set audio samplerate(s) (" );
     for( i = 0; i < hb_audio_rates_count; i++ )
     {
         fprintf( stderr, hb_audio_rates[i].string );
@@ -1246,9 +1446,11 @@
             fprintf( stderr, "/" );
     }
     fprintf( stderr, " kHz)\n"
+    "                            Seperated by commas for more than one audio track.\n"
     "    -D, --drc <float>       Apply extra dynamic range compression to the audio,\n"
     "                            making soft sounds louder. Range is 1.0 to 4.0\n"
     "                            (too loud), with 1.5 - 2.5 being a useful range.\n"
+    "                            Seperated by commas for more than one audio track.\n"
 
 
 	"\n"
@@ -1461,33 +1663,64 @@
                 chapter_markers = 1;
                 break;
             case 'a':
-                audios = strdup( optarg );
+            {
+                char * token = strtok(optarg, ",");
+                if (token == NULL)
+                    token = optarg;
+                int track_start, track_end;
+                while( token != NULL )
+                {
+                    audio = hb_audio_new();
+                    if (strlen(token) >= 3)
+                    {
+                        if (sscanf(token, "%d-%d", &track_start, &track_end) == 2)
+                        {
+                            int i;
+                            for (i = track_start - 1; i < track_end; i++)
+                            {
+                                if (i != track_start - 1)
+                                    audio = hb_audio_new();
+                                audio->in.track = i;
+                                audio->out.track = num_audio_tracks++;
+                                hb_list_add(audios, audio);
+                            }
+                        }
+                        else if( !strcasecmp(token, "none" ) )
+                        {
+                            audio->in.track = audio->out.track = -1;
+                            audio->out.codec = 0;
+                            hb_list_add(audios, audio);
+                            break;
+                        }
+                        else
+                        {
+                            fprintf(stderr, "ERROR: Unable to parse audio input \"%s\", skipping.",
+                                    token);
+                            free(audio);
+                        }
+                    }
+                    else
+                    {
+                        audio->in.track = atoi(token) - 1;
+                        audio->out.track = num_audio_tracks++;
+                        hb_list_add(audios, audio);
+                    }
+                    token = strtok(NULL, ",");
+                }
                 break;
+            }
             case '6':
-                if( !strcasecmp( optarg, "mono" ) )
+                if( optarg != NULL )
                 {
-                    audio_mixdown = HB_AMIXDOWN_MONO;
+                    mixdowns = strdup( optarg );
                 }
-                else if( !strcasecmp( optarg, "stereo" ) )
+                break;
+            case 'D':
+                if( optarg != NULL )
                 {
-                    audio_mixdown = HB_AMIXDOWN_STEREO;
+                    dynamic_range_compression = strdup( optarg );
                 }
-                else if( !strcasecmp( optarg, "dpl1" ) )
-                {
-                    audio_mixdown = HB_AMIXDOWN_DOLBY;
-                }
-                else if( !strcasecmp( optarg, "dpl2" ) )
-                {
-                    audio_mixdown = HB_AMIXDOWN_DOLBYPLII;
-                }
-                else if( !strcasecmp( optarg, "6ch" ) )
-                {
-                    audio_mixdown = HB_AMIXDOWN_6CH;
-                }
                 break;
-            case 'D':
-                dynamic_range_compression = atof( optarg );
-                break;
             case 's':
                 sub = atoi( optarg );
                 break;
@@ -1608,28 +1841,10 @@
                 }
                 break;
             case 'E':
-                if( !strcasecmp( optarg, "ac3" ) )
+                if( optarg != NULL )
                 {
-                    acodec = HB_ACODEC_AC3;
+                    acodecs = strdup( optarg );
                 }
-                else if( !strcasecmp( optarg, "lame" ) )
-                {
-                    acodec = HB_ACODEC_LAME;
-                }
-                else if( !strcasecmp( optarg, "faac" ) )
-                {
-                    acodec = HB_ACODEC_FAAC;
-                }
-                else if( !strcasecmp( optarg, "vorbis") )
-                {
-                    acodec = HB_ACODEC_VORBIS;
-                }
-                else if( !strcasecmp( optarg, "aac+ac3") )
-                {
-                    acodec = HB_ACODEC_FAAC;
-                    audio_mixdown = HB_AMIXDOWN_DOLBYPLII_AC3;
-                    arate = 48000;
-                }
                 break;
             case 'w':
                 width = atoi( optarg );
@@ -1669,23 +1884,11 @@
                 break;
             }
             case 'R':
-            {
-                int i;
-                arate = 0;
-                for( i = 0; i < hb_audio_rates_count; i++ )
+                if( optarg != NULL )
                 {
-                    if( !strcmp( optarg, hb_audio_rates[i].string ) )
-                    {
-                        arate = hb_audio_rates[i].rate;
-                        break;
-                    }
+                    arates = strdup( optarg );
                 }
-                if( !arate )
-                {
-                    fprintf( stderr, "invalid framerate %s\n", optarg );
-                }
                 break;
-            }
             case 'b':
                 vbitrate = atoi( optarg );
                 break;
@@ -1696,7 +1899,10 @@
                 size = atoi( optarg );
                 break;
             case 'B':
-                abitrate = atoi( optarg );
+                if( optarg != NULL )
+                {
+                    abitrates = strdup( optarg );
+                }
                 break;
             case 'Q':
                 crf = 0;
@@ -1810,23 +2016,23 @@
             return 1;
         }
 
-        if( !acodec )
+        if( !acodecs )
         {
             if( mux == HB_MUX_MP4 || mux == HB_MUX_IPOD )
             {
-                acodec = HB_ACODEC_FAAC;
+                default_acodec = HB_ACODEC_FAAC;
             }
             else if( mux == HB_MUX_AVI )
             {
-                acodec = HB_ACODEC_LAME;
+                default_acodec = HB_ACODEC_LAME;
             }
             else if( mux == HB_MUX_OGM )
             {
-                acodec = HB_ACODEC_VORBIS;
+                default_acodec = HB_ACODEC_VORBIS;
             }
             else if( mux == HB_MUX_MKV )
             {
-                acodec = HB_ACODEC_AC3;
+                default_acodec = HB_ACODEC_AC3;
             }
         }
 
@@ -1834,3 +2040,42 @@
 
     return 0;
 }
+
+static int get_acodec_for_string( char *codec )
+{
+    if( !strcasecmp( codec, "ac3" ) )
+    {
+        return HB_ACODEC_AC3;
+    }
+    else if( !strcasecmp( codec, "dts" ) || !strcasecmp( codec, "dca" ) )
+    {
+        return HB_ACODEC_DCA;
+    }
+    else if( !strcasecmp( codec, "lame" ) )
+    {
+        return HB_ACODEC_LAME;
+    }
+    else if( !strcasecmp( codec, "faac" ) )
+    {
+        return HB_ACODEC_FAAC;
+    }
+    else if( !strcasecmp( codec, "vorbis") )
+    {
+        return HB_ACODEC_VORBIS;
+    }
+    else
+    {
+        return -1;
+    }
+}
+
+static int is_sample_rate_valid(int rate)
+{
+    int i;
+    for( i = 0; i < hb_audio_rates_count; i++ )
+    {
+            if (rate == hb_audio_rates[i].rate)
+                return 1;
+    }
+    return 0;
+}
Index: libhb/deca52.c
===================================================================
--- libhb/deca52.c	(revision 1364)
+++ libhb/deca52.c	(working copy)
@@ -88,6 +88,7 @@
 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 @@
 	/* 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->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->out.mixdown);
 
     pv->level     = 32768.0;
-    pv->dynamic_range_compression = job->dynamic_range_compression;
+    pv->dynamic_range_compression = audio->out.dynamic_range_compression;
 
     pv->next_expected_pts = 0;
     pv->sequence = 0;
@@ -168,6 +169,7 @@
 {
     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 @@
     }
 
     /* AC3 passthrough: don't decode the AC3 frame */
-    if( pv->job->acodec & HB_ACODEC_AC3 ||
-        w->amixdown == HB_AMIXDOWN_AC3 )
+    if( audio->out.codec == HB_ACODEC_AC3 )
     {
         buf = hb_buffer_init( pv->size );
         memcpy( buf->data, pv->frame, pv->size );
Index: libhb/enclame.c
===================================================================
--- libhb/enclame.c	(revision 1364)
+++ libhb/enclame.c	(working copy)
@@ -39,6 +39,7 @@
 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 @@
     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->out.bitrate );
+    lame_set_in_samplerate( pv->lame, audio->out.samplerate );
+    lame_set_out_samplerate( pv->lame, audio->out.samplerate );
     lame_init_params( pv->lame );
 
     pv->input_samples = 1152 * 2;
@@ -85,6 +86,7 @@
 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 @@
     }
 
     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->out.samplerate;
+    buf->stop  = buf->start + 90000 * 1152 / audio->out.samplerate;
     buf->size  = lame_encode_buffer_interleaved( pv->lame, samples_s16,
             1152, buf->data, LAME_MAXMP3BUFFER );
     buf->frametype   = HB_FRAME_AUDIO;
Index: libhb/muxavi.c
===================================================================
--- libhb/muxavi.c	(revision 1364)
+++ libhb/muxavi.c	(working copy)
@@ -281,7 +281,7 @@
     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,6 +346,8 @@
     {
         audio = hb_list_item( title->list_audio, i );
 
+        is_ac3 = (audio->out.codec == HB_ACODEC_AC3);
+
         mux_data = calloc( sizeof( hb_mux_data_t ), 1 );
         audio->mux_data = mux_data;
 
@@ -358,8 +360,8 @@
         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->in.bitrate / 8 ) :
+                                   ( audio->out.bitrate * 1000 / 8 );
         h.Quality       = 0xFFFFFFFF;
         h.SampleSize    = 1;
 
@@ -369,16 +371,16 @@
         {
             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->in.channel_layout);
+            f.SamplesPerSec  = audio->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->out.mixdown);
+            f.SamplesPerSec  = audio->out.samplerate;
         }
         f.AvgBytesPerSec = h.Rate;
         f.BlockAlign     = 1;
@@ -391,7 +393,7 @@
             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->out.samplerate;
             m.FramesPerBlock = 1;
             m.CodecDelay     = 1393;
         }
@@ -513,7 +515,7 @@
     {
         audio = hb_list_item( title->list_audio, i );
         fseek( m->file, 264 + i *
-               ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 :
+               ( 102 + ( ( audio->out.codec == HB_ACODEC_AC3 ) ? 0 :
                  sizeof( hb_wave_mp3_t ) ) ), SEEK_SET );
         WriteInt32( m->file, audio->mux_data->header.Length );
     }
Index: libhb/dvd.c
===================================================================
--- libhb/dvd.c	(revision 1364)
+++ libhb/dvd.c	(working copy)
@@ -257,28 +257,28 @@
         {
             case 0x00:
                 audio->id    = ( ( 0x80 + position ) << 8 ) | 0xbd;
-                audio->codec = HB_ACODEC_AC3;
+                audio->in.codec = HB_ACODEC_AC3;
                 break;
 
             case 0x02:
             case 0x03:
                 audio->id    = 0xc0 + position;
-                audio->codec = HB_ACODEC_MPGA;
+                audio->in.codec = HB_ACODEC_MPGA;
                 break;
 
             case 0x04:
                 audio->id    = ( ( 0xa0 + position ) << 8 ) | 0xbd;
-                audio->codec = HB_ACODEC_LPCM;
+                audio->in.codec = HB_ACODEC_LPCM;
                 break;
 
             case 0x06:
                 audio->id    = ( ( 0x88 + position ) << 8 ) | 0xbd;
-                audio->codec = HB_ACODEC_DCA;
+                audio->in.codec = HB_ACODEC_DCA;
                 break;
 
             default:
                 audio->id    = 0;
-                audio->codec = 0;
+                audio->in.codec = 0;
                 hb_log( "scan: unknown audio codec (%x)",
                         audio_format );
                 break;
@@ -308,18 +308,18 @@
 
         lang = lang_for_code( vts->vtsi_mat->vts_audio_attr[i].lang_code );
 
-        snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)",
+        snprintf( audio->lang.description, sizeof( audio->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->in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->in.codec ==
+                HB_ACODEC_DCA ? "DTS" : ( audio->in.codec ==
                 HB_ACODEC_MPGA ? "MPEG" : "LPCM" ) ) );
-        snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s",
+        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",
+        snprintf( audio->lang.iso639_2, sizeof( audio->lang.iso639_2 ), "%s",
                   lang->iso639_2);
 
         hb_log( "scan: id=%x, lang=%s, 3cc=%s", audio->id,
-                audio->lang, audio->iso639_2 );
+                audio->lang.description, audio->lang.iso639_2 );
 
         hb_list_add( title->list_audio, audio );
     }
Index: libhb/hb.c
===================================================================
--- libhb/hb.c	(revision 1364)
+++ libhb/hb.c	(working copy)
@@ -834,7 +834,7 @@
     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,18 +859,12 @@
     /* 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 )
+            if( ( audio = hb_list_item( job->list_audio, i ) ) )
             {
-                break;
+                hb_list_add( title_copy->list_audio, hb_audio_copy(audio) );
             }
-            if( ( audio = hb_list_item( title->list_audio, job->audios[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 );
-            }
         }
     }
 
@@ -900,17 +894,13 @@
         /*
          * 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 )
+            if( ( audio = hb_list_item( job->list_audio, i ) ) )
             {
+                strncpy(audio_lang, audio->lang.iso639_2, sizeof(audio_lang));
                 break;
             }
-            if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
-            {
-                strncpy(audio_lang, audio->iso639_2, sizeof(audio_lang));
-                break;
-            }
         }
 
         /*
@@ -1035,6 +1025,7 @@
     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: libhb/muxmp4.c
===================================================================
--- libhb/muxmp4.c	(revision 1364)
+++ libhb/muxmp4.c	(working copy)
@@ -27,6 +27,11 @@
     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 @@
     /* 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->out.samplerate;
+    audio = NULL;
 
     /* Create an empty mp4 file */
     if (job->largeFileSize)
@@ -166,7 +175,7 @@
        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 @@
             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 @@
             *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)
@@ -263,12 +272,11 @@
         mux_data = malloc( sizeof( hb_mux_data_t ) );
         audio->mux_data = mux_data;
 
-        if( job->acodec & HB_ACODEC_AC3 ||
-            job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+        if( audio->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 @@
         } 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",
@@ -288,15 +296,15 @@
                 audio->config.aac.bytes, audio->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->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->lang.iso639_2[0] - 0x60;   language_code <<= 5;
+        language_code |= audio->lang.iso639_2[1] - 0x60;  language_code <<= 5;
+        language_code |= audio->lang.iso639_2[2] - 0x60;
         MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.mdhd.language", language_code);
 
 
@@ -372,7 +380,7 @@
 
             if ( job->areBframes )
             {
-                duration += buf->renderOffset * job->arate / 90000;
+                duration += buf->renderOffset * m->samplerate / 90000;
             }
 
             sample = MP4GenerateChapterSample( m, duration );
@@ -396,8 +404,8 @@
         /* 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 @@
                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 @@
                          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: libhb/stream.c
===================================================================
--- libhb/stream.c	(revision 1364)
+++ libhb/stream.c	(working copy)
@@ -340,7 +340,7 @@
     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 @@
         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->in.codec)
                 hb_list_add( aTitle->list_audio, audio );
             else
             {
@@ -773,7 +773,7 @@
         if (buf[3] == 0xbd)
         {
             audio->id = 0x80bd | (aud_pid_index << 8);
-            audio->codec = HB_ACODEC_AC3;
+            audio->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 @@
         else if ((buf[3] & 0xe0) == 0xc0)
         {
             audio->id = buf[3] | aud_pid_index;
-            audio->codec = HB_ACODEC_MPGA;
+            audio->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 @@
         }
     }
     fseeko(stream->file_handle, cur_pos, SEEK_SET);
-    if (! audio->codec)
+    if (! audio->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 @@
     switch ( id >> 12 )
     {
         case 0x0:
-            audio->codec = HB_ACODEC_MPGA;
+            audio->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 @@
             free( audio );
             return;
         case 0x8:
-            audio->codec = HB_ACODEC_AC3;
+            audio->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->in.codec = HB_ACODEC_LPCM;
             hb_log("add_audio_to_title: added LPCM audio stream 0x%x", id);
             break;
         default:
@@ -913,12 +913,12 @@
         }
 
 		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->in.samplerate)
+            audio->in.samplerate = stream->a52_info[i].rate;
+        if (!audio->in.bitrate)
+            audio->in.bitrate = stream->a52_info[i].bitrate;
+        if (!audio->config.a52.ac3flags)
+            audio->config.a52.ac3flags = audio->flags.ac3 = stream->a52_info[i].flags;
 
 	}
     else
@@ -927,74 +927,74 @@
         lang = lang_for_code(0x0000);
     }
 
-	if (!audio->input_channel_layout)
+	if (!audio->in.channel_layout)
 	{
-		switch( audio->ac3flags & A52_CHANNEL_MASK )
+		switch( audio->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->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->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->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->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->in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
 				break;
 			/* other inputs */
 			case A52_3F:
-				audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+				audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
 				break;
 			case A52_2F1R:
-				audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+				audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
 				break;
 			case A52_2F2R:
-				audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+				audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
 				break;
 			/* unknown */
 			default:
-				audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+				audio->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->flags.ac3 & A52_LFE)
 		{
-			audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
+			audio->in.channel_layout = audio->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->lang.description, sizeof( audio->lang.description ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,
+	  audio->in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->in.codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->in.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->lang.iso639_2, sizeof( audio->lang.iso639_2 ), "%s", lang->iso639_2);
 
-	if ( (audio->ac3flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
-		sprintf( audio->lang + strlen( audio->lang ),
+	if ( (audio->flags.ac3 & A52_CHANNEL_MASK) == A52_DOLBY ) {
+        sprintf( audio->lang.description + strlen( audio->lang.description ),
 			 " (Dolby Surround)" );
 	} else {
-		sprintf( audio->lang + strlen( audio->lang ),
+        sprintf( audio->lang.description + strlen( audio->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->in.channel_layout) +
+			HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->in.channel_layout),
+			HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->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->lang.description, audio->in.samplerate,
+            audio->in.bitrate, audio->flags.ac3 );
 
 }
 
@@ -1879,7 +1879,7 @@
             // 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 @@
                 // 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 @@
 				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: libhb/decdca.c
===================================================================
--- libhb/decdca.c	(revision 1364)
+++ libhb/decdca.c	(working copy)
@@ -61,6 +61,7 @@
 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 @@
 	/* 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->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->out.mixdown);
 
     pv->level     = 32768.0;
 
Index: libhb/muxogm.c
===================================================================
--- libhb/muxogm.c	(revision 1364)
+++ libhb/muxogm.c	(working copy)
@@ -135,7 +135,7 @@
     {
         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->out.codec;
         mux_data->i_packet_no = 0;
         audio->mux_data       = mux_data;
         ogg_stream_init( &mux_data->os, i + 1 );
@@ -202,7 +202,7 @@
         audio   = hb_list_item( title->list_audio, i );
         mux_data = audio->mux_data;
         memset( &h, 0, sizeof( ogg_stream_header_t ) );
-        switch( job->acodec )
+        switch( audio->out.codec )
         {
             case HB_ACODEC_LAME:
             {
@@ -212,7 +212,7 @@
 
                 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->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 @@
                 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->out.bitrate / 8 );
 
                 op.packet   = (unsigned char*) &h;
                 op.bytes    = sizeof( ogg_stream_header_t );
@@ -275,7 +275,7 @@
     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->out.codec == HB_ACODEC_VORBIS )
         {
             int       j;
             mux_data = audio->mux_data;
Index: libhb/sync.c
===================================================================
--- libhb/sync.c	(revision 1364)
+++ libhb/sync.c	(working copy)
@@ -130,6 +130,7 @@
     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 @@
                               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->out.codec == HB_ACODEC_AC3 )
         {
             free( pv->sync_audio[i].ac3_buf );
         }
@@ -207,8 +208,7 @@
     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->out.codec == HB_ACODEC_AC3 )
     {
         /* Have a silent AC-3 frame ready in case we have to fill a
            gap */
@@ -219,9 +219,9 @@
         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->in.bitrate;
+        c->sample_rate = sync->audio->in.samplerate;
+        c->channels    = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( sync->audio->in.channel_layout );
 
         if( avcodec_open( c, codec ) < 0 )
         {
@@ -231,8 +231,8 @@
 
         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->in.bitrate * AC3_SAMPLES_PER_FRAME /
+                             sync->audio->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 @@
     {
         /* 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->out.mixdown), &error );
         sync->data.end_of_input = 0;
     }
 }
@@ -432,9 +432,9 @@
                              * 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 @@
 {
     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->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->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->out.codec == HB_ACODEC_AC3 ||
+        audio->out.codec == HB_ACODEC_DCA )
     {
         /*
          * If we don't have to do sample rate conversion or this audio is AC3
@@ -586,11 +586,11 @@
         /* 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->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->out.samplerate / 90000;
 
         sync->data.input_frames = count_in;
         sync->data.output_frames = count_out;
@@ -630,16 +630,15 @@
     hb_fifo_t       * fifo;
     int               rate;
 
-    if( job->acodec & HB_ACODEC_AC3 ||
-        job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+    if( audio->out.codec == HB_ACODEC_AC3 )
     {
         fifo = audio->fifo_out;
-        rate = audio->rate;
+        rate = audio->in.samplerate;
     }
     else
     {
         fifo = audio->fifo_sync;
-        rate = job->arate;
+        rate = audio->out.samplerate;
     }
 
     while( !hb_fifo_is_full( fifo ) && ( buf = hb_fifo_see( audio->fifo_raw ) ) )
@@ -717,7 +716,7 @@
 
     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->out.samplerate );
     }
 }
 
@@ -759,7 +758,7 @@
     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->out.codec == HB_ACODEC_AC3 )
     {
         buf        = hb_buffer_init( sync->ac3_size );
         buf->start = sync->next_pts;
@@ -770,7 +769,7 @@
     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->out.mixdown) );
         buf->start = sync->next_pts;
         buf->stop  = buf->start + duration;
         memset( buf->data, 0, buf->size );
Index: libhb/encfaac.c
===================================================================
--- libhb/encfaac.c	(revision 1364)
+++ libhb/encfaac.c	(working copy)
@@ -45,6 +45,7 @@
 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 @@
     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->out.mixdown);
 
-    pv->faac = faacEncOpen( job->arate, pv->out_discrete_channels, &pv->input_samples,
+    pv->faac = faacEncOpen( audio->out.samplerate, pv->out_discrete_channels, &pv->input_samples,
                            &pv->output_bytes );
     pv->buf  = malloc( pv->input_samples * sizeof( float ) );
 
@@ -74,12 +75,12 @@
 	}
 
     cfg->useTns        = 0;
-    cfg->bitRate       = job->abitrate * 1000 / pv->out_discrete_channels; /* Per channel */
+    cfg->bitRate       = audio->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->out.mixdown == HB_AMIXDOWN_6CH && audio->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 @@
 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 @@
                       &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->out.samplerate;
+    buf->stop  = buf->start + 90000 * pv->input_samples / audio->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: libhb/work.c
===================================================================
--- libhb/work.c	(revision 1364)
+++ libhb/work.c	(working copy)
@@ -337,57 +337,53 @@
         }
     }
 
-    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->out.codec == HB_ACODEC_AC3 ) && ( audio->in.codec != HB_ACODEC_AC3 ) ) ||
+            ( ( audio->out.codec == HB_ACODEC_DCA ) && ( audio->in.codec != HB_ACODEC_DCA ) ) )
         {
+            hb_log( "Passthru requested and input codec is not the same as output codec for track %d", audio->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->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->out.track );
+        if( (audio->out.codec == HB_ACODEC_AC3) || (audio->out.codec == HB_ACODEC_DCA) )
+        {
+            hb_log( "   + %s passthrough", (audio->out.codec == HB_ACODEC_AC3) ?
+                "AC3" : "DCA" );
+        }
+        else
+        {
+            hb_log( "   + audio %d kbps, %d Hz", audio->out.bitrate, audio->out.samplerate );
+            hb_log( "   + encoder %s", ( audio->out.codec == HB_ACODEC_FAAC ) ?
+            "faac" : ( ( audio->out.codec == HB_ACODEC_LAME ) ? "lame" :
+            "vorbis" ) );
+            if ( audio->out.dynamic_range_compression > 1 )
+                hb_log("   + dynamic range compression: %f", audio->out.dynamic_range_compression);
+        }
 
+        hb_log( "     + %x, %s", audio->id, audio->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->out.mixdown) {
+				hb_log( "       + Requested mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
 				break;
 			}
 		}
@@ -396,33 +392,22 @@
 
         /* 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->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA) &&
+            (audio->out.codec == HB_ACODEC_FAAC || audio->out.codec == HB_ACODEC_VORBIS) );
+        int audioCodecsSupport6Ch =  ( (audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA) &&
+            (audio->out.codec == HB_ACODEC_FAAC || audio->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->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->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
+                    audio->out.mixdown = HB_AMIXDOWN_MONO;
                 } else {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+                    audio->out.mixdown = HB_AMIXDOWN_STEREO;
                 }
                 break;
 
@@ -430,11 +415,11 @@
             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->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->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->out.mixdown > HB_AMIXDOWN_STEREO) {
+                    audio->out.mixdown = HB_AMIXDOWN_STEREO;
                 }
                 break;
 
@@ -444,12 +429,12 @@
             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->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->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->out.mixdown > HB_AMIXDOWN_DOLBY) {
+                    audio->out.mixdown = HB_AMIXDOWN_DOLBY;
                 }
                 break;
 
@@ -457,21 +442,21 @@
             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->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->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->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->out.mixdown == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {
+                            audio->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->out.mixdown > HB_AMIXDOWN_DOLBYPLII) {
+                            audio->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
                         }
                     }
                 }
@@ -482,13 +467,13 @@
             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->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+                    audio->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->out.mixdown > HB_AMIXDOWN_DOLBY) {
+                        audio->out.mixdown = HB_AMIXDOWN_DOLBY;
                     }
                 }
                 /* all other mixdowns will have been preserved here */
@@ -496,30 +481,26 @@
 
             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->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
+                    audio->out.mixdown = HB_AMIXDOWN_MONO;
                 /* mix everything else down to stereo */
                 } else {
-                    job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+                    audio->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->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];
+        if (audio->out.codec == HB_ACODEC_VORBIS)
+            audio->config.vorbis.language = audio->lang.simple;
 
-        audio->config.vorbis.language = audio->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 );
@@ -530,7 +511,7 @@
         /*
          * Audio Decoder Thread
          */
-        switch( audio->codec )
+        switch( audio->in.codec )
         {
             case HB_ACODEC_AC3:
                 w = getWork( WORK_DECA52 );
@@ -544,12 +525,16 @@
             case HB_ACODEC_LPCM:
                 w = getWork( WORK_DECLPCM );
                 break;
+            default:
+                /* Invalid input codec */
+                hb_error("Invalid input codec: %d", audio->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->audio         = audio;
 
         /* FIXME: This feels really hackish, anything better? */
         audio_w = calloc( sizeof( hb_work_object_t ), 1 );
@@ -560,10 +545,8 @@
         /*
          * Audio Encoder Thread
          */
-        if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )
+        switch( audio->out.codec )
         {
-            switch( job->acodec )
-            {
             case HB_ACODEC_FAAC:
                 w = getWork( WORK_ENCFAAC );
                 break;
@@ -573,11 +556,17 @@
             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: %d", audio->out.codec);
+                w = NULL;
+                *job->die = 1;
+                goto cleanup;
         }
 
-        if( job->acodec != HB_ACODEC_AC3 &&
-            job->audio_mixdowns[i] != HB_AMIXDOWN_AC3)
+        if( audio->out.codec != HB_ACODEC_AC3 )
         {
             /*
              * Add the encoder thread if not doing AC-3 pass through
@@ -585,8 +574,7 @@
             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->audio         = audio;
 
             /* FIXME: This feels really hackish, anything better? */
             audio_w = calloc( sizeof( hb_work_object_t ), 1 );
@@ -640,12 +628,16 @@
     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 +655,10 @@
     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 +678,14 @@
     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->fifo_in != NULL )
+            hb_fifo_close( &audio->fifo_in );
+        if( audio->fifo_raw != NULL )
+            hb_fifo_close( &audio->fifo_raw );
+        if( audio->fifo_sync != NULL )
+            hb_fifo_close( &audio->fifo_sync );
+        if( audio->fifo_out != NULL )
+            hb_fifo_close( &audio->fifo_out );
     }
 
     if( job->indepth_scan )
Index: libhb/scan.c
===================================================================
--- libhb/scan.c	(revision 1364)
+++ libhb/scan.c	(working copy)
@@ -147,8 +147,8 @@
 			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->in.codec == HB_ACODEC_AC3 &&
+					!audio->in.bitrate )
 				{
 					hb_list_rem( title->list_audio, audio );
 					free( audio );
@@ -162,11 +162,11 @@
         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->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA ) &&
+                !audio->in.bitrate )
             {
                 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
-                    audio->codec );
+                    audio->in.codec );
                 hb_list_rem( title->list_audio, audio );
                 free( audio );
                 continue;
@@ -188,9 +188,9 @@
         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->in.codec == HB_ACODEC_LPCM || audio->in.codec == HB_ACODEC_MPGA )
             {
-                audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
             }
         }
 
@@ -247,13 +247,8 @@
         job->vrate      = title->rate;
         job->vrate_base = title->rate_base;
 
-        job->audios[0] = 0;
-        job->audios[1] = -1;
+        job->list_audio = hb_list_init();
 
-        job->acodec   = HB_ACODEC_FAAC;
-        job->abitrate = 128;
-        job->arate    = 44100;
-
         job->subtitle = -1;
 
         job->mux = HB_MUX_MP4;
@@ -451,14 +446,14 @@
         }
 
         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 @@
     {
         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->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA ) &&
             audio->id    == b->id )
         {
             break;
@@ -599,7 +594,7 @@
         return;
     }
 
-    if( audio->bitrate )
+    if( audio->in.bitrate )
     {
         /* Already done for this track */
         return;
@@ -608,59 +603,59 @@
     for( i = 0; i < b->size - 7; i++ )
     {
 
-        if ( audio->codec == HB_ACODEC_AC3 )
+        if ( audio->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->in.samplerate = rate;
+                audio->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->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->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->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->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->in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
                         break;
                     /* other inputs */
                     case A52_3F:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+                        audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
                         break;
                     case A52_2F1R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+                        audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
                         break;
                     case A52_2F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+                        audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
                         break;
                     /* unknown */
                     default:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                        audio->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->in.channel_layout = audio->in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
                 }
 
                 /* store the AC3 flags for future reference
@@ -668,18 +663,18 @@
                 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;
+                audio->flags.ac3 = audio->config.a52.ac3flags;
 
                 /* XXX */
                 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->lang.description + strlen( audio->lang.description ),
                          " (Dolby Surround)" );
                 } else {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->lang.description + strlen( audio->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->in.channel_layout) +
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->in.channel_layout),
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->in.channel_layout));
                 }
 
                 break;
@@ -687,7 +682,7 @@
             }
 
         }
-        else if ( audio->codec == HB_ACODEC_DCA )
+        else if ( audio->in.codec == HB_ACODEC_DCA )
         {
 
             hb_log( "scan: checking for DCA syncinfo" );
@@ -697,51 +692,51 @@
             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->in.samplerate    = rate;
+                audio->in.bitrate = bitrate;
                 switch( flags & DCA_CHANNEL_MASK )
                 {
                     /* mono sources */
                     case DCA_MONO:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
+                        audio->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->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->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->in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
                         break;
                     /* other inputs */
                     case DCA_3F:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+                        audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
                         break;
                     case DCA_2F1R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+                        audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
                         break;
                     case DCA_2F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+                        audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
                         break;
                     case DCA_4F2R:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
+                        audio->in.channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
                         break;
                     /* unknown */
                     default:
-                        audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+                        audio->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->in.channel_layout = audio->in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
                 }
 
                 /* store the DCA flags for future reference
@@ -749,18 +744,18 @@
                 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;
+                audio->flags.dca = audio->config.dca.dcaflags;
 
                 /* XXX */
                 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->lang.description + strlen( audio->lang.description ),
                          " (Dolby Surround)" );
                 } else {
-                    sprintf( audio->lang + strlen( audio->lang ),
+                    sprintf( audio->lang.description + strlen( audio->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->in.channel_layout) +
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->in.channel_layout),
+                        HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->in.channel_layout));
                 }
 
                 break;
@@ -778,8 +773,8 @@
     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->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA ) &&
+            !audio->in.bitrate )
         {
             return 0;
         }
Index: libhb/muxmkv.c
===================================================================
--- libhb/muxmkv.c	(revision 1364)
+++ libhb/muxmkv.c	(working copy)
@@ -29,6 +29,7 @@
     mk_Track  * track;
     uint64_t  prev_chapter_tc;
     uint16_t  current_chapter;
+    int       codec;
 };
 
 /**********************************************************************
@@ -160,7 +161,9 @@
         mux_data = malloc( sizeof( hb_mux_data_t ) );
         audio->mux_data = mux_data;
 
-        switch (job->acodec)
+        mux_data->codec = audio->out.codec;
+
+        switch (audio->out.codec)
         {
             case HB_ACODEC_AC3:
                 track->codecPrivate = NULL;
@@ -195,22 +198,13 @@
                 }
                 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->config.aac.bytes;
+                track->codecPrivateSize = audio->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->out.codec);
                 return 0;
         }
 
@@ -221,12 +215,12 @@
         }
         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->lang.iso639_2;
+        track->extra.audio.samplingFreq = (float)audio->out.samplerate;
+        track->extra.audio.channels = (audio->out.codec == HB_ACODEC_AC3 ) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->in.channel_layout) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->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->out.codec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)
           free(track->codecPrivate);
     }
 
@@ -308,7 +302,7 @@
     {
         /* 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: libhb/common.c
===================================================================
--- libhb/common.c	(revision 1364)
+++ libhb/common.c	(working copy)
@@ -43,9 +43,7 @@
   { "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 +113,7 @@
     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 +200,6 @@
             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 +213,37 @@
     /* 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->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->out.codec == HB_ACODEC_AC3 ||
+            audio->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->in.bitrate / 8;
         }
         else
         {
@@ -252,12 +251,12 @@
              * Where we are transcoding the audio we use the destination
              * bitrate.
              */
-            abitrate = job->abitrate * 1000 / 8;
+            abitrate = audio->out.bitrate * 1000 / 8;
         }
         avail -= length * abitrate;
 
         /* Audio overhead */
-        avail -= length * job->arate * overhead / samples_per_frame;
+        avail -= length * audio->out.samplerate * overhead / samples_per_frame;
     }
 
     if( avail < 0 )
@@ -654,3 +653,33 @@
     *_f = NULL;
 }
 
+/**********************************************************************
+ * hb_audio_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_audio_t *hb_audio_copy(const hb_audio_t *src)
+{
+    hb_audio_t *audio = hb_audio_new();
+    memcpy(audio, src, sizeof(*audio));
+    return audio;
+}
+
+/**********************************************************************
+ * hb_audio_new
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_audio_t *hb_audio_new(void)
+{
+    hb_audio_t *audio = calloc(1, sizeof(*audio));
+    /* Initalize some sensable defaults */
+    audio->in.codec = 0;
+    audio->out.codec = HB_ACODEC_FAAC;
+    audio->out.bitrate = 128;
+    audio->out.samplerate = 44100;
+    audio->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
+    audio->out.dynamic_range_compression = 0;
+
+    return audio;
+}
Index: libhb/encvorbis.c
===================================================================
--- libhb/encvorbis.c	(revision 1364)
+++ libhb/encvorbis.c	(working copy)
@@ -44,13 +44,14 @@
 
 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->out.mixdown);
 
     pv->job   = job;
 
@@ -58,17 +59,18 @@
 
     /* 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->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->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->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->out.samplerate, -1, 1000 * audio->out.bitrate, -1 ) )
     {
         hb_error( "encvorbis: vorbis_encode_setup_managed failed.\n" );
         *job->die = 1;
@@ -80,7 +82,7 @@
         hb_log( "encvorbis: vorbis_encode_ctl( ratemanage2_get ) failed" );
     }
 
-    ctl_rate_arg.bitrate_average_kbps = job->abitrate;
+    ctl_rate_arg.bitrate_average_kbps = audio->out.bitrate;
     ctl_rate_arg.management_active = 1;
 
     if( vorbis_encode_ctl( &pv->vi, OV_ECTL_RATEMANAGE2_SET, &ctl_rate_arg ) ||
Index: libhb/common.h
===================================================================
--- libhb/common.h	(revision 1364)
+++ libhb/common.h	(working copy)
@@ -70,6 +70,9 @@
 
 int hb_calc_bitrate( hb_job_t *, int size );
 
+hb_audio_t *hb_audio_copy(const hb_audio_t *src);
+hb_audio_t *hb_audio_new();
+
 struct hb_rate_s
 {
     char * string;
@@ -175,77 +178,9 @@
     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[] */
+    /* List of audio settings. */
+    hb_list_t     * list_audio;
 
-/* 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;
-
     /* Subtitle settings:
          subtitle: index in hb_title_t's subtitles list, starting
          from 0. -1 means no subtitle */
@@ -300,22 +235,38 @@
 #endif
 };
 
-struct hb_audio_s
-{
-    int  id;
-    char lang[1024];
-    char lang_simple[1024];
-    char iso639_2[4];
-    int  codec;
-    int  rate;
-    int  bitrate;
+/* 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 ) )
 
-    /* ac3flags is only set when the source audio format is HB_ACODEC_AC3 */
-    int ac3flags;
-
-    /* dcaflags is only set when the source audio format is HB_ACODEC_DCA */
-    int dcaflags;
-
+/* 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 +274,6 @@
 #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 +285,6 @@
 #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,12 +293,64 @@
 #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_s
+{
+#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
 
+    /* Input */
+    struct
+    {
+        int track;      /* Input track number */
+        uint32_t codec;      /* Input audio codec */
+        int samplerate; /* Input sample rate (Hz) */
+        int bitrate;    /* Input bitrate (kbps) */
+        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;
+
+    /* 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;
+
+    /* Misc. */
+    union
+    {
+        int ac3;    /* flags.ac3 is only set when the source audio format is HB_ACODEC_AC3 */
+        int dca;    /* flags.dca is only set when the source audio format is HB_ACODEC_DCA */
+    } flags;
+
+    struct
+    {
+        char description[1024];
+        char simple[1024];
+        char iso639_2[4];
+    } lang;
+
 #ifdef __LIBHB__
     /* Internal data */
+    /* Input */
+    int  id;
+
+    /* Misc. */
     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 */
@@ -357,9 +358,6 @@
 
     hb_esconfig_t config;
     hb_mux_data_t * mux_data;
-
-	/* amixdown is the mixdown format to be used for this audio track */
-   	int amixdown;
 #endif
 };
 
@@ -506,10 +504,8 @@
     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: macosx/Controller.mm
===================================================================
--- macosx/Controller.mm	(revision 1364)
+++ macosx/Controller.mm	(working copy)
@@ -81,7 +81,7 @@
     
     outputPanel = [[HBOutputPanelController alloc] init];
     fPictureController = [[PictureController alloc] initWithDelegate:self];
-    fQueueController = [[HBQueueController alloc] init];
+   //*DISABLE QUEUE* fQueueController = [[HBQueueController alloc] init];
     fAdvancedOptions = [[HBAdvancedController alloc] init];
     /* we init the HBPresets class which currently is only used
     * for updating built in presets, may move more functionality
@@ -1467,8 +1467,8 @@
     hb_title_t * title = (hb_title_t *) hb_list_item( list,
             [fSrcTitlePopUp indexOfSelectedItem] );
     hb_job_t * job = title->job;
-    //int i;
-
+    hb_audio_t *audio;
+    
     /* Chapter selection */
     job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
     job->chapter_end   = [fSrcChapterEndPopUp   indexOfSelectedItem] + 1;
@@ -1478,7 +1478,8 @@
     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
     job->mux    = FormatSettings[format][codecs] & HB_MUX_MASK;
     job->vcodec = FormatSettings[format][codecs] & HB_VCODEC_MASK;
-    job->acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+    
+
     /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
 	if ([fDstFormatPopUp indexOfSelectedItem] == 0)
 	{
@@ -1594,67 +1595,78 @@
     job->subtitle = [fSubPopUp indexOfSelectedItem] - 2;
 
     /* Audio tracks and mixdowns */
-    /* check for the condition where track 2 has an audio selected, but track 1 does not */
-    /* we will use track 2 as track 1 in this scenario */
-    if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+    /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/
+    int num_audio_tracks = hb_list_count(job->list_audio);
+    for( int i = 0; i < num_audio_tracks;i++)
     {
-        job->audios[0] = [fAudLang1PopUp indexOfSelectedItem] - 1;
-        job->audios[1] = [fAudLang2PopUp indexOfSelectedItem] - 1; /* will be -1 if "none" is selected */
-        job->audios[2] = -1;
-        job->audio_mixdowns[0] = [[fAudTrack1MixPopUp selectedItem] tag];
-        job->audio_mixdowns[1] = [[fAudTrack2MixPopUp selectedItem] tag];
+        audio = hb_audio_copy( (hb_audio_t *) hb_list_item( job->list_audio, i ) );
+        hb_list_rem(job->list_audio, audio); // issue, this give us a memory crash ... FIX ME!!!
     }
-    else if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+    /* Now lets add our new tracks to the audio list here */
+    if ([fAudLang1PopUp indexOfSelectedItem] > 0)
     {
-        job->audios[0] = [fAudLang2PopUp indexOfSelectedItem] - 1;
-        job->audio_mixdowns[0] = [[fAudTrack2MixPopUp selectedItem] tag];
-        job->audios[1] = -1;
+        /* First we copy the source audio structure (remember, in the popup 0 is "None" so we subtract 1 to match the list->audio*/
+        audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang1PopUp indexOfSelectedItem] - 1 ) );
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK; 
+        audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+        audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack1MixPopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+        /* We add the newly modified audio track to job->list_audio */
+        hb_list_add(job->list_audio, audio );
+        
+        /*HACK: We use the format and codecs popups to determine if we should slide in the extra ac3 passthru track for the atv hybrid mp4 */
+        if (format == 0 && codecs == 2 && audio->in.codec != HB_ACODEC_DCA) // if mp4 and aac + ac3 and input is NOT DTS (dts cannot be passed through as ac3)
+        {
+            audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang1PopUp indexOfSelectedItem] - 1 ) );
+            /* We go ahead and assign values to our audio->out.<properties> */
+            audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+            audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+            audio->out.codec = audio->in.codec; // <-- HB_ACODEC_AC3
+            audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+            audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+            audio->out.mixdown = HB_ACODEC_AC3;//<-- Lets manually set the mixdown int 
+            audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+            /* We add the newly modified audio track to job->list_audio */
+            hb_list_add(job->list_audio, audio );
+        }
+        
     }
-    else
+    if ([fAudLang2PopUp indexOfSelectedItem] > 0)
     {
-        job->audios[0] = -1;
+        /* First we copy the source audio structure (remember, in the popup 0 is "None" so we subtract 1 to match the list->audio*/
+        audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang2PopUp indexOfSelectedItem] - 1 ) );
+        /* Now we modify it according to the gui settings for the specified track number */
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+        audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+        audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack2MixPopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+        /* We add the newly modified audio track to job->list_audio */
+        hb_list_add(job->list_audio, audio );
+        
+        /*HACK: We use the format and codecs popups to determine if we should slide in the extra ac3 passthru track for the atv hybrid mp4 */
+        if (format == 0 && codecs == 2 && audio->in.codec != HB_ACODEC_DCA) // if mp4 and aac + ac3 and input is NOT DTS (dts cannot be passed through as ac3)
+        {
+            audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang2PopUp indexOfSelectedItem] - 1 ) );
+            /* We go ahead and assign values to our audio->out.<properties> */
+            audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+            audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+            audio->out.codec = audio->in.codec; // <-- HB_ACODEC_AC3
+            audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+            audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+            audio->out.mixdown = HB_ACODEC_AC3;//<-- Lets manually input the mixdown int 
+            audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+            /* We add the newly modified audio track to job->list_audio */
+            hb_list_add(job->list_audio, audio );
+        }
     }
 
-    /*
-     * Where one or more of the audio tracks has a mixdown of DPLII+AC3 we need to create an extra
-     * track for each.
-     */
-    if (job->audio_mixdowns[0] == HB_AMIXDOWN_DOLBYPLII_AC3)
-    {
-        /*
-         * Make space for the AC3 track by moving 1 to 2
-         */
-        job->audios[2] = job->audios[1];
-        job->audio_mixdowns[2] = job->audio_mixdowns[1];
-        job->audios[1] = job->audios[0];
-        job->audio_mixdowns[0] = HB_AMIXDOWN_DOLBYPLII;
-        job->audio_mixdowns[1] = HB_AMIXDOWN_AC3;
-    }
-
-    if (job->audio_mixdowns[1] == HB_AMIXDOWN_DOLBYPLII_AC3)
-    {
-        job->audios[2] = job->audios[1];
-        job->audio_mixdowns[1] = HB_AMIXDOWN_DOLBYPLII;
-        job->audio_mixdowns[2] = HB_AMIXDOWN_AC3;
-        job->audios[3] = -1;
-    }
-
-    if (job->audio_mixdowns[2] == HB_AMIXDOWN_DOLBYPLII_AC3)
-    {
-        job->audios[3] = job->audios[2];
-        job->audio_mixdowns[2] = HB_AMIXDOWN_DOLBYPLII;
-        job->audio_mixdowns[3] = HB_AMIXDOWN_AC3;
-        job->audios[4] = -1;
-    }
-
-    /* Audio settings */
-    job->arate = hb_audio_rates[[fAudRatePopUp
-                     indexOfSelectedItem]].rate;
-    job->abitrate = [[fAudBitratePopUp selectedItem] tag];
     
-    /* Dynamic Range Compression */
-    job->dynamic_range_compression = [fAudDrcField floatValue];
-    
     /* set vfr according to the Picture Window */
     if ([fPictureController vfr])
     {
@@ -1785,16 +1797,16 @@
 
     // Create a Queue Controller job group. Each job that we submit to libhb will also
     // get added to the job group so that the queue can track the jobs.
-    HBJobGroup * jobGroup = [HBJobGroup jobGroup];
+   //*DISABLE QUEUE* HBJobGroup * jobGroup = [HBJobGroup jobGroup];
     // The job group can maintain meta data that libhb can not...
-    [jobGroup setPresetName: [fPresetSelectedDisplay stringValue]];
+   //*DISABLE QUEUE* [jobGroup setPresetName: [fPresetSelectedDisplay stringValue]];
 
     // Job groups require that each job within the group be assigned a unique id so
     // that the queue can xref between itself and the private jobs that libhb
     // maintains. The ID is composed a group id number and a "sequence" number. libhb
     // does not use this id.
-    static int jobGroupID = 0;
-    jobGroupID++;
+   //*DISABLE QUEUE* static int jobGroupID = 0;
+   //*DISABLE QUEUE* jobGroupID++;
     
     // A sequence number, starting at zero, is used to identifiy to each pass. This is
     // used by the queue UI to determine if a pass if the first pass of an encode.
@@ -1835,9 +1847,9 @@
         /*
         * Add the pre-scan job
         */
-        job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+     //*DISABLE QUEUE*   job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
         hb_add( fHandle, job );
-        [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
+     //*DISABLE QUEUE*   [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
 
         job->x264opts = x264opts_tmp;
     }
@@ -1861,12 +1873,12 @@
         job->select_subtitle = NULL;
         
         job->pass = 1;
-        job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+      //*DISABLE QUEUE*  job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
         hb_add( fHandle, job );
-        [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
+     //*DISABLE QUEUE*   [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
 
         job->pass = 2;
-        job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+      //*DISABLE QUEUE*  job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
 
         job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */  
         strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]);
@@ -1874,22 +1886,22 @@
         job->select_subtitle = subtitle_tmp;
 
         hb_add( fHandle, job );
-        [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
+      //*DISABLE QUEUE*  [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
     }
     else
     {
         job->indepth_scan = 0;
         job->pass = 0;
-        job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+    //*DISABLE QUEUE*    job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
         hb_add( fHandle, job );
-        [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
+    //*DISABLE QUEUE*    [jobGroup addJob:[HBJob jobWithLibhbJob:job]];     // add this pass to the job group
     }
 	
     NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
 	[[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
 	
     // Let the queue controller know about the job group
-    [fQueueController addJobGroup:jobGroup];
+   //*DISABLE QUEUE* [fQueueController addJobGroup:jobGroup];
 }
 
 /* Rip: puts up an alert before ultimately calling doRip
@@ -1941,7 +1953,7 @@
         otherwise, just rip the queue */
         if( hb_count( fHandle ) == 0)
         {
-            [self doAddToQueue];
+            [self doAddToQueue];         
         }
 
         NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
@@ -2787,17 +2799,15 @@
 
 - (IBAction) setEnabledStateOfAudioMixdownControls: (id) sender
 {
-
     /* enable/disable the mixdown text and popupbutton for audio track 1 */
-    [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES];
-    [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ?
-        [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
-
-    /* enable/disable the mixdown text and popupbutton for audio track 2 */
-    [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES];
-    [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ?
-        [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
-
+        [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES];
+        [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ?
+         [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
+        
+        /* enable/disable the mixdown text and popupbutton for audio track 2 */
+        [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES];
+        [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ?
+         [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
 }
 
 - (IBAction) addAllAudioTracksToPopUp: (id) sender
@@ -2808,14 +2818,14 @@
         hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
 
 	hb_audio_t * audio;
-
+    
     [sender removeAllItems];
     [sender addItemWithTitle: _( @"None" )];
     for( int i = 0; i < hb_list_count( title->list_audio ); i++ )
     {
-        audio = (hb_audio_t *) hb_list_item( title->list_audio, i );
+        audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, i ) );
         [[sender menu] addItemWithTitle:
-            [NSString stringWithCString: audio->lang]
+            [NSString stringWithCString: audio->lang.description]
             action: NULL keyEquivalent: @""];
     }
     [sender selectItemAtIndex: 0];
@@ -2863,17 +2873,17 @@
 
 - (IBAction) audioTrackPopUpChanged: (id) sender mixdownToUse: (int) mixdownToUse
 {
-
+    
     /* make sure we have a selected title before continuing */
     if (fTitle == NULL) return;
-
+    
     /* find out if audio track 1 or 2 was changed - this is passed to us in the tag of the sender */
     /* the sender will have been either fAudLang1PopUp (tag = 0) or fAudLang2PopUp (tag = 1) */
     int thisAudio = [sender tag];
-
+    
     /* get the index of the selected audio */
     int thisAudioIndex = [sender indexOfSelectedItem] - 1;
-
+    
 #if 0
     /* Handbrake can't currently cope with ripping the same source track twice */
     /* So, if this audio is also selected in the other audio track popup, set that popup's selection to "none" */
@@ -2887,10 +2897,10 @@
         [self audioTrackPopUpChanged: otherAudioPopUp];
     }
 #endif
-
+    
     /* pointer for the hb_audio_s struct we will use later on */
     hb_audio_t * audio;
-
+    
     /* find out what the currently-selected output audio codec is */
     int format = [fDstFormatPopUp indexOfSelectedItem];
     int codecs = [fDstCodecsPopUp indexOfSelectedItem];
@@ -2900,17 +2910,17 @@
     bool mp4AacAc3;
     if (format == 0 && codecs == 2) // if mp4 and aac + ac3
     {
-    mp4AacAc3 = 1;
+        mp4AacAc3 = 1;
     }
     else
     {
-    mp4AacAc3 = 0;
+        mp4AacAc3 = 0;
     }
-
+    
     /* pointer to this track's mixdown NSPopUpButton */
     NSTextField   * mixdownTextField;
     NSPopUpButton * mixdownPopUp;
-
+    
     /* find our mixdown NSTextField and NSPopUpButton */
     if (thisAudio == 0)
     {
@@ -2922,125 +2932,124 @@
         mixdownTextField = fAudTrack2MixLabel;
         mixdownPopUp = fAudTrack2MixPopUp;
     }
-
+    
     /* delete the previous audio mixdown options */
     [mixdownPopUp removeAllItems];
-
+    
     /* check if the audio mixdown controls need their enabled state changing */
     [self setEnabledStateOfAudioMixdownControls: NULL];
-
+    
     if (thisAudioIndex != -1)
     {
-
+        
         /* get the audio */
-        audio = (hb_audio_t *) hb_list_item( fTitle->list_audio, thisAudioIndex );
+        audio = hb_audio_copy( (hb_audio_t *) hb_list_item( fTitle->list_audio, thisAudioIndex ) );// Should "fTitle" be title and be setup ?
         if (audio != NULL)
         {
-
+            
             /* find out if our selected output audio codec supports mono and / or 6ch */
             /* we also check for an input codec of AC3 or DCA,
-               as they are the only libraries able to do the mixdown to mono / conversion to 6-ch */
+             as they are the only libraries able to do the mixdown to mono / conversion to 6-ch */
             /* 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) && acodec == HB_ACODEC_FAAC);
-            int audioCodecsSupport6Ch =  ((audio->codec == HB_ACODEC_AC3 ||
-                audio->codec == HB_ACODEC_DCA) && (acodec == HB_ACODEC_FAAC ||
-                acodec == HB_ACODEC_VORBIS));
-
+             but this may change in the future, so they are separated for flexibility */
+            int audioCodecsSupportMono = ((audio->in.codec == HB_ACODEC_AC3 ||
+                                           audio->in.codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC);
+            int audioCodecsSupport6Ch =  ((audio->in.codec == HB_ACODEC_AC3 ||
+                                           audio->in.codec == HB_ACODEC_DCA) && (acodec == HB_ACODEC_FAAC ||
+                                                                                 acodec == HB_ACODEC_VORBIS));
+            
             /* check for AC-3 passthru */
-            if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
+            if (audio->in.codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
             {
-            
-                    [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: "AC3 Passthru"]
-                        action: NULL keyEquivalent: @""];
+                
+                [[mixdownPopUp menu] addItemWithTitle:
+                 [NSString stringWithCString: "AC3 Passthru"]
+                                               action: NULL keyEquivalent: @""];
             }
             else
             {
-
+                
                 /* add the appropriate audio mixdown menuitems to the popupbutton */
                 /* in each case, we set the new menuitem's tag to be the amixdown value for that mixdown,
-                   so that we can reference the mixdown later */
-
+                 so that we can reference the mixdown later */
+                
                 /* keep a track of the min and max mixdowns we used, so we can select the best match later */
                 int minMixdownUsed = 0;
                 int maxMixdownUsed = 0;
                 
                 /* get the input channel layout without any lfe channels */
-                int layout = audio->input_channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
+                int layout = audio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
 
-                /* do we want to add a mono option? */
-                if (!mp4AacAc3 && audioCodecsSupportMono == 1) {
-                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: hb_audio_mixdowns[0].human_readable_name]
-                        action: NULL keyEquivalent: @""];
-                    [menuItem setTag: hb_audio_mixdowns[0].amixdown];
-                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[0].amixdown;
-                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[0].amixdown);
-                }
-
-                /* do we want to add a stereo option? */
-                /* offer stereo if we have a mono source and non-mono-supporting codecs, as otherwise we won't have a mixdown at all */
-                /* also offer stereo if we have a stereo-or-better source */
-                if (((!mp4AacAc3 || audio->codec == HB_ACODEC_MPGA ||  audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_DCA) && ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO))) {
-                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: hb_audio_mixdowns[1].human_readable_name]
-                        action: NULL keyEquivalent: @""];
-                    [menuItem setTag: hb_audio_mixdowns[1].amixdown];
-                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[1].amixdown;
-                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[1].amixdown);
-                }
-
-                /* do we want to add a dolby surround (DPL1) option? */
-                if (!mp4AacAc3 && (layout == HB_INPUT_CH_LAYOUT_3F1R || layout == HB_INPUT_CH_LAYOUT_3F2R || layout == HB_INPUT_CH_LAYOUT_DOLBY)) {
-                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: hb_audio_mixdowns[2].human_readable_name]
-                        action: NULL keyEquivalent: @""];
-                    [menuItem setTag: hb_audio_mixdowns[2].amixdown];
-                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[2].amixdown;
-                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[2].amixdown);
-                }
-
-                /* do we want to add a dolby pro logic 2 (DPL2) option? */
-                if ((!mp4AacAc3 || audio->codec == HB_ACODEC_DCA) && layout == HB_INPUT_CH_LAYOUT_3F2R) {
-                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: hb_audio_mixdowns[3].human_readable_name]
-                        action: NULL keyEquivalent: @""];
-                    [menuItem setTag: hb_audio_mixdowns[3].amixdown];
-                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[3].amixdown;
-                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[3].amixdown);
-                }
-
-                /* do we want to add a 6-channel discrete option? */
-                if (!mp4AacAc3 && (audioCodecsSupport6Ch == 1 && layout == HB_INPUT_CH_LAYOUT_3F2R && (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE))) {
-                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: hb_audio_mixdowns[4].human_readable_name]
-                        action: NULL keyEquivalent: @""];
-                    [menuItem setTag: hb_audio_mixdowns[4].amixdown];
-                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[4].amixdown;
-                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[4].amixdown);
-                }
-
-                /* do we want to add an AC-3 passthrough option? */
-                if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3) {
-                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: hb_audio_mixdowns[5].human_readable_name]
-                        action: NULL keyEquivalent: @""];
-                    [menuItem setTag: hb_audio_mixdowns[5].amixdown];
-                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[5].amixdown;
-                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
-                }
-
-                /* do we want to add the DPLII+AC3 passthrough option? */
-                if (mp4AacAc3 && audio->codec == HB_ACODEC_AC3) {
-                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
-                        [NSString stringWithCString: hb_audio_mixdowns[6].human_readable_name]
-                        action: NULL keyEquivalent: @""];
-                    [menuItem setTag: hb_audio_mixdowns[6].amixdown];
-                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[6].amixdown;
-                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[6].amixdown);
-                }
+                    /* do we want to add a mono option? */
+                    //if (!mp4AacAc3 && audioCodecsSupportMono == 1)
+                    if (audioCodecsSupportMono == 1) 
+                    {
+                        NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                                                [NSString stringWithCString: hb_audio_mixdowns[0].human_readable_name]
+                                                                              action: NULL keyEquivalent: @""];
+                        [menuItem setTag: hb_audio_mixdowns[0].amixdown];
+                        if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[0].amixdown;
+                        maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[0].amixdown);
+                    }
+                    
+                    /* do we want to add a stereo option? */
+                    /* offer stereo if we have a mono source and non-mono-supporting codecs, as otherwise we won't have a mixdown at all */
+                    /* also offer stereo if we have a stereo-or-better source */
+                    //if (((!mp4AacAc3 || audio->in.codec == HB_ACODEC_MPGA ||  audio->in.codec == HB_ACODEC_LPCM || audio->in.codec == HB_ACODEC_DCA) && ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO))) 
+                    //if (((audio->in.codec == HB_ACODEC_MPGA ||  audio->in.codec == HB_ACODEC_LPCM || audio->in.codec == HB_ACODEC_DCA) && ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO))) 
+                    if ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO)
+                    {
+                        NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                                                [NSString stringWithCString: hb_audio_mixdowns[1].human_readable_name]
+                                                                              action: NULL keyEquivalent: @""];
+                        [menuItem setTag: hb_audio_mixdowns[1].amixdown];
+                        if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[1].amixdown;
+                        maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[1].amixdown);
+                    }
+                    
+                    /* do we want to add a dolby surround (DPL1) option? */
+                    if (layout == HB_INPUT_CH_LAYOUT_3F1R || layout == HB_INPUT_CH_LAYOUT_3F2R || layout == HB_INPUT_CH_LAYOUT_DOLBY)
+                    {
+                        NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                                                [NSString stringWithCString: hb_audio_mixdowns[2].human_readable_name]
+                                                                              action: NULL keyEquivalent: @""];
+                        [menuItem setTag: hb_audio_mixdowns[2].amixdown];
+                        if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[2].amixdown;
+                        maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[2].amixdown);
+                    }
+                    
+                    /* do we want to add a dolby pro logic 2 (DPL2) option? */
+                    if (layout == HB_INPUT_CH_LAYOUT_3F2R) 
+                    {
+                        NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                                                [NSString stringWithCString: hb_audio_mixdowns[3].human_readable_name]
+                                                                              action: NULL keyEquivalent: @""];
+                        [menuItem setTag: hb_audio_mixdowns[3].amixdown];
+                        if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[3].amixdown;
+                        maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[3].amixdown);
+                    }
+                    
+                    /* do we want to add a 6-channel discrete option? */
+                    if (!mp4AacAc3 && (audioCodecsSupport6Ch == 1 && layout == HB_INPUT_CH_LAYOUT_3F2R && (audio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE))) 
+                    {
+                        NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                                                [NSString stringWithCString: hb_audio_mixdowns[4].human_readable_name]
+                                                                              action: NULL keyEquivalent: @""];
+                        [menuItem setTag: hb_audio_mixdowns[4].amixdown];
+                        if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[4].amixdown;
+                        maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[4].amixdown);
+                    }
+                    
+                    /* do we want to add an AC-3 passthrough option? */
+                    if (audio->in.codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3) {
+                        NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                                                [NSString stringWithCString: hb_audio_mixdowns[5].human_readable_name]
+                                                                              action: NULL keyEquivalent: @""];
+                        [menuItem setTag: hb_audio_mixdowns[5].amixdown];
+                        if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[5].amixdown;
+                        maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
+                    }
+                    
                 /* auto-select the best mixdown based on our saved mixdown preference */
                 
                 /* for now, this is hard-coded to a "best" mixdown of HB_AMIXDOWN_DOLBYPLII */
@@ -3059,24 +3068,24 @@
                 
                 /* if useMixdown > maxMixdownUsed, then use maxMixdownUsed */
                 if (useMixdown > maxMixdownUsed) useMixdown = maxMixdownUsed;
-
+                
                 /* if useMixdown < minMixdownUsed, then use minMixdownUsed */
                 if (useMixdown < minMixdownUsed) useMixdown = minMixdownUsed;
-
+                
                 /* select the (possibly-amended) preferred mixdown */
                 [mixdownPopUp selectItemWithTag: useMixdown];
 				
 				/* lets call the audioTrackMixdownChanged method here to determine appropriate bitrates, etc. */
                 [self audioTrackMixdownChanged: NULL];
             }
-
+            
         }
         
     }
-
+    
 	/* see if the new audio track choice will change the bitrate we need */
     [self calculateBitrate: sender];	
-
+    
 }
 - (IBAction) audioTrackMixdownChanged: (id) sender
 {
@@ -3095,9 +3104,7 @@
         case HB_ACODEC_FAAC:
             /* check if we have a 6ch discrete conversion in either audio track */
             if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || 
-                [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || 
-                [[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3 || 
-                [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3)
+                [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
             {
                 /* FAAC is happy using our min bitrate of 32 kbps, even for 6ch */
                 minbitrate = 32;
@@ -3164,9 +3171,7 @@
 
     /* select the default bitrate (but use 384 for 6-ch AAC) */
     if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || 
-        [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH ||
-        [[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3 || 
-        [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3)
+        [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
     {
         [fAudBitratePopUp selectItemWithTag: 384];
     }
Index: macosx/HandBrake.plist
===================================================================
--- macosx/HandBrake.plist	(revision 1364)
+++ macosx/HandBrake.plist	(working copy)
@@ -9,7 +9,7 @@
 	<key>CFBundleExecutable</key>
 	<string>HandBrake</string>
 	<key>CFBundleGetInfoString</key>
-	<string>0.9.2</string>
+	<string>0.9.3svn1364M</string>
 	<key>CFBundleIconFile</key>
 	<string>HandBrake</string>
 	<key>CFBundleIdentifier</key>
@@ -21,11 +21,11 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>0.9.2</string>
+	<string>0.9.3svn1364M</string>
 	<key>CFBundleSignature</key>
 	<string>HB##</string>
 	<key>CFBundleVersion</key>
-	<string>2008021900</string>
+	<string>2008032501</string>
 	<key>NSHumanReadableCopyright</key>
 	<string>HandBrake Devs</string>
 	<key>NSMainNibFile</key>
Index: macosx/HBQueueController.mm
===================================================================
--- macosx/HBQueueController.mm	(revision 1364)
+++ macosx/HBQueueController.mm	(working copy)
@@ -141,10 +141,21 @@
         crf = job->crf;
         if (job->x264opts)
             x264opts = [[NSString stringWithUTF8String:job->x264opts] retain];
-        memcpy(audio_mixdowns, job->audio_mixdowns, sizeof(audio_mixdowns));
-        acodec = job->acodec;
-        abitrate = job->abitrate;
-        arate = job->arate;
+        /* we need to get the job_list_item out of (hb_job_t *) job which we have above */
+        /* ... and now that we store these variables in job->list_audio, we need to get it and
+        display it appropriately, though I do not have the foggiest how to do it. :) */
+        //hb_audio_t * audio;
+        //for( int i = 0; i < hb_list_count(job->list_audio); i++ )
+        //{
+        //audio = hb_audio_copy( (hb_audio_t *) hb_list_item( job->list_audio, i ) );
+        //acodec = audio->out.codec;
+        //abitrate = audio->out.bitrate;
+        //arate = audio->out.samplerate;
+        //}
+        //memcpy(audio_mixdowns, job->audio_mixdowns, sizeof(audio_mixdowns));
+        //acodec = job->acodec;
+        //abitrate = job->abitrate;
+        //arate = job->arate;
         subtitle = job->subtitle;
         mux = job->mux;
         if (job->file)
@@ -517,8 +528,8 @@
                 jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Surround", ai + 1]];
             if (audio_mixdowns[ai] == HB_AMIXDOWN_DOLBYPLII)
                 jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Pro Logic II", ai + 1]];
-            if (audio_mixdowns[ai] == HB_AMIXDOWN_AC3)
-                jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Pass-Through", ai + 1]];
+            //if (audio_mixdowns[ai] == HB_AMIXDOWN_AC3)
+            //    jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Pass-Through", ai + 1]];
                 
         }
         if (withIcon)   // implies indent the info