rendered paste bodyIndex: 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_config_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 );@@ -253,7 +276,7 @@ static void PrintTitleInfo( hb_title_t * title ) { hb_chapter_t * chapter;- hb_audio_t * audio;+ hb_audio_config_t * audio; hb_subtitle_t * subtitle; int i; @@ -282,15 +305,15 @@ fprintf( stderr, " + audio tracks:\n" ); 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 = hb_list_audio_config_item( title->list_audio, i );+ 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,28 @@ if (!strcmp(preset_name, "AppleTV")) {+ if (hb_list_count(audios) == 0)+ {+ audio = calloc(1, sizeof(*audio));+ hb_audio_config_init(audio);+ audio->in.track = audio->out.track = 0;+ hb_list_add(audios, audio);++ audio = calloc(1, sizeof(*audio));+ hb_audio_config_init(audio);+ 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 +497,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 +509,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 +521,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 +535,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 +546,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 +557,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 +570,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 +584,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 +598,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 +612,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 +625,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 +640,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 +651,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 +664,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 +679,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 +697,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 +777,13 @@ { job->pixel_ratio = pixelratio; }- + if (vfr) { detelecine = 1; job->vfr = 1; }- + /* Add selected filters */ job->filters = hb_list_init(); if( detelecine )@@ -816,74 +861,231 @@ 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 = calloc(1, sizeof(*audio));+ hb_audio_config_init(audio);+ /* 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, 0);+ 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--;+ }+ else+ {+ hb_audio_add( job, audio );+ }+ hb_list_rem(audios, audio);+ free(audio);+ }+ /* 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_audio_config_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_audio_config_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_audio_config_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_audio_config_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_audio_config_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_audio_config_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_audio_config_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_audio_config_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_audio_config_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_audio_config_item(job->list_audio, i);+ audio->out.mixdown = mixdown;+ }+ }+ /* Audio Mixdown */ if( size ) {@@ -1227,18 +1429,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 +1451,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 +1668,68 @@ 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 = calloc(1, sizeof(*audio));+ hb_audio_config_init(audio);+ 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 = calloc(1, sizeof(*audio));+ hb_audio_config_init(audio);+ }+ 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 +1850,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 +1893,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 +1908,10 @@ size = atoi( optarg ); break; case 'B':- abitrate = atoi( optarg );+ if( optarg != NULL )+ {+ abitrates = strdup( optarg );+ } break; case 'Q': crf = 0;@@ -1758,6 +1973,7 @@ if( p && !strcasecmp( p, ".avi" ) ) { mux = HB_MUX_AVI;+ default_acodec = HB_ACODEC_LAME; } else if( p && ( !strcasecmp( p, ".mp4" ) || !strcasecmp( p, ".m4v" ) ) )@@ -1766,15 +1982,18 @@ mux = HB_MUX_IPOD; else mux = HB_MUX_MP4;+ default_acodec = HB_ACODEC_FAAC; } else if( p && ( !strcasecmp( p, ".ogm" ) || !strcasecmp( p, ".ogg" ) ) ) { mux = HB_MUX_OGM;+ default_acodec = HB_ACODEC_VORBIS; } else if( p && !strcasecmp(p, ".mkv" ) ) { mux = HB_MUX_MKV;+ default_acodec = HB_ACODEC_AC3; } else {@@ -1786,6 +2005,7 @@ else if( !strcasecmp( format, "avi" ) ) { mux = HB_MUX_AVI;+ default_acodec = HB_ACODEC_LAME; } else if( !strcasecmp( format, "mp4" ) ) {@@ -1793,15 +2013,18 @@ mux = HB_MUX_IPOD; else mux = HB_MUX_MP4;+ default_acodec = HB_ACODEC_FAAC; } else if( !strcasecmp( format, "ogm" ) || !strcasecmp( format, "ogg" ) ) { mux = HB_MUX_OGM;+ default_acodec = HB_ACODEC_VORBIS; } else if( !strcasecmp( format, "mkv" ) ) { mux = HB_MUX_MKV;+ default_acodec = HB_ACODEC_AC3; } else {@@ -1809,28 +2032,46 @@ "choices are avi, mp4, m4v, ogm, ogg and mkv\n.", format ); return 1; }+ } - if( !acodec )- {- if( mux == HB_MUX_MP4 || mux == HB_MUX_IPOD )- {- acodec = HB_ACODEC_FAAC;- }- else if( mux == HB_MUX_AVI )- {- acodec = HB_ACODEC_LAME;- }- else if( mux == HB_MUX_OGM )- {- acodec = HB_ACODEC_VORBIS;- }- else if( mux == HB_MUX_MKV )- {- acodec = HB_ACODEC_AC3;- }- }+ 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/reader.c===================================================================--- libhb/reader.c (revision 1364)+++ libhb/reader.c (working copy)@@ -358,7 +358,7 @@ audio = hb_list_item( title->list_audio, i ); if( id == audio->id ) {- fifos[n++] = audio->fifo_in;+ fifos[n++] = audio->priv.fifo_in; } } 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->config.out.mixdown); /* pass the number of channels used into the private work data */ /* will only be actually used if we're not doing AC3 passthru */- pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);+ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); pv->level = 32768.0;- pv->dynamic_range_compression = job->dynamic_range_compression;+ pv->dynamic_range_compression = audio->config.out.dynamic_range_compression; pv->next_expected_pts = 0; pv->sequence = 0;@@ -168,6 +169,7 @@ { 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->config.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->config.out.bitrate );+ lame_set_in_samplerate( pv->lame, audio->config.out.samplerate );+ lame_set_out_samplerate( pv->lame, audio->config.out.samplerate ); lame_init_params( pv->lame ); pv->input_samples = 1152 * 2;@@ -85,6 +86,7 @@ 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->config.out.samplerate;+ buf->stop = buf->start + 90000 * 1152 / audio->config.out.samplerate; buf->size = lame_encode_buffer_interleaved( pv->lame, samples_s16, 1152, buf->data, LAME_MAXMP3BUFFER ); buf->frametype = HB_FRAME_AUDIO;Index: 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,8 +346,10 @@ { audio = hb_list_item( title->list_audio, i ); + is_ac3 = (audio->config.out.codec == HB_ACODEC_AC3);+ mux_data = calloc( sizeof( hb_mux_data_t ), 1 );- audio->mux_data = mux_data;+ audio->priv.mux_data = mux_data; #define h mux_data->header #define f mux_data->format.a.f@@ -358,8 +360,8 @@ h.Type = FOURCC( "auds" ); h.InitialFrames = 1; h.Scale = 1;- h.Rate = is_ac3 ? ( audio->bitrate / 8 ) :- ( job->abitrate * 1000 / 8 );+ h.Rate = is_ac3 ? ( audio->config.in.bitrate / 8 ) :+ ( audio->config.out.bitrate * 1000 / 8 ); h.Quality = 0xFFFFFFFF; h.SampleSize = 1; @@ -369,16 +371,16 @@ { f.BytesCount = sizeof( hb_wave_formatex_t ) - 8; f.FormatTag = 0x2000;- f.Channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout);- f.SamplesPerSec = audio->rate;+ f.Channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->config.in.channel_layout);+ f.SamplesPerSec = audio->config.in.samplerate; } else { f.BytesCount = sizeof( hb_wave_formatex_t ) + sizeof( hb_wave_mp3_t ) - 8; f.FormatTag = 0x55;- f.Channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(job->audio_mixdowns[i]);- f.SamplesPerSec = job->arate;+ f.Channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);+ f.SamplesPerSec = audio->config.out.samplerate; } f.AvgBytesPerSec = h.Rate; f.BlockAlign = 1;@@ -391,7 +393,7 @@ f.Size = sizeof( hb_wave_mp3_t ); m.Id = 1; m.Flags = 2;- m.BlockSize = 1152 * f.AvgBytesPerSec / job->arate;+ m.BlockSize = 1152 * f.AvgBytesPerSec / audio->config.out.samplerate; m.FramesPerBlock = 1; m.CodecDelay = 1393; }@@ -439,7 +441,7 @@ char fourcc[4] = "00wb"; audio = hb_list_item( title->list_audio, i );- mux_data = audio->mux_data;+ mux_data = audio->priv.mux_data; fourcc[1] = '1' + i; /* This is fine as we don't allow more than 8 tracks */@@ -513,9 +515,9 @@ { audio = hb_list_item( title->list_audio, i ); fseek( m->file, 264 + i *- ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 :+ ( 102 + ( ( audio->config.out.codec == HB_ACODEC_AC3 ) ? 0 : sizeof( hb_wave_mp3_t ) ) ), SEEK_SET );- WriteInt32( m->file, audio->mux_data->header.Length );+ WriteInt32( m->file, audio->priv.mux_data->header.Length ); } /* movi size */Index: 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->config.in.codec = HB_ACODEC_AC3; break; case 0x02: case 0x03: audio->id = 0xc0 + position;- audio->codec = HB_ACODEC_MPGA;+ audio->config.in.codec = HB_ACODEC_MPGA; break; case 0x04: audio->id = ( ( 0xa0 + position ) << 8 ) | 0xbd;- audio->codec = HB_ACODEC_LPCM;+ audio->config.in.codec = HB_ACODEC_LPCM; break; case 0x06: audio->id = ( ( 0x88 + position ) << 8 ) | 0xbd;- audio->codec = HB_ACODEC_DCA;+ audio->config.in.codec = HB_ACODEC_DCA; break; default: audio->id = 0;- audio->codec = 0;+ audio->config.in.codec = 0; hb_log( "scan: unknown audio codec (%x)", audio_format ); break;@@ -308,19 +308,20 @@ lang = lang_for_code( vts->vtsi_mat->vts_audio_attr[i].lang_code ); - snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)",+ snprintf( audio->config.lang.description, sizeof( audio->config.lang.description ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,- audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec ==- HB_ACODEC_DCA ? "DTS" : ( audio->codec ==+ audio->config.in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->config.in.codec ==+ HB_ACODEC_DCA ? "DTS" : ( audio->config.in.codec == HB_ACODEC_MPGA ? "MPEG" : "LPCM" ) ) );- snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s",+ snprintf( audio->config.lang.simple, sizeof( audio->config.lang.simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );- snprintf( audio->iso639_2, sizeof( audio->iso639_2 ), "%s",+ snprintf( audio->config.lang.iso639_2, sizeof( audio->config.lang.iso639_2 ), "%s", lang->iso639_2); hb_log( "scan: id=%x, lang=%s, 3cc=%s", audio->id,- audio->lang, audio->iso639_2 );+ audio->config.lang.description, audio->config.lang.iso639_2 ); + audio->config.in.track = i; hb_list_add( title->list_audio, audio ); } Index: libhb/hb.c===================================================================--- libhb/hb.c (revision 1364)+++ libhb/hb.c (working copy)@@ -453,7 +453,7 @@ cc_1 = 0; cc_2 = 0; int offset = 0;- + for( k = 0; k < 3; k++ ) { /* One pas for Y, one pass for Cb, one pass for Cr */@@ -476,14 +476,14 @@ so it's width*height + (width / 2) * (height / 2) */ offset *= 5/4; }- + /* Look at one horizontal line at a time */ block = width;- + for( j = 0; j < block; ++j ) { off = 0;- + for( n = 0; n < ( height - 4 ); n = n + 2 ) { /* Look at groups of 4 sequential horizontal lines */@@ -491,29 +491,29 @@ s2 = ( ( buf->data + offset )[ off + j + block ] & 0xff ); s3 = ( ( buf->data + offset )[ off + j + 2 * block ] & 0xff ); s4 = ( ( buf->data + offset )[ off + j + 3 * block ] & 0xff );- + /* Note if the 1st and 2nd lines are more different in color than the 1st and 3rd lines are similar in color.*/- if ( ( abs( s1 - s3 ) < color_equal ) && + if ( ( abs( s1 - s3 ) < color_equal ) && ( abs( s1 - s2 ) > color_diff ) ) ++cc_1;- + /* Note if the 2nd and 3rd lines are more different in color than the 2nd and 4th lines are similar in color.*/ if ( ( abs( s2 - s4 ) < color_equal ) && ( abs( s2 - s3 ) > color_diff) ) ++cc_2;- + /* Now move down 2 horizontal lines before starting over.*/ off += 2 * block; } }- + // compare results /* The final metric seems to be doing some kind of bits per pixel style calculation to decide whether or not enough lines showed alternating colors for the frame size. */ cc[k] = (int)( ( cc_1 + cc_2 ) * 1000.0 / ( width * height ) );- + /* If the plane's cc score meets the threshold, flag it as combed. */ flag[k] = 0; if ( cc[k] > threshold )@@ -521,13 +521,13 @@ flag[k] = 1; } }- + #if 0 /* Debugging info */ // if(flag) hb_log("flags: %i/%i/%i | cc0: %i | cc1: %i | cc2: %i", flag[0], flag[1], flag[2], cc[0], cc[1], cc[2]); #endif- + /* When more than one plane shows combing, tell the caller. */ if (flag[0] || flag[1] || flag[2] ) {@@ -834,7 +834,7 @@ 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->config.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->config.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)@@ -261,14 +270,13 @@ audio = hb_list_item( title->list_audio, i ); mux_data = malloc( sizeof( hb_mux_data_t ) );- audio->mux_data = mux_data;+ audio->priv.mux_data = mux_data; - if( job->acodec & HB_ACODEC_AC3 ||- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )+ if( audio->config.out.codec == HB_ACODEC_AC3 ) { mux_data->track = MP4AddAC3AudioTrack( m->file,- job->arate, 1536, MP4_MPEG4_AUDIO_TYPE );+ m->samplerate, 1536, MP4_MPEG4_AUDIO_TYPE ); MP4SetTrackBytesProperty( m->file, mux_data->track, "udta.name.value",@@ -276,7 +284,7 @@ } else { mux_data->track = MP4AddAudioTrack( m->file,- job->arate, 1024, MP4_MPEG4_AUDIO_TYPE );+ m->samplerate, 1024, MP4_MPEG4_AUDIO_TYPE ); MP4SetTrackBytesProperty( m->file, mux_data->track, "udta.name.value",@@ -285,18 +293,18 @@ MP4SetAudioProfileLevel( m->file, 0x0F ); MP4SetTrackESConfiguration( m->file, mux_data->track,- audio->config.aac.bytes, audio->config.aac.length );+ audio->priv.config.aac.bytes, audio->priv.config.aac.length ); /* Set the correct number of channels for this track */- reserved2[9] = (u_int8_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown);+ reserved2[9] = (u_int8_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); MP4SetTrackBytesProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.mp4a.reserved2", reserved2, sizeof(reserved2)); } /* Set the language for this track */ /* The language is stored as 5-bit text - 0x60 */- language_code = audio->iso639_2[0] - 0x60; language_code <<= 5;- language_code |= audio->iso639_2[1] - 0x60; language_code <<= 5;- language_code |= audio->iso639_2[2] - 0x60;+ language_code = audio->config.lang.iso639_2[0] - 0x60; language_code <<= 5;+ language_code |= audio->config.lang.iso639_2[1] - 0x60; language_code <<= 5;+ language_code |= audio->config.lang.iso639_2[2] - 0x60; MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.mdhd.language", language_code); @@ -372,7 +380,7 @@ 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->config.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->config.in.codec = HB_ACODEC_AC3; hb_log("transport stream pid 0x%x (type 0x%x) is AC-3 audio id 0x%x", stream->ts_audio_pids[aud_pid_index], stream->ts_audio_stream_type[1 + aud_pid_index],@@ -784,7 +784,7 @@ else if ((buf[3] & 0xe0) == 0xc0) { audio->id = buf[3] | aud_pid_index;- audio->codec = HB_ACODEC_MPGA;+ audio->config.in.codec = HB_ACODEC_MPGA; hb_log("transport stream pid 0x%x (type 0x%x) is MPEG audio id 0x%x", stream->ts_audio_pids[aud_pid_index], stream->ts_audio_stream_type[1 + aud_pid_index],@@ -794,7 +794,7 @@ } } fseeko(stream->file_handle, cur_pos, SEEK_SET);- if (! audio->codec)+ if (! audio->config.in.codec) { hb_log("transport stream pid 0x%x (type 0x%x) isn't audio", stream->ts_audio_pids[aud_pid_index],@@ -811,7 +811,7 @@ switch ( id >> 12 ) { case 0x0:- audio->codec = HB_ACODEC_MPGA;+ audio->config.in.codec = HB_ACODEC_MPGA; hb_log("add_audio_to_title: added MPEG audio stream 0x%x", id); break; case 0x2:@@ -819,11 +819,11 @@ free( audio ); return; case 0x8:- audio->codec = HB_ACODEC_AC3;+ audio->config.in.codec = HB_ACODEC_AC3; hb_log("add_audio_to_title: added AC3 audio stream 0x%x", id); break; case 0xa:- audio->codec = HB_ACODEC_LPCM;+ audio->config.in.codec = HB_ACODEC_LPCM; hb_log("add_audio_to_title: added LPCM audio stream 0x%x", id); break; default:@@ -913,12 +913,12 @@ } lang = lang_for_code(stream->a52_info[i].lang_code);- if (!audio->rate)- audio->rate = stream->a52_info[i].rate;- if (!audio->bitrate)- audio->bitrate = stream->a52_info[i].bitrate;- if (!audio->config.a52.ac3flags)- audio->config.a52.ac3flags = audio->ac3flags = stream->a52_info[i].flags;+ if (!audio->config.in.samplerate)+ audio->config.in.samplerate = stream->a52_info[i].rate;+ if (!audio->config.in.bitrate)+ audio->config.in.bitrate = stream->a52_info[i].bitrate;+ if (!audio->priv.config.a52.ac3flags)+ audio->priv.config.a52.ac3flags = audio->config.flags.ac3 = stream->a52_info[i].flags; } else@@ -927,74 +927,74 @@ lang = lang_for_code(0x0000); } - if (!audio->input_channel_layout)+ if (!audio->config.in.channel_layout) {- switch( audio->ac3flags & A52_CHANNEL_MASK )+ switch( audio->config.flags.ac3 & A52_CHANNEL_MASK ) { /* mono sources */ case A52_MONO: case A52_CHANNEL1: case A52_CHANNEL2:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_MONO; break; /* stereo input */ case A52_CHANNEL: case A52_STEREO:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO; break; /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */ case A52_DOLBY:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_DOLBY; break; /* 3F/2R input */ case A52_3F2R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R; break; /* 3F/1R input */ case A52_3F1R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R; break; /* other inputs */ case A52_3F:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F; break; case A52_2F1R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R; break; case A52_2F2R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R; break; /* unknown */ default:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO; } /* add in our own LFE flag if the source has LFE */- if (audio->ac3flags & A52_LFE)+ if (audio->config.flags.ac3 & A52_LFE) {- audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;+ audio->config.in.channel_layout = audio->config.in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE; } } - snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,- audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->codec == HB_ACODEC_DCA ? "DTS" : "LPCM" ) ) );- snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );- snprintf( audio->iso639_2, sizeof( audio->iso639_2 ), "%s", lang->iso639_2);+ snprintf( audio->config.lang.description, sizeof( audio->config.lang.description ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,+ audio->config.in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->config.in.codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->config.in.codec == HB_ACODEC_DCA ? "DTS" : "LPCM" ) ) );+ snprintf( audio->config.lang.simple, sizeof( audio->config.lang.simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );+ snprintf( audio->config.lang.iso639_2, sizeof( audio->config.lang.iso639_2 ), "%s", lang->iso639_2); - if ( (audio->ac3flags & A52_CHANNEL_MASK) == A52_DOLBY ) {- sprintf( audio->lang + strlen( audio->lang ),+ if ( (audio->config.flags.ac3 & A52_CHANNEL_MASK) == A52_DOLBY ) {+ sprintf( audio->config.lang.description + strlen( audio->config.lang.description ), " (Dolby Surround)" ); } else {- sprintf( audio->lang + strlen( audio->lang ),+ sprintf( audio->config.lang.description + strlen( audio->config.lang.description ), " (%d.%d ch)",- HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +- HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),- HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->config.in.channel_layout) ++ HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->config.in.channel_layout),+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->config.in.channel_layout)); } hb_log( "stream: audio %x: lang %s, rate %d, bitrate %d, "- "flags = 0x%x", audio->id, audio->lang, audio->rate,- audio->bitrate, audio->ac3flags );+ "flags = 0x%x", audio->id, audio->config.lang.description, audio->config.in.samplerate,+ audio->config.in.bitrate, audio->config.flags.ac3 ); } @@ -1879,7 +1879,7 @@ // 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->config.out.mixdown); /* pass the number of channels used into the private work data */ /* will only be actually used if we're not doing AC3 passthru */- pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);+ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); pv->level = 32768.0; Index: libhb/muxogm.c===================================================================--- libhb/muxogm.c (revision 1364)+++ libhb/muxogm.c (working copy)@@ -135,9 +135,9 @@ { audio = hb_list_item( title->list_audio, i ); mux_data = malloc( sizeof( hb_mux_data_t ) );- mux_data->codec = job->acodec;+ mux_data->codec = audio->config.out.codec; mux_data->i_packet_no = 0;- audio->mux_data = mux_data;+ audio->priv.mux_data = mux_data; ogg_stream_init( &mux_data->os, i + 1 ); } @@ -200,9 +200,9 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i );- mux_data = audio->mux_data;+ mux_data = audio->priv.mux_data; memset( &h, 0, sizeof( ogg_stream_header_t ) );- switch( job->acodec )+ switch( audio->config.out.codec ) { case HB_ACODEC_LAME: {@@ -212,7 +212,7 @@ SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1); SetQWLE( &h.i_time_unit, 0 );- SetQWLE( &h.i_samples_per_unit, job->arate );+ SetQWLE( &h.i_samples_per_unit, audio->config.out.samplerate ); SetDWLE( &h.i_default_len, 1 ); SetDWLE( &h.i_buffer_size, 30 * 1024 ); SetWLE ( &h.i_bits_per_sample, 0 );@@ -220,7 +220,7 @@ SetDWLE( &h.header.audio.i_channels, 2 ); SetDWLE( &h.header.audio.i_block_align, 0 ); SetDWLE( &h.header.audio.i_avgbytespersec,- job->abitrate / 8 );+ audio->config.out.bitrate / 8 ); op.packet = (unsigned char*) &h; op.bytes = sizeof( ogg_stream_header_t );@@ -233,9 +233,9 @@ } case HB_ACODEC_VORBIS: {- memcpy( &op, audio->config.vorbis.headers[0],+ memcpy( &op, audio->priv.config.vorbis.headers[0], sizeof( ogg_packet ) );- op.packet = audio->config.vorbis.headers[0] ++ op.packet = audio->priv.config.vorbis.headers[0] + sizeof( ogg_packet ); ogg_stream_packetin( &mux_data->os, &op ); break;@@ -275,16 +275,16 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i );- if( job->acodec == HB_ACODEC_VORBIS )+ if( audio->config.out.codec == HB_ACODEC_VORBIS ) { int j;- mux_data = audio->mux_data;+ mux_data = audio->priv.mux_data; for( j = 1; j < 3; j++ ) {- memcpy( &op, audio->config.vorbis.headers[j],+ memcpy( &op, audio->priv.config.vorbis.headers[j], sizeof( ogg_packet ) );- op.packet = audio->config.vorbis.headers[j] ++ op.packet = audio->priv.config.vorbis.headers[j] + sizeof( ogg_packet ); ogg_stream_packetin( &mux_data->os, &op ); @@ -387,7 +387,7 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i );- mux_data = audio->mux_data;+ mux_data = audio->priv.mux_data; if( OGMFlush( m, mux_data ) < 0 ) { return -1;Index: 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->config.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->config.out.codec == HB_ACODEC_AC3 ) { /* Have a silent AC-3 frame ready in case we have to fill a gap */@@ -219,9 +219,9 @@ codec = avcodec_find_encoder( CODEC_ID_AC3 ); c = avcodec_alloc_context(); - c->bit_rate = sync->audio->bitrate;- c->sample_rate = sync->audio->rate;- c->channels = 2;+ c->bit_rate = sync->audio->config.in.bitrate;+ c->sample_rate = sync->audio->config.in.samplerate;+ c->channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( sync->audio->config.in.channel_layout ); if( avcodec_open( c, codec ) < 0 ) {@@ -231,8 +231,8 @@ zeros = calloc( AC3_SAMPLES_PER_FRAME * sizeof( short ) * c->channels, 1 );- sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /- sync->audio->rate / 8;+ sync->ac3_size = sync->audio->config.in.bitrate * AC3_SAMPLES_PER_FRAME /+ sync->audio->config.in.samplerate / 8; sync->ac3_buf = malloc( sync->ac3_size ); if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,@@ -249,7 +249,7 @@ { /* Initialize libsamplerate */ int error;- sync->state = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown), &error );+ sync->state = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->config.out.mixdown), &error ); sync->data.end_of_input = 0; } }@@ -432,9 +432,9 @@ * 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->config.out.samplerate ) { hb_log("sync: audio %d weird duration %lld, start %lld, stop %lld, next %lld", i, duration, buf->start, buf->stop, sync->next_pts); if ( duration <= 0 ) {- duration = ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->rate;+ duration = ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->config.out.samplerate; buf->stop = buf->start + duration; } } sync->next_pts += duration; if( /* audio->rate == job->arate || This should work but doesn't */- job->acodec & HB_ACODEC_AC3 ||- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )+ audio->config.out.codec == HB_ACODEC_AC3 ||+ audio->config.out.codec == HB_ACODEC_DCA ) { /* * If we don't have to do sample rate conversion or this audio is AC3@@ -586,11 +586,11 @@ /* Not pass-thru - do sample rate conversion */ int count_in, count_out; hb_buffer_t * buf_raw = buf;- int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) *+ int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown) * sizeof( float ); count_in = buf_raw->size / channel_count;- count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;+ count_out = ( buf_raw->stop - buf_raw->start ) * audio->config.out.samplerate / 90000; sync->data.input_frames = count_in; sync->data.output_frames = count_out;@@ -630,19 +630,18 @@ hb_fifo_t * fifo; int rate; - if( job->acodec & HB_ACODEC_AC3 ||- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )+ if( audio->config.out.codec == HB_ACODEC_AC3 ) {- fifo = audio->fifo_out;- rate = audio->rate;+ fifo = audio->priv.fifo_out;+ rate = audio->config.in.samplerate; } else {- fifo = audio->fifo_sync;- rate = job->arate;+ fifo = audio->priv.fifo_sync;+ rate = audio->config.out.samplerate; } - while( !hb_fifo_is_full( fifo ) && ( buf = hb_fifo_see( audio->fifo_raw ) ) )+ while( !hb_fifo_is_full( fifo ) && ( buf = hb_fifo_see( audio->priv.fifo_raw ) ) ) { if ( sync->next_pts - buf->start > 500 ) {@@ -656,7 +655,7 @@ sync->first_drop = buf->start; } ++sync->drop_count;- buf = hb_fifo_get( audio->fifo_raw );+ buf = hb_fifo_get( audio->priv.fifo_raw ); hb_buffer_close( &buf ); continue; }@@ -711,13 +710,13 @@ * audio stream and are ready to inject the next input frame into * the output stream. */- buf = hb_fifo_get( audio->fifo_raw );+ buf = hb_fifo_get( audio->priv.fifo_raw ); OutputAudioFrame( job, audio, buf, sync, fifo, i ); } if( NeedSilence( w, audio, i ) ) {- InsertSilence( w, i, (90000 * AC3_SAMPLES_PER_FRAME) / sync->audio->rate );+ InsertSilence( w, i, (90000 * AC3_SAMPLES_PER_FRAME) / sync->audio->config.out.samplerate ); } } @@ -727,10 +726,10 @@ hb_job_t * job = pv->job; hb_sync_audio_t * sync = &pv->sync_audio[i]; - if( hb_fifo_size( audio->fifo_in ) ||- hb_fifo_size( audio->fifo_raw ) ||- hb_fifo_size( audio->fifo_sync ) ||- hb_fifo_size( audio->fifo_out ) )+ if( hb_fifo_size( audio->priv.fifo_in ) ||+ hb_fifo_size( audio->priv.fifo_raw ) ||+ hb_fifo_size( audio->priv.fifo_sync ) ||+ hb_fifo_size( audio->priv.fifo_out ) ) { /* We have some audio, we are fine */ return 0;@@ -759,22 +758,22 @@ hb_sync_audio_t *sync = &pv->sync_audio[i]; hb_buffer_t *buf; - if( job->acodec & HB_ACODEC_AC3 || job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )+ if( sync->audio->config.out.codec == HB_ACODEC_AC3 ) { buf = hb_buffer_init( sync->ac3_size ); buf->start = sync->next_pts; buf->stop = buf->start + duration; memcpy( buf->data, sync->ac3_buf, buf->size );- OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->fifo_out, i );+ OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->priv.fifo_out, i ); } else { buf = hb_buffer_init( duration * sizeof( float ) *- HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown) );+ HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->config.out.mixdown) ); buf->start = sync->next_pts; buf->stop = buf->start + duration; memset( buf->data, 0, buf->size );- OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->fifo_sync, i );+ OutputAudioFrame( job, sync->audio, buf, sync, sync->audio->priv.fifo_sync, i ); } } Index: 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->config.out.mixdown); - pv->faac = faacEncOpen( job->arate, pv->out_discrete_channels, &pv->input_samples,+ pv->faac = faacEncOpen( audio->config.out.samplerate, pv->out_discrete_channels, &pv->input_samples, &pv->output_bytes ); pv->buf = malloc( pv->input_samples * sizeof( float ) ); @@ -74,12 +75,12 @@ } cfg->useTns = 0;- cfg->bitRate = job->abitrate * 1000 / pv->out_discrete_channels; /* Per channel */+ cfg->bitRate = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; /* Per channel */ cfg->bandWidth = 0; cfg->outputFormat = 0; cfg->inputFormat = FAAC_INPUT_FLOAT; - if (w->amixdown == HB_AMIXDOWN_6CH && w->source_acodec == HB_ACODEC_AC3)+ if (audio->config.out.mixdown == HB_AMIXDOWN_6CH && audio->config.in.codec == HB_ACODEC_AC3) { /* we are preserving 5.1 AC-3 audio into 6-channel AAC, and need to re-map the output of deca52 into our own mapping - the mapping@@ -140,6 +141,7 @@ 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->config.out.samplerate;+ buf->stop = buf->start + 90000 * pv->input_samples / audio->config.out.samplerate / pv->out_discrete_channels; buf->size = faacEncEncode( pv->faac, (int32_t *) pv->buf, pv->input_samples, buf->data, pv->output_bytes ); buf->frametype = HB_FRAME_AUDIO;Index: libhb/muxcommon.c===================================================================--- libhb/muxcommon.c (revision 1364)+++ libhb/muxcommon.c (working copy)@@ -98,7 +98,7 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i );- if( !hb_fifo_size( audio->fifo_out ) )+ if( !hb_fifo_size( audio->priv.fifo_out ) ) { ready = 0; break;@@ -131,8 +131,8 @@ { audio = hb_list_item( title->list_audio, i ); track = calloc( sizeof( hb_track_t ), 1 );- track->fifo = audio->fifo_out;- track->mux_data = audio->mux_data;+ track->fifo = audio->priv.fifo_out;+ track->mux_data = audio->priv.mux_data; hb_list_add( list, track ); } Index: libhb/work.c===================================================================--- libhb/work.c (revision 1364)+++ libhb/work.c (working copy)@@ -337,57 +337,55 @@ } } - if( job->audio_mixdowns[0] == HB_AMIXDOWN_AC3 || job->audio_mixdowns[1] == HB_AMIXDOWN_AC3 )- {- /* Hard set correct sample rate for AC3 when libhb- mistakenly thinks the audio codec is AAC */- job->arate = 48000;- }-- if( job->acodec & HB_ACODEC_AC3 )- {- hb_log( " + audio AC3 passthrough" );-- /* Hard set correct sample rate for AC3 */- job->arate = 48000;- }- else- {- hb_log( " + audio %d kbps, %d Hz", job->abitrate, job->arate );- hb_log( " + encoder %s", ( job->acodec & HB_ACODEC_FAAC ) ?- "faac" : ( ( job->acodec & HB_ACODEC_LAME ) ? "lame" :- "vorbis" ) );- }-- if ( job->dynamic_range_compression > 1 )- hb_log(" + dynamic range compression: %f", job->dynamic_range_compression);-- /* if we are doing AC3 passthru (at the codec level, not pass-through),- * then remove any non-AC3 audios from the job */+ /* if we are doing passthru, and the input codec is not the same as the output+ * codec, then remove this audio from the job */ /* otherwise, Bad Things will happen */ for( i = 0; i < hb_list_count( title->list_audio ); ) { audio = hb_list_item( title->list_audio, i );- if( ( job->acodec & HB_ACODEC_AC3 ) && ( audio->codec != HB_ACODEC_AC3 ) )+ if( ( ( audio->config.out.codec == HB_ACODEC_AC3 ) && ( audio->config.in.codec != HB_ACODEC_AC3 ) ) ||+ ( ( audio->config.out.codec == HB_ACODEC_DCA ) && ( audio->config.in.codec != HB_ACODEC_DCA ) ) ) {+ hb_log( "Passthru requested and input codec is not the same as output codec for track %d",+ audio->config.out.track ); hb_list_rem( title->list_audio, audio ); free( audio ); continue; }- i++;+ /* Adjust output track number, in case we removed one.+ * Output tracks sadly still need to be in sequential order.+ */+ audio->config.out.track = i++; } for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i );- hb_log( " + %x, %s", audio->id, audio->lang );+ hb_log( " + audio track %d", audio->config.out.track );+ hb_log( " + input track %d", audio->config.in.track );+ if( (audio->config.out.codec == HB_ACODEC_AC3) || (audio->config.out.codec == HB_ACODEC_DCA) )+ {+ hb_log( " + %s passthrough", (audio->config.out.codec == HB_ACODEC_AC3) ?+ "AC3" : "DCA" );+ }+ else+ {+ hb_log( " + audio %d kbps, %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );+ hb_log( " + encoder %s", ( audio->config.out.codec == HB_ACODEC_FAAC ) ?+ "faac" : ( ( audio->config.out.codec == HB_ACODEC_LAME ) ? "lame" :+ "vorbis" ) );+ if ( audio->config.out.dynamic_range_compression > 1 )+ hb_log(" + dynamic range compression: %f", audio->config.out.dynamic_range_compression);+ } + hb_log( " + %x, %s", audio->id, audio->config.lang.description );+ /* sense-check the current mixdown options */ /* log the requested mixdown */ for (j = 0; j < hb_audio_mixdowns_count; j++) {- if (hb_audio_mixdowns[j].amixdown == job->audio_mixdowns[i]) {- hb_log( " + Requested mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );+ if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) {+ hb_log( " + Requested mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name ); break; } }@@ -396,33 +394,22 @@ /* audioCodecsSupportMono and audioCodecsSupport6Ch are the same for now, but this may change in the future, so they are separated for flexibility */- int audioCodecsSupportMono = ((audio->codec == HB_ACODEC_AC3 ||- audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS));- int audioCodecsSupport6Ch = ((audio->codec == HB_ACODEC_AC3 ||- audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS));+ int audioCodecsSupportMono = ( (audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA) &&+ (audio->config.out.codec == HB_ACODEC_FAAC || audio->config.out.codec == HB_ACODEC_VORBIS) );+ int audioCodecsSupport6Ch = ( (audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA) &&+ (audio->config.out.codec == HB_ACODEC_FAAC || audio->config.out.codec == HB_ACODEC_VORBIS)); - if( audio->codec != HB_ACODEC_AC3 && job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )- {- /*- * Sanity check that we haven't asked for AC3 from a non AC3 track - drop this track- * to stereo to avoid a crash later.- */- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;- }-- if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )- { /* find out what the format of our source audio is */- switch (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) {+ switch (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) { /* mono sources */ case HB_INPUT_CH_LAYOUT_MONO: /* regardless of what stereo mixdown we've requested, a mono source always get mixed down to mono if we can, and mixed up to stereo if we can't */- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {- job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;+ if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {+ audio->config.out.mixdown = HB_AMIXDOWN_MONO; } else {- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO; } break; @@ -430,11 +417,11 @@ case HB_INPUT_CH_LAYOUT_STEREO: /* if we've requested a mono mixdown, and it is supported, then do the mix */ /* use stereo if not supported */- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;+ if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO; /* otherwise, preserve stereo regardless of if we requested something higher */- } else if (job->audio_mixdowns[i] > HB_AMIXDOWN_STEREO) {- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;+ } else if (audio->config.out.mixdown > HB_AMIXDOWN_STEREO) {+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO; } break; @@ -444,12 +431,12 @@ case HB_INPUT_CH_LAYOUT_DOLBY: /* if we've requested a mono mixdown, and it is supported, then do the mix */ /* preserve dolby if not supported */- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;+ if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBY; /* otherwise, preserve dolby even if we requested something higher */ /* a stereo mixdown will still be honoured here */- } else if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBY) {- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;+ } else if (audio->config.out.mixdown > HB_AMIXDOWN_DOLBY) {+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBY; } break; @@ -457,21 +444,21 @@ case HB_INPUT_CH_LAYOUT_3F2R: /* if we've requested a mono mixdown, and it is supported, then do the mix */ /* use dpl2 if not supported */- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;+ if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII; } else { /* check if we have 3F2R input and also have an LFE - i.e. we have a 5.1 source) */- if (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE) {+ if (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE) { /* we have a 5.1 source */ /* if we requested 6ch, but our audio format doesn't support it, then mix to DPLII instead */- if (job->audio_mixdowns[i] == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;+ if (audio->config.out.mixdown == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII; } } else { /* we have a 5.0 source, so we can't do 6ch conversion default to DPL II instead */- if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBYPLII) {- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;+ if (audio->config.out.mixdown > HB_AMIXDOWN_DOLBYPLII) {+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII; } } }@@ -482,13 +469,13 @@ case HB_INPUT_CH_LAYOUT_3F1R: /* if we've requested a mono mixdown, and it is supported, then do the mix */ /* use dpl1 if not supported */- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;+ if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBY; } else { /* we have a 4.0 or 4.1 source, so we can't do DPLII or 6ch conversion default to DPL I instead */- if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBY) {- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;+ if (audio->config.out.mixdown > HB_AMIXDOWN_DOLBY) {+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBY; } } /* all other mixdowns will have been preserved here */@@ -496,41 +483,37 @@ default: /* if we've requested a mono mixdown, and it is supported, then do the mix */- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {- job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;+ if (audio->config.out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {+ audio->config.out.mixdown = HB_AMIXDOWN_MONO; /* mix everything else down to stereo */ } else {- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO; } }- } /* log the output mixdown */ for (j = 0; j < hb_audio_mixdowns_count; j++) {- if (hb_audio_mixdowns[j].amixdown == job->audio_mixdowns[i]) {- hb_log( " + Actual mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );+ if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) {+ hb_log( " + Actual mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name ); break; } } - /* we now know we have a valid mixdown for the input source and the audio output format */- /* remember the mixdown for this track */- audio->amixdown = job->audio_mixdowns[i];+ if (audio->config.out.codec == HB_ACODEC_VORBIS)+ audio->priv.config.vorbis.language = audio->config.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 );- audio->fifo_sync = hb_fifo_init( FIFO_CPU_MULT * cpu_count );- audio->fifo_out = hb_fifo_init( FIFO_CPU_MULT * cpu_count );+ audio->priv.fifo_in = hb_fifo_init( 2048 );+ audio->priv.fifo_raw = hb_fifo_init( FIFO_CPU_MULT * cpu_count );+ audio->priv.fifo_sync = hb_fifo_init( FIFO_CPU_MULT * cpu_count );+ audio->priv.fifo_out = hb_fifo_init( FIFO_CPU_MULT * cpu_count ); /* * Audio Decoder Thread */- switch( audio->codec )+ switch( audio->config.in.codec ) { case HB_ACODEC_AC3: w = getWork( WORK_DECA52 );@@ -544,12 +527,16 @@ case HB_ACODEC_LPCM: w = getWork( WORK_DECLPCM ); break;+ default:+ /* Invalid input codec */+ hb_error("Invalid input codec: %d", audio->config.in.codec);+ *job->die = 1;+ goto cleanup; }- w->fifo_in = audio->fifo_in;- w->fifo_out = audio->fifo_raw;- w->config = &audio->config;- w->amixdown = audio->amixdown;- w->source_acodec = audio->codec;+ w->fifo_in = audio->priv.fifo_in;+ w->fifo_out = audio->priv.fifo_raw;+ w->config = &audio->priv.config;+ w->audio = audio; /* FIXME: This feels really hackish, anything better? */ audio_w = calloc( sizeof( hb_work_object_t ), 1 );@@ -560,10 +547,8 @@ /* * Audio Encoder Thread */- if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )+ switch( audio->config.out.codec ) {- switch( job->acodec )- { case HB_ACODEC_FAAC: w = getWork( WORK_ENCFAAC ); break;@@ -573,20 +558,25 @@ case HB_ACODEC_VORBIS: w = getWork( WORK_ENCVORBIS ); break;- }+ case HB_ACODEC_AC3:+ break;+ case HB_ACODEC_DCA: /* These are all invalid output codecs. */+ default:+ hb_error("Invalid audio codec: %#x", audio->config.out.codec);+ w = NULL;+ *job->die = 1;+ goto cleanup; } - if( job->acodec != HB_ACODEC_AC3 &&- job->audio_mixdowns[i] != HB_AMIXDOWN_AC3)+ if( audio->config.out.codec != HB_ACODEC_AC3 ) { /* * Add the encoder thread if not doing AC-3 pass through */- w->fifo_in = audio->fifo_sync;- w->fifo_out = audio->fifo_out;- w->config = &audio->config;- w->amixdown = audio->amixdown;- w->source_acodec = audio->codec;+ w->fifo_in = audio->priv.fifo_sync;+ w->fifo_out = audio->priv.fifo_out;+ w->config = &audio->priv.config;+ w->audio = audio; /* FIXME: This feels really hackish, anything better? */ audio_w = calloc( sizeof( hb_work_object_t ), 1 );@@ -640,12 +630,16 @@ w->close( w ); job->done = 1; +cleanup: /* Close work objects */ while( ( w = hb_list_item( job->list_work, 0 ) ) ) { hb_list_rem( job->list_work, w );- hb_thread_close( &w->thread );- w->close( w );+ if( w != NULL && w->thread != NULL )+ {+ hb_thread_close( &w->thread );+ w->close( w );+ } /* FIXME: This feels really hackish, anything better? */ if ( w->id == WORK_DECA52 ||@@ -663,8 +657,10 @@ hb_list_close( &job->list_work ); /* Stop read & write threads */- hb_thread_close( &job->reader );- hb_thread_close( &job->muxer );+ if( job->reader != NULL )+ hb_thread_close( &job->reader );+ if( job->muxer != NULL )+ hb_thread_close( &job->muxer ); /* Close fifos */ hb_fifo_close( &job->fifo_mpeg2 );@@ -684,10 +680,14 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i );- hb_fifo_close( &audio->fifo_in );- hb_fifo_close( &audio->fifo_raw );- hb_fifo_close( &audio->fifo_sync );- hb_fifo_close( &audio->fifo_out );+ if( audio->priv.fifo_in != NULL )+ hb_fifo_close( &audio->priv.fifo_in );+ if( audio->priv.fifo_raw != NULL )+ hb_fifo_close( &audio->priv.fifo_raw );+ if( audio->priv.fifo_sync != NULL )+ hb_fifo_close( &audio->priv.fifo_sync );+ if( audio->priv.fifo_out != NULL )+ hb_fifo_close( &audio->priv.fifo_out ); } if( job->indepth_scan )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->config.in.codec == HB_ACODEC_AC3 &&+ !audio->config.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->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA ) &&+ !audio->config.in.bitrate ) { hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",- audio->codec );+ audio->config.in.codec ); hb_list_rem( title->list_audio, audio ); free( audio ); continue;@@ -188,9 +188,9 @@ for( j = 0; j < hb_list_count( title->list_audio ); j++ ) { audio = hb_list_item( title->list_audio, j );- if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )+ if( audio->config.in.codec == HB_ACODEC_LPCM || audio->config.in.codec == HB_ACODEC_MPGA ) {- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO; } } @@ -247,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->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA ) && audio->id == b->id ) { break;@@ -599,7 +594,7 @@ return; } - if( audio->bitrate )+ if( audio->config.in.bitrate ) { /* Already done for this track */ return;@@ -608,78 +603,77 @@ for( i = 0; i < b->size - 7; i++ ) { - if ( audio->codec == HB_ACODEC_AC3 )+ if ( audio->config.in.codec == HB_ACODEC_AC3 ) { /* check for a52 */ if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) ) { hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );- audio->rate = rate;- audio->bitrate = bitrate;+ audio->config.in.samplerate = rate;+ audio->config.in.bitrate = bitrate; switch( flags & A52_CHANNEL_MASK ) { /* mono sources */ case A52_MONO: case A52_CHANNEL1: case A52_CHANNEL2:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_MONO; break; /* stereo input */ case A52_CHANNEL: case A52_STEREO:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO; break; /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */ case A52_DOLBY:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_DOLBY; break; /* 3F/2R input */ case A52_3F2R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R; break; /* 3F/1R input */ case A52_3F1R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R; break; /* other inputs */ case A52_3F:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F; break; case A52_2F1R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R; break; case A52_2F2R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R; break; /* unknown */ default:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO; } /* add in our own LFE flag if the source has LFE */ if (flags & A52_LFE) {- audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;+ audio->config.in.channel_layout = audio->config.in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE; } /* store the AC3 flags for future reference- This enables us to find out if we had a stereo or Dolby source later on */- audio->config.a52.ac3flags = flags;+ * This enables us to find out if we had a stereo or Dolby source later on+ * Store the ac3 flags in the public ac3flags property too, so we can access it from the GUI+ */+ audio->config.flags.ac3 = audio->priv.config.a52.ac3flags = flags; - /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */- audio->ac3flags = audio->config.a52.ac3flags;- /* XXX */ if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {- sprintf( audio->lang + strlen( audio->lang ),+ sprintf( audio->config.lang.description + strlen( audio->config.lang.description ), " (Dolby Surround)" ); } else {- sprintf( audio->lang + strlen( audio->lang ),+ sprintf( audio->config.lang.description + strlen( audio->config.lang.description ), " (%d.%d ch)",- HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +- HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),- HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->config.in.channel_layout) ++ HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->config.in.channel_layout),+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->config.in.channel_layout)); } break;@@ -687,7 +681,7 @@ } }- else if ( audio->codec == HB_ACODEC_DCA )+ else if ( audio->config.in.codec == HB_ACODEC_DCA ) { hb_log( "scan: checking for DCA syncinfo" );@@ -697,70 +691,69 @@ if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) ) { hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );- audio->rate = rate;- audio->bitrate = bitrate;+ audio->config.in.samplerate = rate;+ audio->config.in.bitrate = bitrate; switch( flags & DCA_CHANNEL_MASK ) { /* mono sources */ case DCA_MONO:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_MONO; break; /* stereo input */ case DCA_CHANNEL: case DCA_STEREO: case DCA_STEREO_SUMDIFF: case DCA_STEREO_TOTAL:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO; break; /* 3F/2R input */ case DCA_3F2R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R; break; /* 3F/1R input */ case DCA_3F1R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R; break; /* other inputs */ case DCA_3F:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_3F; break; case DCA_2F1R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R; break; case DCA_2F2R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R; break; case DCA_4F2R:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_4F2R; break; /* unknown */ default:- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;+ audio->config.in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO; } /* add in our own LFE flag if the source has LFE */ if (flags & DCA_LFE) {- audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;+ audio->config.in.channel_layout = audio->config.in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE; } /* store the DCA flags for future reference- This enables us to find out if we had a stereo or Dolby source later on */- audio->config.dca.dcaflags = flags;+ * This enables us to find out if we had a stereo or Dolby source later on+ * store the dca flags in the public dcaflags property too, so we can access it from the GUI+ */+ audio->config.flags.dca = audio->priv.config.dca.dcaflags = flags; - /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */- audio->dcaflags = audio->config.dca.dcaflags;- /* XXX */ if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {- sprintf( audio->lang + strlen( audio->lang ),+ sprintf( audio->config.lang.description + strlen( audio->config.lang.description ), " (Dolby Surround)" ); } else {- sprintf( audio->lang + strlen( audio->lang ),+ sprintf( audio->config.lang.description + strlen( audio->config.lang.description ), " (%d.%d ch)",- HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +- HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),- HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->config.in.channel_layout) ++ HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->config.in.channel_layout),+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->config.in.channel_layout)); } break;@@ -778,8 +771,8 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i );- if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&- !audio->bitrate )+ if( ( audio->config.in.codec == HB_ACODEC_AC3 || audio->config.in.codec == HB_ACODEC_DCA ) &&+ !audio->config.in.bitrate ) { return 0; }Index: 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; }; /**********************************************************************@@ -158,9 +159,11 @@ { audio = hb_list_item( title->list_audio, i ); mux_data = malloc( sizeof( hb_mux_data_t ) );- audio->mux_data = mux_data;+ audio->priv.mux_data = mux_data; - switch (job->acodec)+ mux_data->codec = audio->config.out.codec;++ switch (audio->config.out.codec) { case HB_ACODEC_AC3: track->codecPrivate = NULL;@@ -180,8 +183,8 @@ uint64_t header_sizes[3]; for (i = 0; i < 3; ++i) {- ogg_headers[i] = (ogg_packet *)audio->config.vorbis.headers[i];- ogg_headers[i]->packet = (unsigned char *)&audio->config.vorbis.headers[i] + sizeof( ogg_packet );+ ogg_headers[i] = (ogg_packet *)audio->priv.config.vorbis.headers[i];+ ogg_headers[i]->packet = (unsigned char *)&audio->priv.config.vorbis.headers[i] + sizeof( ogg_packet ); header_sizes[i] = ogg_headers[i]->bytes; } track->codecPrivate = mk_laceXiph(header_sizes, 2, &cp_size);@@ -195,22 +198,13 @@ } break; case HB_ACODEC_FAAC:- if( job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )- {- track->codecPrivate = NULL;- track->codecPrivateSize = 0;- track->codecID = MK_ACODEC_AC3;- }- else- {- track->codecPrivate = audio->config.aac.bytes;- track->codecPrivateSize = audio->config.aac.length;- track->codecID = MK_ACODEC_AAC;- }+ track->codecPrivate = audio->priv.config.aac.bytes;+ track->codecPrivateSize = audio->priv.config.aac.length;+ track->codecID = MK_ACODEC_AAC; break; default: *job->die = 1;- hb_error("muxmkv: Unknown audio codec: %x", job->acodec);+ hb_error("muxmkv: Unknown audio codec: %x", audio->config.out.codec); return 0; } @@ -221,12 +215,12 @@ } track->flagEnabled = 1; track->trackType = MK_TRACK_AUDIO;- track->language = audio->iso639_2;- track->extra.audio.samplingFreq = (float)job->arate;- track->extra.audio.channels = (job->acodec == HB_ACODEC_AC3 || job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown);+ track->language = audio->config.lang.iso639_2;+ track->extra.audio.samplingFreq = (float)audio->config.out.samplerate;+ track->extra.audio.channels = (audio->config.out.codec == HB_ACODEC_AC3 ) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->config.in.channel_layout) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); // track->defaultDuration = job->arate * 1000; mux_data->track = mk_createTrack(m->file, track);- if (job->acodec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)+ if (audio->config.out.codec == HB_ACODEC_VORBIS && track->codecPrivate != NULL) free(track->codecPrivate); } @@ -308,7 +302,7 @@ { /* 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)@@ -7,6 +7,7 @@ #include <stdarg.h> #include <time.h> #include <sys/time.h>+#include <assert.h> #include "common.h" @@ -43,9 +44,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 +114,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 +201,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 +214,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->config.out.codec ) {+ case HB_ACODEC_FAAC:+ case HB_ACODEC_VORBIS:+ samples_per_frame = 1024;+ break;+ case HB_ACODEC_LAME:+ samples_per_frame = 1152;+ break;+ case HB_ACODEC_AC3:+ samples_per_frame = 1536;+ break;+ default:+ return 0;+ }++ if( audio->config.out.codec == HB_ACODEC_AC3 ||+ audio->config.out.codec == HB_ACODEC_DCA)+ { /*- * For AC-3 we take the bitrate from the input audio+ * For pass through we take the bitrate from the input audio * bitrate as we are simply passing it through. */- audio = hb_list_item( title->list_audio, job->audios[i] );- abitrate = audio->bitrate / 8;+ abitrate = audio->config.in.bitrate / 8; } else {@@ -252,12 +252,12 @@ * Where we are transcoding the audio we use the destination * bitrate. */- abitrate = job->abitrate * 1000 / 8;+ abitrate = audio->config.out.bitrate * 1000 / 8; } avail -= length * abitrate; /* Audio overhead */- avail -= length * job->arate * overhead / samples_per_frame;+ avail -= length * audio->config.out.samplerate * overhead / samples_per_frame; } if( avail < 0 )@@ -654,3 +654,91 @@ *_f = NULL; } +/**********************************************************************+ * hb_audio_copy+ **********************************************************************+ *+ *********************************************************************/+hb_audio_t *hb_audio_copy(const hb_audio_t *src)+{+ hb_audio_t *audio = calloc(1, sizeof(*audio));+ memcpy(audio, src, sizeof(*audio));+ return audio;+}++/**********************************************************************+ * hb_audio_new+ **********************************************************************+ *+ *********************************************************************/+void hb_audio_config_init(hb_audio_config_t * audiocfg)+{+ /* Set read only paramaters to invalid values */+ audiocfg->in.codec = 0xDEADBEEF;+ audiocfg->in.bitrate = -1;+ audiocfg->in.samplerate = -1;+ audiocfg->in.channel_layout = 0;+ audiocfg->flags.ac3 = 0;+ audiocfg->lang.description[0] = 0;+ audiocfg->lang.simple[0] = 0;+ audiocfg->lang.iso639_2[0] = 0;++ /* Initalize some sensable defaults */+ audiocfg->in.track = audiocfg->out.track = 0;+ audiocfg->out.codec = HB_ACODEC_FAAC;+ audiocfg->out.bitrate = 128;+ audiocfg->out.samplerate = 44100;+ audiocfg->out.mixdown = HB_AMIXDOWN_DOLBYPLII;+ audiocfg->out.dynamic_range_compression = 0;+}++/**********************************************************************+ * hb_audio_add+ **********************************************************************+ *+ *********************************************************************/+int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg)+{+ assert(job != NULL);+ assert(audiocfg != NULL);++ hb_title_t *title = job->title;+ hb_audio_t *audio;++ audio = hb_audio_copy( hb_list_item( title->list_audio, audiocfg->in.track ) );+ if( audio == NULL )+ {+ /* We fail! */+ return 0;+ }++ if( (audiocfg->in.bitrate != -1) && (audiocfg->in.codec != 0xDEADBEEF) )+ {+ /* This most likely means the client didn't call hb_audio_config_init+ * so bail.+ */+ return 0;+ }++ /* Really shouldn't ignore the passed out track, but there is currently no+ * way to handle duplicates or out-of-order track numbers.+ */+ audio->config.out.track = hb_list_count(job->list_audio) + 1;+ audio->config.out.codec = audiocfg->out.codec;+ audio->config.out.samplerate = audiocfg->out.samplerate;+ audio->config.out.bitrate = audiocfg->out.bitrate;+ audio->config.out.mixdown = audiocfg->out.mixdown;+ audio->config.out.dynamic_range_compression = audiocfg->out.dynamic_range_compression;++ hb_list_add(job->list_audio, audio);+ return 1;+}++hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i)+{+ assert(list != NULL);++ hb_audio_t *audio = hb_list_item(list, i);++ return &(audio->config);+}Index: 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->config.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->config.out.bitrate < min_bitrate) {- hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", job->abitrate, pv->out_discrete_channels);+ hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", audio->config.out.bitrate, pv->out_discrete_channels); hb_log( "encvorbis: Resetting bitrate to %d kbps", min_bitrate);- job->abitrate = min_bitrate;+ /* Naughty! We shouldn't modify the audio from here. */+ audio->config.out.bitrate = min_bitrate; } /* init */ vorbis_info_init( &pv->vi ); if( vorbis_encode_setup_managed( &pv->vi, pv->out_discrete_channels,- job->arate, -1, 1000 * job->abitrate, -1 ) )+ audio->config.out.samplerate, -1, 1000 * audio->config.out.bitrate, -1 ) ) { hb_error( "encvorbis: vorbis_encode_setup_managed failed.\n" ); *job->die = 1;@@ -80,7 +82,7 @@ hb_log( "encvorbis: vorbis_encode_ctl( ratemanage2_get ) failed" ); } - ctl_rate_arg.bitrate_average_kbps = job->abitrate;+ ctl_rate_arg.bitrate_average_kbps = audio->config.out.bitrate; ctl_rate_arg.management_active = 1; if( vorbis_encode_ctl( &pv->vi, OV_ECTL_RATEMANAGE2_SET, &ctl_rate_arg ) ||Index: libhb/common.h===================================================================--- libhb/common.h (revision 1364)+++ libhb/common.h (working copy)@@ -39,6 +39,7 @@ typedef struct hb_title_s hb_title_t; typedef struct hb_chapter_s hb_chapter_t; typedef struct hb_audio_s hb_audio_t;+typedef struct hb_audio_config_s hb_audio_config_t; typedef struct hb_subtitle_s hb_subtitle_t; typedef struct hb_state_s hb_state_t; typedef union hb_esconfig_u hb_esconfig_t;@@ -53,6 +54,9 @@ #include "ports.h" #ifdef __LIBHB__ #include "internal.h"+#define PRIVATE+#else+#define PRIVATE const #endif hb_list_t * hb_list_init();@@ -70,6 +74,11 @@ int hb_calc_bitrate( hb_job_t *, int size ); +hb_audio_t *hb_audio_copy(const hb_audio_t *src);+void hb_audio_config_init(hb_audio_config_t * audiocfg);+int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg);+hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i);+ struct hb_rate_s { char * string;@@ -175,77 +184,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 +241,49 @@ #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 starts here */+/* Audio Codecs */+#define HB_ACODEC_MASK 0x00FF00+#define HB_ACODEC_FAAC 0x000100+#define HB_ACODEC_LAME 0x000200+#define HB_ACODEC_VORBIS 0x000400+#define HB_ACODEC_AC3 0x000800+#define HB_ACODEC_MPGA 0x001000+#define HB_ACODEC_LPCM 0x002000+#define HB_ACODEC_DCA 0x004000 - /* ac3flags is only set when the source audio format is HB_ACODEC_AC3 */- int ac3flags;+/* 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 ) ) - /* 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 +291,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 +302,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,24 +310,68 @@ #define HB_INPUT_CH_LAYOUT_GET_ENCODED_FRONT_COUNT( a ) ( ( a & HB_INPUT_CH_LAYOUT_ENCODED_FRONT_MASK ) >> 4 ) #define HB_INPUT_CH_LAYOUT_GET_ENCODED_REAR_COUNT( a ) ( ( a & HB_INPUT_CH_LAYOUT_ENCODED_REAR_MASK ) ) - /* input_channel_layout is the channel layout of this audio */- /* this is used to provide a common way of describing the source audio */- int input_channel_layout;+struct hb_audio_config_s+{+ /* Output */+ struct+ {+ int track; /* Output track number */+ uint32_t codec; /* Output audio codec.+ * HB_ACODEC_AC3 means pass-through, then bitrate and samplerate+ * are ignored.+ */+ int samplerate; /* Output sample rate (Hz) */+ int bitrate; /* Output bitrate (kbps) */+ int mixdown; /* The mixdown format to be used for this audio track (see HB_AMIXDOWN_*) */+ double dynamic_range_compression; /* Amount of DRC that gets applied to this track */+ } out; + /* Input */+ struct+ {+ int track; /* Input track number */+ PRIVATE uint32_t codec; /* Input audio codec */+ PRIVATE int samplerate; /* Input sample rate (Hz) */+ PRIVATE int bitrate; /* Input bitrate (kbps) */+ PRIVATE int channel_layout;+ /* channel_layout is the channel layout of this audio this is used to+ * provide a common way of describing the source audio+ */+ } in;++ /* Misc. */+ union+ {+ PRIVATE int ac3; /* flags.ac3 is only set when the source audio format is HB_ACODEC_AC3 */+ PRIVATE int dca; /* flags.dca is only set when the source audio format is HB_ACODEC_DCA */+ } flags;++ struct+ {+ PRIVATE char description[1024];+ PRIVATE char simple[1024];+ PRIVATE char iso639_2[4];+ } lang;+};+ #ifdef __LIBHB__- /* Internal data */- hb_fifo_t * fifo_in; /* AC3/MPEG/LPCM ES */- hb_fifo_t * fifo_raw; /* Raw audio */- hb_fifo_t * fifo_sync; /* Resampled, synced raw audio */- hb_fifo_t * fifo_out; /* MP3/AAC/Vorbis ES */+struct hb_audio_s+{+ int id; - hb_esconfig_t config;- hb_mux_data_t * mux_data;+ hb_audio_config_t config; - /* amixdown is the mixdown format to be used for this audio track */- int amixdown;+ struct {+ hb_fifo_t * fifo_in; /* AC3/MPEG/LPCM ES */+ hb_fifo_t * fifo_raw; /* Raw audio */+ hb_fifo_t * fifo_sync; /* Resampled, synced raw audio */+ hb_fifo_t * fifo_out; /* MP3/AAC/Vorbis ES */++ hb_esconfig_t config;+ hb_mux_data_t * mux_data;+ } priv;+}; #endif-}; struct hb_chapter_s {@@ -506,10 +516,8 @@ 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/HBQueueController.h===================================================================--- macosx/HBQueueController.h (revision 1364)+++ macosx/HBQueueController.h (working copy)@@ -106,6 +106,8 @@ int crf; NSString *x264opts; + NSString *audioinfo_codecs;+ NSString *audioinfo_summary; //<-hack to use a string to display all audio info for each job in one string int audio_mixdowns[8]; int acodec; int abitrate;Index: macosx/Controller.mm===================================================================--- macosx/Controller.mm (revision 1364)+++ macosx/Controller.mm (working copy)@@ -1467,7 +1467,7 @@ hb_title_t * title = (hb_title_t *) hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); hb_job_t * job = title->job;- //int i;+ hb_audio_config_t * audio; /* Chapter selection */ job->chapter_start = [fSrcChapterStartPopUp 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,119 @@ 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*/+ for( int i = 0; i < hb_list_count(job->list_audio);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];+ hb_audio_t * temp_audio = (hb_audio_t*) hb_list_item( job->list_audio, 0 );+ hb_list_rem(job->list_audio, temp_audio); }- 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_config_t *) hb_list_audio_config_item( title->list_audio, [fAudLang1PopUp indexOfSelectedItem] - 1);+ audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));+ hb_audio_config_init(audio);++ /* We go ahead and assign values to our audio->out.<properties> */+ audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;+ if ([[fAudTrack1MixPopUp titleOfSelectedItem] isEqualToString: @"AC3 Passthru"])+ {+ audio->out.codec = HB_ACODEC_AC3;+ audio->out.mixdown = HB_ACODEC_AC3;+ audio->out.bitrate = audio->in.bitrate / 1000; // we use the audio.in bitrate for passthru, / 1000 so it displays right.+ audio->out.samplerate = 48000;+ audio->out.dynamic_range_compression = 1.00;+ }+ else+ {+ audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;+ audio->out.mixdown = [[fAudTrack1MixPopUp selectedItem] tag];+ audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];+ audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;+ 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 );+ hb_audio_add( job, audio );+ free(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_config_t *) hb_list_audio_config_item( title->list_audio, [fAudLang1PopUp indexOfSelectedItem] - 1 );+ audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));+ hb_audio_config_init(audio);++ /* We go ahead and assign values to our audio->out.<properties> */+ audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;+ audio->out.codec = HB_ACODEC_AC3;+ audio->out.codec = HB_ACODEC_AC3;+ audio->out.samplerate = 48000;+ audio->out.bitrate = audio->in.bitrate / 1000; // we use the audio.in bitrate for passthru, / 1000 do it displays right.+ audio->out.mixdown = HB_ACODEC_AC3;//<-- Lets manually set the mixdown int+ audio->out.dynamic_range_compression = 1.00;+ /* We add the newly modified audio track to job->list_audio */+ //hb_list_add(job->list_audio, audio );+ hb_audio_add( job, audio );+ free(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_config_t *) hb_list_audio_config_item( title->list_audio, [fAudLang2PopUp indexOfSelectedItem] - 1 );+ /* Now we modify it according to the gui settings for the specified track number */+ audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));+ hb_audio_config_init(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;- }+ /* We go ahead and assign values to our audio->out.<properties> */+ audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;+ if ([[fAudTrack2MixPopUp titleOfSelectedItem] isEqualToString: @"AC3 Passthru"])+ {+ audio->out.codec = HB_ACODEC_AC3;+ audio->out.mixdown = HB_ACODEC_AC3;+ audio->out.bitrate = audio->in.bitrate / 1000; // we use the audio.in bitrate for passthru, / 1000 so it displays right.+ audio->out.samplerate = 48000;+ }+ else+ {+ audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;+ audio->out.mixdown = [[fAudTrack2MixPopUp selectedItem] tag];+ audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];+ audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;+ }+ 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 );+ hb_audio_add( job, audio );+ free(audio); - 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;- }+ /*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_config_t *) hb_list_audio_config_item( title->list_audio, [fAudLang2PopUp indexOfSelectedItem] - 1 );+ audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));+ hb_audio_config_init(audio); - 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;+ /* We go ahead and assign values to our audio->out.<properties> */+ audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;+ audio->out.codec = HB_ACODEC_AC3;+ audio->out.codec = HB_ACODEC_AC3;+ audio->out.samplerate = 48000;+ audio->out.bitrate = audio->in.bitrate / 1000; // we use the audio.in bitrate for passthru, / 1000 so it displays right.+ 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 );+ hb_audio_add( job, audio );+ free(audio);+ } } - /* 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 +1838,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];+ HBJobGroup * jobGroup = [HBJobGroup jobGroup]; // The job group can maintain meta data that libhb can not...- [jobGroup setPresetName: [fPresetSelectedDisplay stringValue]];+ [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++;+ static int jobGroupID = 0;+ 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.@@ -2787,17 +2840,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]];+ [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]];-+ /* 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@@ -2807,15 +2858,15 @@ hb_title_t * title = (hb_title_t*) hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] ); - hb_audio_t * audio;+ hb_audio_config_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_config_t *) hb_list_audio_config_item( title->list_audio, i ); [[sender menu] addItemWithTitle:- [NSString stringWithCString: audio->lang]+ [NSString stringWithCString: audio->lang.description] action: NULL keyEquivalent: @""]; } [sender selectItemAtIndex: 0];@@ -2889,7 +2940,7 @@ #endif /* pointer for the hb_audio_s struct we will use later on */- hb_audio_t * audio;+ hb_audio_config_t * audio; /* find out what the currently-selected output audio codec is */ int format = [fDstFormatPopUp indexOfSelectedItem];@@ -2900,11 +2951,11 @@ 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 */@@ -2933,114 +2984,113 @@ { /* get the audio */- audio = (hb_audio_t *) hb_list_item( fTitle->list_audio, thisAudioIndex );+ audio = (hb_audio_config_t *) hb_list_audio_config_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 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->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 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 (!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 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 ((!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 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->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 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->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 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);+ } - /* 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);- } /* 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 */@@ -3095,9 +3145,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 +3212,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>2008033101</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,62 @@ 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;+ /* So, with the advent of job->list_audio's I decided why not just use an NSString and concatanate+ all of the info we need for all of the audio values to display right into an NSString here ? So I+ did. I have no idea why we are reading libhb stuff just to display it in the queue gui. So here we+ are with a huge string. But its easy to change and saves alot of messing about. Maybe we move a bunch+ of other display stuff into strings for display for each job. It's not like they have to actually do+ anything.*/+ hb_audio_config_t * audio;+ NSString * thisJobAudioCodecs = [NSString stringWithFormat:@""];+ NSString * thisJobAudioInfo = [NSString stringWithFormat:@""]; // Setup a simple way to start the string+ for( int i = 0; i < hb_list_count(job->list_audio); i++ )+ {+ audio = (hb_audio_config_t *) hb_list_audio_config_item( job->list_audio, i );+ /* Output Codec */+ NSString *outputCodec;+ if (audio->out.codec == HB_ACODEC_AC3)+ outputCodec = @"AC3";+ else if (audio->out.codec == HB_ACODEC_FAAC)+ outputCodec = @"AAC";+ else if (audio->out.codec == HB_ACODEC_LAME)+ outputCodec = @"MP3";+ else if (audio->out.codec == HB_ACODEC_VORBIS)+ outputCodec = @"Vorbis";+ else+ outputCodec = @"Unknown Codec"; + /* Add the codec to the audio codecs list ( We should check against dupes)*/+ thisJobAudioCodecs = [thisJobAudioCodecs stringByAppendingString:[NSString stringWithFormat:@" %@,",outputCodec]];+ if (i > 0)+ {+ /* Insert a line break so that we get each track on a separate line */+ /* Wicked HACK alert!!, use 18 whitespaces to align offset in display for list > 2 to offset "Audio" in the queue display+ Please Fix Me because this is embarrassing (but it works) */+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:@"\n "];+ }+ /* Detailed Job audio track info*/+ /* Track Number and Mixdown Info */+ if (audio->out.mixdown == HB_ACODEC_AC3)// Remember for ac3 passthru the mixdown uses the source codec+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@" - Track %d: Source: %@ Output: %@, Pass-Thru", i + 1, [NSString stringWithUTF8String:audio->lang.description], outputCodec]];+ else if (audio->out.mixdown == HB_AMIXDOWN_MONO)+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@" - Track %d: Source: %@ Output: %@, Mono", i + 1, [NSString stringWithUTF8String:audio->lang.description], outputCodec]];+ else if (audio->out.mixdown == HB_AMIXDOWN_STEREO)+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@" - Track %d: Source: %@ Output: %@, Stereo", i + 1, [NSString stringWithUTF8String:audio->lang.description], outputCodec]];+ else if (audio->out.mixdown == HB_AMIXDOWN_DOLBY)+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@" - Track %d: Source: %@ Output: %@, Dolby Surround", i + 1, [NSString stringWithUTF8String:audio->lang.description], outputCodec]];+ else if (audio->out.mixdown == HB_AMIXDOWN_DOLBYPLII)+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@" - Track %d: Source: %@ Output: %@, Dolby Pro Logic II", i + 1, [NSString stringWithUTF8String:audio->lang.description], outputCodec]];+ else if (audio->out.mixdown == HB_AMIXDOWN_6CH)+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@" - Track %d: Source: %@ Output: %@, 6 Channel Discreet", i + 1, [NSString stringWithUTF8String:audio->lang.description], outputCodec]];+ else+ thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@" - Track %d: Source: %@ Output: Unknown Codec Info", i + 1, [NSString stringWithUTF8String:audio->lang.description]]];+ + thisJobAudioInfo = [thisJobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", %d kbps, %d Hz", audio->out.bitrate, audio->out.samplerate]];+ + }+ audioinfo_summary = [[NSString stringWithFormat:@"%@",thisJobAudioInfo]retain];+ audioinfo_codecs = [[NSString stringWithFormat:@"%@",thisJobAudioCodecs]retain];+ subtitle = job->subtitle; mux = job->mux; if (job->file)@@ -197,6 +249,8 @@ [file release]; [titleName release]; [subtitleLang release];+ [audioinfo_summary release];+ [audioinfo_codecs release]; [super dealloc]; } @@ -407,9 +461,9 @@ jobFormatInfo = @"unknown"; if (chapter_markers == 1)- jobFormatInfo = [NSString stringWithFormat:@"%@ Container, %@ Video + %@ Audio, Chapter Markers\n", jobFormatInfo, jobVideoCodec, jobAudioCodec];+ jobFormatInfo = [NSString stringWithFormat:@"%@ Container, %@ Video + %@ Audio, Chapter Markers\n", jobFormatInfo, jobVideoCodec, audioinfo_codecs]; else- jobFormatInfo = [NSString stringWithFormat:@"%@ Container, %@ Video + %@ Audio\n", jobFormatInfo, jobVideoCodec, jobAudioCodec];+ jobFormatInfo = [NSString stringWithFormat:@"%@ Container, %@ Video + %@ Audio\n", jobFormatInfo, jobVideoCodec, audioinfo_codecs]; [finalString appendString: @"Format: " withAttributes:detailBoldAttr]; [finalString appendString: jobFormatInfo withAttributes:detailAttr];@@ -497,34 +551,10 @@ if (withAudioInfo) {- NSString * jobAudioInfo;- if ([jobAudioCodec isEqualToString: @"AC3"])- jobAudioInfo = [NSString stringWithFormat:@"%@, Pass-Through", jobAudioCodec];- else- jobAudioInfo = [NSString stringWithFormat:@"%@, %d kbps, %d Hz", jobAudioCodec, abitrate, arate];- - // we now get the audio mixdown info for each of the two gui audio tracks- // lets do it the long way here to get a handle on things.- // Hardcoded for two tracks for gui: audio_mixdowns[i] audio_mixdowns[i]- int ai; // counter for each audios [] , macgui only allows for two audio tracks currently- for( ai = 0; ai < 2; ai++ )- {- if (audio_mixdowns[ai] == HB_AMIXDOWN_MONO)- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Mono", ai + 1]];- if (audio_mixdowns[ai] == HB_AMIXDOWN_STEREO)- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Stereo", ai + 1]];- if (audio_mixdowns[ai] == HB_AMIXDOWN_DOLBY)- 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 (withIcon) // implies indent the info [finalString appendString: @"\t" withAttributes:detailBoldAttr]; [finalString appendString: @"Audio: " withAttributes:detailBoldAttr];- [finalString appendString:[NSString stringWithFormat:@"%@\n", jobAudioInfo] withAttributes:detailAttr];+ [finalString appendString:[NSString stringWithFormat:@"%@\n", audioinfo_summary] withAttributes:detailAttr]; } if (withSubtitleInfo)