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_t * audio = NULL;
+static int num_audio_tracks = 0;
+static char * mixdowns = NULL;
+static char * dynamic_range_compression = NULL;
+static char * arates = NULL;
+static char * abitrates = NULL;
+static char * acodecs = NULL;
+static int default_acodec = HB_ACODEC_FAAC;
+static int default_arate = 44100;
+static int default_abitrate = 128;
static int sub = 0;
static int width = 0;
static int height = 0;
static int crop[4] = { -1,-1,-1,-1 };
static int cpu = 0;
static int vrate = 0;
-static int arate = 0;
static float vquality = -1.0;
static int vbitrate = 0;
static int size = 0;
-static int abitrate = 0;
static int mux = 0;
-static int acodec = 0;
static int pixelratio = 0;
static int loosePixelratio = 0;
static int modulus = 0;
@@ -87,6 +92,9 @@
static int CheckOptions( int argc, char ** argv );
static int HandleEvents( hb_handle_t * h );
+static int get_acodec_for_string( char *codec );
+static int is_sample_rate_valid(int rate);
+
/* Only print the "Muxing..." message once */
static int show_mux_warning = 1;
@@ -107,6 +115,8 @@
int build;
char * version;
+ audios = hb_list_init();
+
/* Parse command line */
if( ParseOptions( argc, argv ) ||
CheckOptions( argc, argv ) )
@@ -230,7 +240,20 @@
if( input ) free( input );
if( output ) free( output );
if( format ) free( format );
- if( audios ) free( audios );
+ if( audios )
+ {
+ while( ( audio = hb_list_item( audios, 0 ) ) )
+ {
+ hb_list_rem( audios, audio );
+ free( audio );
+ }
+ hb_list_close( &audios );
+ }
+ if( mixdowns ) free( mixdowns );
+ if( dynamic_range_compression ) free( dynamic_range_compression );
+ if( arates ) free( arates );
+ if( abitrates ) free( abitrates );
+ if( acodecs ) free( acodecs );
if (native_language ) free (native_language );
if( x264opts ) free (x264opts );
if( x264opts2 ) free (x264opts2 );
@@ -283,14 +306,14 @@
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
audio = hb_list_item( title->list_audio, i );
- if( ( audio->codec & HB_ACODEC_AC3 ) || ( audio->codec & HB_ACODEC_DCA) )
+ if( ( audio->in.codec == HB_ACODEC_AC3 ) || ( audio->in.codec == HB_ACODEC_DCA) )
{
fprintf( stderr, " + %d, %s, %dHz, %dbps\n", i + 1,
- audio->lang, audio->rate, audio->bitrate );
+ audio->lang.description, audio->in.samplerate, audio->in.bitrate );
}
else
{
- fprintf( stderr, " + %d, %s\n", i + 1, audio->lang );
+ fprintf( stderr, " + %d, %s\n", i + 1, audio->lang.description );
}
}
fprintf( stderr, " + subtitle tracks:\n" );
@@ -300,13 +323,13 @@
fprintf( stderr, " + %d, %s (iso639-2: %s)\n", i + 1, subtitle->lang,
subtitle->iso639_2);
}
-
+
if(title->detected_interlacing)
{
/* Interlacing was found in half or more of the preview frames */
fprintf( stderr, " + combing detected, may be interlaced or telecined\n");
}
-
+
}
static int HandleEvents( hb_handle_t * h )
@@ -334,7 +357,16 @@
hb_list_t * list;
hb_title_t * title;
hb_job_t * job;
+ int i;
+ /* Audio argument string parsing variables */
+ int acodec = 0;
+ int abitrate = 0;
+ int arate = 0;
+ int mixdown = HB_AMIXDOWN_DOLBYPLII;
+ double d_r_c = 0;
+ /* Audio argument string parsing variables */
+
list = hb_get_titles( h );
if( !hb_list_count( list ) )
@@ -419,9 +451,9 @@
mux = HB_MUX_MKV;
vcodec = HB_VCODEC_X264;
job->vbitrate = 1000;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
x264opts = strdup("ref=5:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2");
deinterlace = 1;
deinterlace_opt = "0";
@@ -433,15 +465,26 @@
if (!strcmp(preset_name, "AppleTV"))
{
+ if (hb_list_count(audios) == 0)
+ {
+ audio = hb_audio_new();
+ audio->in.track = audio->out.track = 0;
+ hb_list_add(audios, audio);
+
+ audio = hb_audio_new();
+ audio->in.track = 0;
+ audio->out.track = 1;
+ hb_list_add(audios, audio);
+ if (acodecs) free(acodecs);
+ acodecs = strdup("faac,ac3");
+ }
mux = HB_MUX_MP4;
job->largeFileSize = 1;
vcodec = HB_VCODEC_X264;
job->vbitrate = 2500;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
- audio_mixdown = HB_AMIXDOWN_DOLBYPLII_AC3;
- arate = 48000;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
x264opts = strdup("bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0");
job->chapter_markers = 1;
pixelratio = 1;
@@ -452,7 +495,7 @@
mux = HB_MUX_MKV;
vcodec = HB_VCODEC_X264;
job->vbitrate = 1800;
- acodec = HB_ACODEC_AC3;
+ default_acodec = HB_ACODEC_AC3;
x264opts = strdup("ref=16:mixed-refs:bframes=16:bime:weightb:b-rdo:direct=auto:b-pyramid:me=esa:subme=7:me-range=64:analyse=all:8x8dct:trellis=1:no-fast-pskip:no-dct-decimate:filter=-2,-1");
job->chapter_markers = 1;
pixelratio = 1;
@@ -464,9 +507,9 @@
{
mux = HB_MUX_MP4;
job->vbitrate = 512;
- job->abitrate = 128;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 128;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
job->width = 512;
job->chapter_markers = 1;
}
@@ -476,9 +519,9 @@
mux = HB_MUX_MP4;
vcodec = HB_VCODEC_X264;
size = 695;
- job->abitrate = 128;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 128;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
job->width = 640;
x264opts = strdup("ref=3:mixed-refs:bframes=16:bime:weightb:b-rdo:b-pyramid:direct=auto:me=umh:subme=6:trellis=1:analyse=all:8x8dct:no-fast-pskip");
job->chapter_markers = 1;
@@ -490,9 +533,9 @@
{
mux = HB_MUX_MP4;
job->vbitrate = 1000;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
}
if (!strcmp(preset_name, "Constant Quality Rate"))
@@ -501,7 +544,7 @@
vcodec = HB_VCODEC_X264;
job->vquality = 0.64709997177124023;
job->crf = 1;
- acodec = HB_ACODEC_AC3;
+ default_acodec = HB_ACODEC_AC3;
x264opts = strdup("ref=3:mixed-refs:bframes=3:b-pyramid:b-rdo:bime:weightb:filter=-2,-1:subme=6:trellis=1:analyse=all:8x8dct:me=umh");
job->chapter_markers = 1;
pixelratio = 1;
@@ -512,7 +555,7 @@
mux = HB_MUX_MKV;
vcodec = HB_VCODEC_X264;
job->vbitrate = 1600;
- acodec = HB_ACODEC_AC3;
+ default_acodec = HB_ACODEC_AC3;
x264opts = strdup("ref=5:mixed-refs:bframes=3:bime:weightb:b-rdo:b-pyramid:me=umh:subme=7:trellis=1:analyse=all:8x8dct:no-fast-pskip");
job->chapter_markers = 1;
pixelratio = 1;
@@ -525,7 +568,7 @@
mux = HB_MUX_MKV;
vcodec = HB_VCODEC_X264;
job->vbitrate = 1800;
- acodec = HB_ACODEC_AC3;
+ default_acodec = HB_ACODEC_AC3;
x264opts = strdup("ref=3:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip");
job->chapter_markers = 1;
pixelratio = 1;
@@ -539,9 +582,9 @@
job->ipod_atom = 1;
vcodec = HB_VCODEC_X264;
job->vbitrate = 960;
- job->abitrate = 128;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 128;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
job->width = 480;
x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=1");
job->chapter_markers = 1;
@@ -553,9 +596,9 @@
job->ipod_atom = 1;
vcodec = HB_VCODEC_X264;
job->vbitrate = 1500;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
job->width = 640;
x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1");
job->chapter_markers = 1;
@@ -567,9 +610,9 @@
job->ipod_atom = 1;
vcodec = HB_VCODEC_X264;
job->vbitrate = 700;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
job->width = 320;
x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1");
job->chapter_markers = 1;
@@ -580,9 +623,9 @@
mux = HB_MUX_MP4;
vcodec = HB_VCODEC_X264;
job->vbitrate = 1500;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
x264opts = strdup("ref=2:bframes=2:subme=5:me=umh");
job->chapter_markers = 1;
pixelratio = 1;
@@ -595,9 +638,9 @@
mux = HB_MUX_MP4;
vcodec = HB_VCODEC_X264;
job->vbitrate = 2500;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
x264opts = strdup("level=41:subme=5:me=umh");
pixelratio = 1;
}
@@ -606,9 +649,9 @@
{
mux = HB_MUX_MP4;
job->vbitrate = 1024;
- job->abitrate = 128;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 128;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
job->width = 368;
job->height = 208;
job->chapter_markers = 1;
@@ -619,9 +662,9 @@
mux = HB_MUX_MP4;
vcodec = HB_VCODEC_X264;
job->vbitrate = 2000;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
x264opts = strdup("ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:me=umh:subme=5:analyse=all:trellis=1:no-fast-pskip");
job->chapter_markers = 1;
pixelratio = 1;
@@ -634,9 +677,9 @@
mux = HB_MUX_MKV;
vcodec = HB_VCODEC_X264;
job->vbitrate = 1300;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
x264opts = strdup("ref=3:mixed-refs:bframes=6:bime:weightb:direct=auto:b-pyramid:me=umh:subme=6:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip");
deinterlace = 1;
deinterlace_opt = "0";
@@ -652,9 +695,9 @@
mux = HB_MUX_MP4;
vcodec = HB_VCODEC_X264;
job->vbitrate = 2000;
- job->abitrate = 160;
- job->arate = 48000;
- acodec = HB_ACODEC_FAAC;
+ default_abitrate = 160;
+ default_arate = 48000;
+ default_acodec = HB_ACODEC_FAAC;
x264opts = strdup("level=40:ref=2:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:no-fast-pskip:filter=-2,-1");
pixelratio = 1;
}
@@ -732,13 +775,13 @@
{
job->pixel_ratio = pixelratio;
}
-
+
if (vfr)
{
detelecine = 1;
job->vfr = 1;
}
-
+
/* Add selected filters */
job->filters = hb_list_init();
if( detelecine )
@@ -816,74 +859,228 @@
job->vrate = 27000000;
job->vrate_base = vrate;
}
- if( arate )
+
+ /* Parse audio tracks */
+ if( hb_list_count(audios) == 0 )
{
- job->arate = arate;
+ /* Create a new audio track with default settings */
+ audio = hb_audio_new();
+ /* Add it to our audios */
+ hb_list_add(audios, audio);
}
+ num_audio_tracks = hb_list_count(audios);
- if( audios )
+ for (i = 0; i < num_audio_tracks; i++)
{
- if( strcasecmp( audios, "none" ) )
+ audio = hb_list_item(audios, i);
+ if ( (audio->in.track == -1) || (audio->out.track == -1) ||
+ (audio->out.codec == 0) )
{
- int audio_count = 0;
- char * tmp = audios;
- while( *tmp )
+ num_audio_tracks--;
+ hb_list_rem(audios, audio);
+ free(audio);
+ continue;
+ }
+ hb_list_add(job->list_audio, hb_audio_copy( hb_list_item( title->list_audio, audio->in.track ) ) );
+ }
+ /* Audio Tracks */
+
+ /* Audio Codecs */
+ i = 0;
+ if( acodecs )
+ {
+ char * token = strtok(acodecs, ",");
+ if (token == NULL)
+ token = acodecs;
+ while ( token != NULL )
+ {
+ if ((acodec = get_acodec_for_string(token)) == -1)
{
- if( *tmp < '0' || *tmp > '9' )
+ fprintf(stderr, "Invalid codec %s, using default for container.\n", token);
+ acodec = default_acodec;
+ }
+ audio = hb_list_item(job->list_audio, i);
+ audio->out.codec = acodec;
+ if( (++i) >= num_audio_tracks )
+ break; /* We have more inputs than audio tracks, oops */
+ token = strtok(NULL, ",");
+ }
+ }
+ if (i < num_audio_tracks)
+ {
+ /* We have fewer inputs than audio tracks, use the default codec for
+ * this container for the remaining tracks. Unless we only have one input
+ * then use that codec instead.
+ */
+ if (i != 1)
+ acodec = default_acodec;
+ for ( ; i < num_audio_tracks; i++)
+ {
+ audio = hb_list_item(job->list_audio, i);
+ audio->out.codec = acodec;
+ }
+ }
+ /* Audio Codecs */
+
+ /* Sample Rate */
+ i = 0;
+ if( arates )
+ {
+ char * token = strtok(arates, ",");
+ if (token == NULL)
+ token = arates;
+ while ( token != NULL )
+ {
+ arate = atoi(token);
+ audio = hb_list_item(job->list_audio, i);
+ if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+ {
+ /* Would probably be better to have this handled in libhb. */
+ audio->out.samplerate = audio->in.samplerate;
+ }
+ else
+ {
+ if (!is_sample_rate_valid(arate))
{
- /* Skip non numeric char */
- tmp++;
- continue;
+ fprintf(stderr, "Invalid sample rate %d, using default\n", arate);
+ arate = default_arate;
}
- job->audio_mixdowns[audio_count] = audio_mixdown;
- job->audios[audio_count++] =
- strtol( tmp, &tmp, 0 ) - 1;
+ audio->out.samplerate = arate;
}
- job->audios[audio_count] = -1;
+ if( (++i) >= num_audio_tracks )
+ break; /* We have more inputs than audio tracks, oops */
+ token = strtok(NULL, ",");
}
- else
+ }
+ if (i < num_audio_tracks)
+ {
+ /* We have fewer inputs than audio tracks, use default sample rate.
+ * Unless we only have one input, then use that for all tracks.
+ */
+ if (i != 1)
+ arate = default_arate;
+ for ( ; i < num_audio_tracks; i++)
{
- job->audios[0] = -1;
+ audio = hb_list_item(job->list_audio, i);
+ if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+ {
+ audio->out.samplerate = audio->in.samplerate;
+ continue;
+ }
+ audio->out.samplerate = arate;
}
}
- else
- {
- /* default to the first audio track if none has been specified */
- job->audios[0] = 0;
- job->audio_mixdowns[0] = audio_mixdown;
- }
+ /* Sample Rate */
- if( audio_mixdown == HB_AMIXDOWN_DOLBYPLII_AC3)
- {
- int i;
- for( i = 3 ; i > 0; i--)
- {
- job->audios[i*2+1] = job->audios[i];
- job->audios[i*2] = job->audios[i];
- if(job->audios[i] != -1 )
- {
- job->audio_mixdowns[i*2+1] = HB_AMIXDOWN_AC3;
- job->audio_mixdowns[i*2] = HB_AMIXDOWN_DOLBYPLII;
- }
- }
-
- job->audios[1] = job->audios[0];
- job->audio_mixdowns[1] = HB_AMIXDOWN_AC3;
- job->audio_mixdowns[0] = HB_AMIXDOWN_DOLBYPLII;
+ /* Audio Bitrate */
+ i = 0;
+ if( abitrates )
+ {
+ char * token = strtok(abitrates, ",");
+ if (token == NULL)
+ token = abitrates;
+ while ( token != NULL )
+ {
+ abitrate = atoi(token);
+ audio = hb_list_item(job->list_audio, i);
+ if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+ {
+ audio->out.bitrate = audio->in.bitrate; /* See note above about arate. */
+ }
+ else
+ {
+ audio->out.bitrate = abitrate;
+ }
+ if( (++i) >= num_audio_tracks )
+ break; /* We have more inputs than audio tracks, oops */
+ token = strtok(NULL, ",");
+ }
}
+ if (i < num_audio_tracks)
+ {
+ /* We have fewer inputs than audio tracks, use the default bitrate
+ * for the remaining tracks. Unless we only have one input, then use
+ * that for all tracks.
+ */
+ if (i != 1)
+ abitrate = default_abitrate;
+ for (; i < num_audio_tracks; i++)
+ {
+ audio = hb_list_item(job->list_audio, i);
+ if (audio->out.codec == HB_ACODEC_AC3 || audio->out.codec == HB_ACODEC_DCA)
+ {
+ audio->out.bitrate = audio->in.bitrate;
+ continue;
+ }
+ audio->out.bitrate = abitrate;
+ }
+ }
+ /* Audio Bitrate */
- if( abitrate )
+ /* Audio DRC */
+ i = 0;
+ if ( dynamic_range_compression )
{
- job->abitrate = abitrate;
+ char * token = strtok(dynamic_range_compression, ",");
+ if (token == NULL)
+ token = dynamic_range_compression;
+ while ( token != NULL )
+ {
+ d_r_c = atof(token);
+ audio = hb_list_item(job->list_audio, i);
+ audio->out.dynamic_range_compression = d_r_c;
+ if( (++i) >= num_audio_tracks )
+ break; /* We have more inputs than audio tracks, oops */
+ token = strtok(NULL, ",");
+ }
}
- if( acodec )
+ if (i < num_audio_tracks)
{
- job->acodec = acodec;
+ /* We have fewer inputs than audio tracks, use no DRC for the remaining
+ * tracks. Unless we only have one input, then use the same DRC for all
+ * tracks.
+ */
+ if (i != 1)
+ d_r_c = 0;
+ for (; i < num_audio_tracks; i++)
+ {
+ audio = hb_list_item(job->list_audio, i);
+ audio->out.dynamic_range_compression = d_r_c;
+ }
}
- if ( dynamic_range_compression )
+ /* Audio DRC */
+
+ /* Audio Mixdown */
+ i = 0;
+ if ( mixdowns )
{
- job->dynamic_range_compression = dynamic_range_compression;
+ char * token = strtok(mixdowns, ",");
+ if (token == NULL)
+ token = mixdowns;
+ while ( token != NULL )
+ {
+ mixdown = hb_mixdown_get_mixdown_from_short_name(token);
+ audio = hb_list_item(job->list_audio, i);
+ audio->out.mixdown = mixdown;
+ if( (++i) >= num_audio_tracks )
+ break; /* We have more inputs than audio tracks, oops */
+ token = strtok(NULL, ",");
+ }
}
+ if (i < num_audio_tracks)
+ {
+ /* We have fewer inputs than audio tracks, use DPLII for the rest. Unless
+ * we only have one input, then use that.
+ */
+ if (i != 1)
+ mixdown = HB_AMIXDOWN_DOLBYPLII;
+ for (; i < num_audio_tracks; i++)
+ {
+ audio = hb_list_item(job->list_audio, i);
+ audio->out.mixdown = mixdown;
+ }
+ }
+ /* Audio Mixdown */
if( size )
{
@@ -1227,18 +1424,21 @@
"### Audio Options-----------------------------------------------------------\n\n"
- " -E, --aencoder <string> Audio encoder (faac/lame/vorbis/ac3/aac+ac3) \n"
- " ac3 meaning passthrough, aac+ac3 meaning an\n"
- " aac dpl2 mixdown paired with ac3 pass-thru\n"
+ " -a, --audio <string> Select audio channel(s), separated by commas\n"
+ " More than one output track can be used for one\n"
+ " input.\n"
+ " (\"none\" for no audio, \"1,2,3\" for multiple\n"
+ " tracks, default: first one)\n"
+ " -E, --aencoder <string> Audio encoder(s) (faac/lame/vorbis/ac3) \n"
+ " ac3 meaning passthrough\n"
+ " Seperated by commas for more than one audio track.\n"
" (default: guessed)\n"
- " -B, --ab <kb/s> Set audio bitrate (default: 128)\n"
- " -a, --audio <string> Select audio channel(s), separated by commas\n"
- " (\"none\" for no audio, \"1,2,3\" for multiple\n"
- " tracks, default: first one,\n"
- " max 8 normally, max 4 with aac+ac3)\n"
- " -6, --mixdown <string> Format for surround sound downmixing\n"
+ " -B, --ab <kb/s> Set audio bitrate(s) (default: 128)\n"
+ " Seperated by commas for more than one audio track.\n"
+ " -6, --mixdown <string> Format(s) for surround sound downmixing\n"
+ " Seperated by commas for more than one audio track.\n"
" (mono/stereo/dpl1/dpl2/6ch, default: dpl2)\n"
- " -R, --arate Set audio samplerate (" );
+ " -R, --arate Set audio samplerate(s) (" );
for( i = 0; i < hb_audio_rates_count; i++ )
{
fprintf( stderr, hb_audio_rates[i].string );
@@ -1246,9 +1446,11 @@
fprintf( stderr, "/" );
}
fprintf( stderr, " kHz)\n"
+ " Seperated by commas for more than one audio track.\n"
" -D, --drc <float> Apply extra dynamic range compression to the audio,\n"
" making soft sounds louder. Range is 1.0 to 4.0\n"
" (too loud), with 1.5 - 2.5 being a useful range.\n"
+ " Seperated by commas for more than one audio track.\n"
"\n"
@@ -1461,33 +1663,64 @@
chapter_markers = 1;
break;
case 'a':
- audios = strdup( optarg );
+ {
+ char * token = strtok(optarg, ",");
+ if (token == NULL)
+ token = optarg;
+ int track_start, track_end;
+ while( token != NULL )
+ {
+ audio = hb_audio_new();
+ if (strlen(token) >= 3)
+ {
+ if (sscanf(token, "%d-%d", &track_start, &track_end) == 2)
+ {
+ int i;
+ for (i = track_start - 1; i < track_end; i++)
+ {
+ if (i != track_start - 1)
+ audio = hb_audio_new();
+ audio->in.track = i;
+ audio->out.track = num_audio_tracks++;
+ hb_list_add(audios, audio);
+ }
+ }
+ else if( !strcasecmp(token, "none" ) )
+ {
+ audio->in.track = audio->out.track = -1;
+ audio->out.codec = 0;
+ hb_list_add(audios, audio);
+ break;
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Unable to parse audio input \"%s\", skipping.",
+ token);
+ free(audio);
+ }
+ }
+ else
+ {
+ audio->in.track = atoi(token) - 1;
+ audio->out.track = num_audio_tracks++;
+ hb_list_add(audios, audio);
+ }
+ token = strtok(NULL, ",");
+ }
break;
+ }
case '6':
- if( !strcasecmp( optarg, "mono" ) )
+ if( optarg != NULL )
{
- audio_mixdown = HB_AMIXDOWN_MONO;
+ mixdowns = strdup( optarg );
}
- else if( !strcasecmp( optarg, "stereo" ) )
+ break;
+ case 'D':
+ if( optarg != NULL )
{
- audio_mixdown = HB_AMIXDOWN_STEREO;
+ dynamic_range_compression = strdup( optarg );
}
- else if( !strcasecmp( optarg, "dpl1" ) )
- {
- audio_mixdown = HB_AMIXDOWN_DOLBY;
- }
- else if( !strcasecmp( optarg, "dpl2" ) )
- {
- audio_mixdown = HB_AMIXDOWN_DOLBYPLII;
- }
- else if( !strcasecmp( optarg, "6ch" ) )
- {
- audio_mixdown = HB_AMIXDOWN_6CH;
- }
break;
- case 'D':
- dynamic_range_compression = atof( optarg );
- break;
case 's':
sub = atoi( optarg );
break;
@@ -1608,28 +1841,10 @@
}
break;
case 'E':
- if( !strcasecmp( optarg, "ac3" ) )
+ if( optarg != NULL )
{
- acodec = HB_ACODEC_AC3;
+ acodecs = strdup( optarg );
}
- else if( !strcasecmp( optarg, "lame" ) )
- {
- acodec = HB_ACODEC_LAME;
- }
- else if( !strcasecmp( optarg, "faac" ) )
- {
- acodec = HB_ACODEC_FAAC;
- }
- else if( !strcasecmp( optarg, "vorbis") )
- {
- acodec = HB_ACODEC_VORBIS;
- }
- else if( !strcasecmp( optarg, "aac+ac3") )
- {
- acodec = HB_ACODEC_FAAC;
- audio_mixdown = HB_AMIXDOWN_DOLBYPLII_AC3;
- arate = 48000;
- }
break;
case 'w':
width = atoi( optarg );
@@ -1669,23 +1884,11 @@
break;
}
case 'R':
- {
- int i;
- arate = 0;
- for( i = 0; i < hb_audio_rates_count; i++ )
+ if( optarg != NULL )
{
- if( !strcmp( optarg, hb_audio_rates[i].string ) )
- {
- arate = hb_audio_rates[i].rate;
- break;
- }
+ arates = strdup( optarg );
}
- if( !arate )
- {
- fprintf( stderr, "invalid framerate %s\n", optarg );
- }
break;
- }
case 'b':
vbitrate = atoi( optarg );
break;
@@ -1696,7 +1899,10 @@
size = atoi( optarg );
break;
case 'B':
- abitrate = atoi( optarg );
+ if( optarg != NULL )
+ {
+ abitrates = strdup( optarg );
+ }
break;
case 'Q':
crf = 0;
@@ -1810,23 +2016,23 @@
return 1;
}
- if( !acodec )
+ if( !acodecs )
{
if( mux == HB_MUX_MP4 || mux == HB_MUX_IPOD )
{
- acodec = HB_ACODEC_FAAC;
+ default_acodec = HB_ACODEC_FAAC;
}
else if( mux == HB_MUX_AVI )
{
- acodec = HB_ACODEC_LAME;
+ default_acodec = HB_ACODEC_LAME;
}
else if( mux == HB_MUX_OGM )
{
- acodec = HB_ACODEC_VORBIS;
+ default_acodec = HB_ACODEC_VORBIS;
}
else if( mux == HB_MUX_MKV )
{
- acodec = HB_ACODEC_AC3;
+ default_acodec = HB_ACODEC_AC3;
}
}
@@ -1834,3 +2040,42 @@
return 0;
}
+
+static int get_acodec_for_string( char *codec )
+{
+ if( !strcasecmp( codec, "ac3" ) )
+ {
+ return HB_ACODEC_AC3;
+ }
+ else if( !strcasecmp( codec, "dts" ) || !strcasecmp( codec, "dca" ) )
+ {
+ return HB_ACODEC_DCA;
+ }
+ else if( !strcasecmp( codec, "lame" ) )
+ {
+ return HB_ACODEC_LAME;
+ }
+ else if( !strcasecmp( codec, "faac" ) )
+ {
+ return HB_ACODEC_FAAC;
+ }
+ else if( !strcasecmp( codec, "vorbis") )
+ {
+ return HB_ACODEC_VORBIS;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static int is_sample_rate_valid(int rate)
+{
+ int i;
+ for( i = 0; i < hb_audio_rates_count; i++ )
+ {
+ if (rate == hb_audio_rates[i].rate)
+ return 1;
+ }
+ return 0;
+}
Index: libhb/deca52.c
===================================================================
--- libhb/deca52.c (revision 1364)
+++ libhb/deca52.c (working copy)
@@ -88,6 +88,7 @@
int deca52Init( hb_work_object_t * w, hb_job_t * job )
{
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ hb_audio_t * audio = w->audio;
w->private_data = pv;
pv->job = job;
@@ -98,14 +99,14 @@
/* Decide what format we want out of a52dec
work.c has already done some of this deduction for us in do_job() */
- pv->flags_out = HB_AMIXDOWN_GET_A52_FORMAT(w->amixdown);
+ pv->flags_out = HB_AMIXDOWN_GET_A52_FORMAT(audio->out.mixdown);
/* pass the number of channels used into the private work data */
/* will only be actually used if we're not doing AC3 passthru */
- pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown);
pv->level = 32768.0;
- pv->dynamic_range_compression = job->dynamic_range_compression;
+ pv->dynamic_range_compression = audio->out.dynamic_range_compression;
pv->next_expected_pts = 0;
pv->sequence = 0;
@@ -168,6 +169,7 @@
{
hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
+ hb_audio_t * audio = w->audio;
int i, j, k;
uint64_t pts, pos;
@@ -219,8 +221,7 @@
}
/* AC3 passthrough: don't decode the AC3 frame */
- if( pv->job->acodec & HB_ACODEC_AC3 ||
- w->amixdown == HB_AMIXDOWN_AC3 )
+ if( audio->out.codec == HB_ACODEC_AC3 )
{
buf = hb_buffer_init( pv->size );
memcpy( buf->data, pv->frame, pv->size );
Index: libhb/enclame.c
===================================================================
--- libhb/enclame.c (revision 1364)
+++ libhb/enclame.c (working copy)
@@ -39,6 +39,7 @@
int enclameInit( hb_work_object_t * w, hb_job_t * job )
{
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ hb_audio_t * audio = w->audio;
w->private_data = pv;
pv->job = job;
@@ -46,9 +47,9 @@
hb_log( "enclame: opening libmp3lame" );
pv->lame = lame_init();
- lame_set_brate( pv->lame, job->abitrate );
- lame_set_in_samplerate( pv->lame, job->arate );
- lame_set_out_samplerate( pv->lame, job->arate );
+ lame_set_brate( pv->lame, audio->out.bitrate );
+ lame_set_in_samplerate( pv->lame, audio->out.samplerate );
+ lame_set_out_samplerate( pv->lame, audio->out.samplerate );
lame_init_params( pv->lame );
pv->input_samples = 1152 * 2;
@@ -85,6 +86,7 @@
static hb_buffer_t * Encode( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
+ hb_audio_t * audio = w->audio;
hb_buffer_t * buf;
int16_t samples_s16[1152 * 2];
uint64_t pts, pos;
@@ -104,8 +106,8 @@
}
buf = hb_buffer_init( pv->output_bytes );
- buf->start = pts + 90000 * pos / 2 / sizeof( float ) / pv->job->arate;
- buf->stop = buf->start + 90000 * 1152 / pv->job->arate;
+ buf->start = pts + 90000 * pos / 2 / sizeof( float ) / audio->out.samplerate;
+ buf->stop = buf->start + 90000 * 1152 / audio->out.samplerate;
buf->size = lame_encode_buffer_interleaved( pv->lame, samples_s16,
1152, buf->data, LAME_MAXMP3BUFFER );
buf->frametype = HB_FRAME_AUDIO;
Index: libhb/muxavi.c
===================================================================
--- libhb/muxavi.c (revision 1364)
+++ libhb/muxavi.c (working copy)
@@ -281,7 +281,7 @@
hb_mux_data_t * mux_data;
int audio_count = hb_list_count( title->list_audio );
- int is_ac3 = ( job->acodec & HB_ACODEC_AC3 );
+ int is_ac3 = 0;
int hdrl_bytes;
int i;
@@ -346,6 +346,8 @@
{
audio = hb_list_item( title->list_audio, i );
+ is_ac3 = (audio->out.codec == HB_ACODEC_AC3);
+
mux_data = calloc( sizeof( hb_mux_data_t ), 1 );
audio->mux_data = mux_data;
@@ -358,8 +360,8 @@
h.Type = FOURCC( "auds" );
h.InitialFrames = 1;
h.Scale = 1;
- h.Rate = is_ac3 ? ( audio->bitrate / 8 ) :
- ( job->abitrate * 1000 / 8 );
+ h.Rate = is_ac3 ? ( audio->in.bitrate / 8 ) :
+ ( audio->out.bitrate * 1000 / 8 );
h.Quality = 0xFFFFFFFF;
h.SampleSize = 1;
@@ -369,16 +371,16 @@
{
f.BytesCount = sizeof( hb_wave_formatex_t ) - 8;
f.FormatTag = 0x2000;
- f.Channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout);
- f.SamplesPerSec = audio->rate;
+ f.Channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->in.channel_layout);
+ f.SamplesPerSec = audio->in.samplerate;
}
else
{
f.BytesCount = sizeof( hb_wave_formatex_t ) +
sizeof( hb_wave_mp3_t ) - 8;
f.FormatTag = 0x55;
- f.Channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(job->audio_mixdowns[i]);
- f.SamplesPerSec = job->arate;
+ f.Channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown);
+ f.SamplesPerSec = audio->out.samplerate;
}
f.AvgBytesPerSec = h.Rate;
f.BlockAlign = 1;
@@ -391,7 +393,7 @@
f.Size = sizeof( hb_wave_mp3_t );
m.Id = 1;
m.Flags = 2;
- m.BlockSize = 1152 * f.AvgBytesPerSec / job->arate;
+ m.BlockSize = 1152 * f.AvgBytesPerSec / audio->out.samplerate;
m.FramesPerBlock = 1;
m.CodecDelay = 1393;
}
@@ -513,7 +515,7 @@
{
audio = hb_list_item( title->list_audio, i );
fseek( m->file, 264 + i *
- ( 102 + ( ( job->acodec & HB_ACODEC_AC3 ) ? 0 :
+ ( 102 + ( ( audio->out.codec == HB_ACODEC_AC3 ) ? 0 :
sizeof( hb_wave_mp3_t ) ) ), SEEK_SET );
WriteInt32( m->file, audio->mux_data->header.Length );
}
Index: libhb/dvd.c
===================================================================
--- libhb/dvd.c (revision 1364)
+++ libhb/dvd.c (working copy)
@@ -257,28 +257,28 @@
{
case 0x00:
audio->id = ( ( 0x80 + position ) << 8 ) | 0xbd;
- audio->codec = HB_ACODEC_AC3;
+ audio->in.codec = HB_ACODEC_AC3;
break;
case 0x02:
case 0x03:
audio->id = 0xc0 + position;
- audio->codec = HB_ACODEC_MPGA;
+ audio->in.codec = HB_ACODEC_MPGA;
break;
case 0x04:
audio->id = ( ( 0xa0 + position ) << 8 ) | 0xbd;
- audio->codec = HB_ACODEC_LPCM;
+ audio->in.codec = HB_ACODEC_LPCM;
break;
case 0x06:
audio->id = ( ( 0x88 + position ) << 8 ) | 0xbd;
- audio->codec = HB_ACODEC_DCA;
+ audio->in.codec = HB_ACODEC_DCA;
break;
default:
audio->id = 0;
- audio->codec = 0;
+ audio->in.codec = 0;
hb_log( "scan: unknown audio codec (%x)",
audio_format );
break;
@@ -308,18 +308,18 @@
lang = lang_for_code( vts->vtsi_mat->vts_audio_attr[i].lang_code );
- snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)",
+ snprintf( audio->lang.description, sizeof( audio->lang.description ), "%s (%s)",
strlen(lang->native_name) ? lang->native_name : lang->eng_name,
- audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec ==
- HB_ACODEC_DCA ? "DTS" : ( audio->codec ==
+ audio->in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->in.codec ==
+ HB_ACODEC_DCA ? "DTS" : ( audio->in.codec ==
HB_ACODEC_MPGA ? "MPEG" : "LPCM" ) ) );
- snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s",
+ snprintf( audio->lang.simple, sizeof( audio->lang.simple ), "%s",
strlen(lang->native_name) ? lang->native_name : lang->eng_name );
- snprintf( audio->iso639_2, sizeof( audio->iso639_2 ), "%s",
+ snprintf( audio->lang.iso639_2, sizeof( audio->lang.iso639_2 ), "%s",
lang->iso639_2);
hb_log( "scan: id=%x, lang=%s, 3cc=%s", audio->id,
- audio->lang, audio->iso639_2 );
+ audio->lang.description, audio->lang.iso639_2 );
hb_list_add( title->list_audio, audio );
}
Index: libhb/hb.c
===================================================================
--- libhb/hb.c (revision 1364)
+++ libhb/hb.c (working copy)
@@ -834,7 +834,7 @@
hb_job_t * job_copy;
hb_title_t * title, * title_copy;
hb_chapter_t * chapter, * chapter_copy;
- hb_audio_t * audio, * audio_copy;
+ hb_audio_t * audio;
hb_subtitle_t * subtitle, * subtitle_copy;
int i;
char audio_lang[4];
@@ -859,18 +859,12 @@
/* Do nothing about audio during first pass */
if( job->pass == 0 || job->pass == 2 )
{
- for( i = 0; i < 8; i++ )
+ for( i = 0; i < hb_list_count(job->list_audio); i++ )
{
- if( job->audios[i] < 0 )
+ if( ( audio = hb_list_item( job->list_audio, i ) ) )
{
- break;
+ hb_list_add( title_copy->list_audio, hb_audio_copy(audio) );
}
- if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
- {
- audio_copy = malloc( sizeof( hb_audio_t ) );
- memcpy( audio_copy, audio, sizeof( hb_audio_t ) );
- hb_list_add( title_copy->list_audio, audio_copy );
- }
}
}
@@ -900,17 +894,13 @@
/*
* Find the first audio language that is being encoded
*/
- for( i = 0; i < 8; i++ )
+ for( i = 0; i < hb_list_count(job->list_audio); i++ )
{
- if( job->audios[i] < 0 )
+ if( ( audio = hb_list_item( job->list_audio, i ) ) )
{
+ strncpy(audio_lang, audio->lang.iso639_2, sizeof(audio_lang));
break;
}
- if( ( audio = hb_list_item( title->list_audio, job->audios[i] ) ) )
- {
- strncpy(audio_lang, audio->iso639_2, sizeof(audio_lang));
- break;
- }
}
/*
@@ -1035,6 +1025,7 @@
memcpy( job_copy, job, sizeof( hb_job_t ) );
title_copy->job = job_copy;
job_copy->title = title_copy;
+ job_copy->list_audio = title_copy->list_audio;
job_copy->file = strdup( job->file );
job_copy->h = h;
job_copy->pause = h->pause_lock;
Index: libhb/muxmp4.c
===================================================================
--- libhb/muxmp4.c (revision 1364)
+++ libhb/muxmp4.c (working copy)
@@ -27,6 +27,11 @@
MP4TrackId chapter_track;
int current_chapter;
uint64_t chapter_duration;
+
+ /* Sample rate of the first audio track.
+ * Used for the timescale
+ */
+ int samplerate;
};
struct hb_mux_data_s
@@ -137,6 +142,10 @@
/* Flags for enabling/disabling tracks in an MP4. */
typedef enum { TRACK_DISABLED = 0x0, TRACK_ENABLED = 0x1, TRACK_IN_MOVIE = 0x2, TRACK_IN_PREVIEW = 0x4, TRACK_IN_POSTER = 0x8} track_header_flags;
+ /* Need the sample rate of the first audio track to use as the timescale. */
+ audio = hb_list_item(title->list_audio, 0);
+ m->samplerate = audio->out.samplerate;
+ audio = NULL;
/* Create an empty mp4 file */
if (job->largeFileSize)
@@ -166,7 +175,7 @@
synchronization issues (audio not playing at the correct speed).
To workaround this, we use the audio samplerate as the
timescale */
- if (!(MP4SetTimeScale( m->file, job->arate )))
+ if (!(MP4SetTimeScale( m->file, m->samplerate )))
{
hb_error("muxmp4.c: MP4SetTimeScale failed!");
*job->die = 1;
@@ -183,7 +192,7 @@
return 0;
}
- mux_data->track = MP4AddH264VideoTrack( m->file, job->arate,
+ mux_data->track = MP4AddH264VideoTrack( m->file, m->samplerate,
MP4_INVALID_DURATION, job->width, job->height,
job->config.h264.sps[1], /* AVCProfileIndication */
job->config.h264.sps[2], /* profile_compat */
@@ -211,7 +220,7 @@
*job->die = 1;
return 0;
}
- mux_data->track = MP4AddVideoTrack( m->file, job->arate,
+ mux_data->track = MP4AddVideoTrack( m->file, m->samplerate,
MP4_INVALID_DURATION, job->width, job->height,
MP4_MPEG4_VIDEO_TYPE );
if (mux_data->track == MP4_INVALID_TRACK_ID)
@@ -263,12 +272,11 @@
mux_data = malloc( sizeof( hb_mux_data_t ) );
audio->mux_data = mux_data;
- if( job->acodec & HB_ACODEC_AC3 ||
- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+ if( audio->out.codec == HB_ACODEC_AC3 )
{
mux_data->track = MP4AddAC3AudioTrack(
m->file,
- job->arate, 1536, MP4_MPEG4_AUDIO_TYPE );
+ m->samplerate, 1536, MP4_MPEG4_AUDIO_TYPE );
MP4SetTrackBytesProperty(
m->file, mux_data->track,
"udta.name.value",
@@ -276,7 +284,7 @@
} else {
mux_data->track = MP4AddAudioTrack(
m->file,
- job->arate, 1024, MP4_MPEG4_AUDIO_TYPE );
+ m->samplerate, 1024, MP4_MPEG4_AUDIO_TYPE );
MP4SetTrackBytesProperty(
m->file, mux_data->track,
"udta.name.value",
@@ -288,15 +296,15 @@
audio->config.aac.bytes, audio->config.aac.length );
/* Set the correct number of channels for this track */
- reserved2[9] = (u_int8_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown);
+ reserved2[9] = (u_int8_t)HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown);
MP4SetTrackBytesProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.mp4a.reserved2", reserved2, sizeof(reserved2));
}
/* Set the language for this track */
/* The language is stored as 5-bit text - 0x60 */
- language_code = audio->iso639_2[0] - 0x60; language_code <<= 5;
- language_code |= audio->iso639_2[1] - 0x60; language_code <<= 5;
- language_code |= audio->iso639_2[2] - 0x60;
+ language_code = audio->lang.iso639_2[0] - 0x60; language_code <<= 5;
+ language_code |= audio->lang.iso639_2[1] - 0x60; language_code <<= 5;
+ language_code |= audio->lang.iso639_2[2] - 0x60;
MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.mdhd.language", language_code);
@@ -372,7 +380,7 @@
if ( job->areBframes )
{
- duration += buf->renderOffset * job->arate / 90000;
+ duration += buf->renderOffset * m->samplerate / 90000;
}
sample = MP4GenerateChapterSample( m, duration );
@@ -396,8 +404,8 @@
/* Because we use the audio samplerate as the timescale,
we have to use potentially variable durations so the video
doesn't go out of sync */
- int64_t bias = ( buf->start * job->arate / 90000 ) - m->sum_dur;
- duration = ( buf->stop - buf->start ) * job->arate / 90000 + bias;
+ int64_t bias = ( buf->start * m->samplerate / 90000 ) - m->sum_dur;
+ duration = ( buf->stop - buf->start ) * m->samplerate / 90000 + bias;
if ( duration <= 0 )
{
/* We got an illegal mp4/h264 duration. This shouldn't
@@ -406,14 +414,14 @@
try to fix the error so that the file will still be playable. */
hb_log("MP4Mux: illegal duration %lld, bias %lld, start %lld (%lld),"
"stop %lld (%lld), sum_dur %lld",
- duration, bias, buf->start * job->arate / 90000, buf->start,
- buf->stop * job->arate / 90000, buf->stop, m->sum_dur );
+ duration, bias, buf->start * m->samplerate / 90000, buf->start,
+ buf->stop * m->samplerate / 90000, buf->stop, m->sum_dur );
/* we don't know when the next frame starts so we can't pick a
valid duration for this one so we pick something "short"
(roughly 1/3 of an NTSC frame time) and rely on the bias calc
for the next frame to correct things (a duration underestimate
just results in a large bias on the next frame). */
- duration = 1000 * job->arate / 90000;
+ duration = 1000 * m->samplerate / 90000;
}
m->sum_dur += duration;
}
@@ -436,7 +444,7 @@
duration,
((mux_data->track != 1) ||
(job->areBframes==0) ||
- (job->vcodec != HB_VCODEC_X264)) ? 0 : ( buf->renderOffset * job->arate / 90000),
+ (job->vcodec != HB_VCODEC_X264)) ? 0 : ( buf->renderOffset * m->samplerate / 90000),
((buf->frametype & HB_FRAME_KEY) != 0) ) )
{
hb_error("Failed to write to output file, disk full?");
Index: libhb/stream.c
===================================================================
--- libhb/stream.c (revision 1364)
+++ libhb/stream.c (working copy)
@@ -340,7 +340,7 @@
if ( stream->frames )
{
hb_log( "stream: %d good frames, %d errors (%.0f%%)", stream->frames,
- stream->errors, (double)stream->errors * 100. /
+ stream->errors, (double)stream->errors * 100. /
(double)stream->frames );
}
/*
@@ -444,7 +444,7 @@
for (i=0; i < stream->ts_number_audio_pids; i++)
{
hb_audio_t *audio = hb_ts_stream_set_audio_id_and_codec(stream, i);
- if (audio->codec)
+ if (audio->in.codec)
hb_list_add( aTitle->list_audio, audio );
else
{
@@ -773,7 +773,7 @@
if (buf[3] == 0xbd)
{
audio->id = 0x80bd | (aud_pid_index << 8);
- audio->codec = HB_ACODEC_AC3;
+ audio->in.codec = HB_ACODEC_AC3;
hb_log("transport stream pid 0x%x (type 0x%x) is AC-3 audio id 0x%x",
stream->ts_audio_pids[aud_pid_index],
stream->ts_audio_stream_type[1 + aud_pid_index],
@@ -784,7 +784,7 @@
else if ((buf[3] & 0xe0) == 0xc0)
{
audio->id = buf[3] | aud_pid_index;
- audio->codec = HB_ACODEC_MPGA;
+ audio->in.codec = HB_ACODEC_MPGA;
hb_log("transport stream pid 0x%x (type 0x%x) is MPEG audio id 0x%x",
stream->ts_audio_pids[aud_pid_index],
stream->ts_audio_stream_type[1 + aud_pid_index],
@@ -794,7 +794,7 @@
}
}
fseeko(stream->file_handle, cur_pos, SEEK_SET);
- if (! audio->codec)
+ if (! audio->in.codec)
{
hb_log("transport stream pid 0x%x (type 0x%x) isn't audio",
stream->ts_audio_pids[aud_pid_index],
@@ -811,7 +811,7 @@
switch ( id >> 12 )
{
case 0x0:
- audio->codec = HB_ACODEC_MPGA;
+ audio->in.codec = HB_ACODEC_MPGA;
hb_log("add_audio_to_title: added MPEG audio stream 0x%x", id);
break;
case 0x2:
@@ -819,11 +819,11 @@
free( audio );
return;
case 0x8:
- audio->codec = HB_ACODEC_AC3;
+ audio->in.codec = HB_ACODEC_AC3;
hb_log("add_audio_to_title: added AC3 audio stream 0x%x", id);
break;
case 0xa:
- audio->codec = HB_ACODEC_LPCM;
+ audio->in.codec = HB_ACODEC_LPCM;
hb_log("add_audio_to_title: added LPCM audio stream 0x%x", id);
break;
default:
@@ -913,12 +913,12 @@
}
lang = lang_for_code(stream->a52_info[i].lang_code);
- if (!audio->rate)
- audio->rate = stream->a52_info[i].rate;
- if (!audio->bitrate)
- audio->bitrate = stream->a52_info[i].bitrate;
- if (!audio->config.a52.ac3flags)
- audio->config.a52.ac3flags = audio->ac3flags = stream->a52_info[i].flags;
+ if (!audio->in.samplerate)
+ audio->in.samplerate = stream->a52_info[i].rate;
+ if (!audio->in.bitrate)
+ audio->in.bitrate = stream->a52_info[i].bitrate;
+ if (!audio->config.a52.ac3flags)
+ audio->config.a52.ac3flags = audio->flags.ac3 = stream->a52_info[i].flags;
}
else
@@ -927,74 +927,74 @@
lang = lang_for_code(0x0000);
}
- if (!audio->input_channel_layout)
+ if (!audio->in.channel_layout)
{
- switch( audio->ac3flags & A52_CHANNEL_MASK )
+ switch( audio->flags.ac3 & A52_CHANNEL_MASK )
{
/* mono sources */
case A52_MONO:
case A52_CHANNEL1:
case A52_CHANNEL2:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_MONO;
break;
/* stereo input */
case A52_CHANNEL:
case A52_STEREO:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
break;
/* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
case A52_DOLBY:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
break;
/* 3F/2R input */
case A52_3F2R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
break;
/* 3F/1R input */
case A52_3F1R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
break;
/* other inputs */
case A52_3F:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
break;
case A52_2F1R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
break;
case A52_2F2R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
break;
/* unknown */
default:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
}
/* add in our own LFE flag if the source has LFE */
- if (audio->ac3flags & A52_LFE)
+ if (audio->flags.ac3 & A52_LFE)
{
- audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
+ audio->in.channel_layout = audio->in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
}
}
- snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,
- audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->codec == HB_ACODEC_DCA ? "DTS" : "LPCM" ) ) );
- snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );
- snprintf( audio->iso639_2, sizeof( audio->iso639_2 ), "%s", lang->iso639_2);
+ snprintf( audio->lang.description, sizeof( audio->lang.description ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,
+ audio->in.codec == HB_ACODEC_AC3 ? "AC3" : ( audio->in.codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->in.codec == HB_ACODEC_DCA ? "DTS" : "LPCM" ) ) );
+ snprintf( audio->lang.simple, sizeof( audio->lang.simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );
+ snprintf( audio->lang.iso639_2, sizeof( audio->lang.iso639_2 ), "%s", lang->iso639_2);
- if ( (audio->ac3flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
- sprintf( audio->lang + strlen( audio->lang ),
+ if ( (audio->flags.ac3 & A52_CHANNEL_MASK) == A52_DOLBY ) {
+ sprintf( audio->lang.description + strlen( audio->lang.description ),
" (Dolby Surround)" );
} else {
- sprintf( audio->lang + strlen( audio->lang ),
+ sprintf( audio->lang.description + strlen( audio->lang.description ),
" (%d.%d ch)",
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->in.channel_layout) +
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->in.channel_layout),
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->in.channel_layout));
}
hb_log( "stream: audio %x: lang %s, rate %d, bitrate %d, "
- "flags = 0x%x", audio->id, audio->lang, audio->rate,
- audio->bitrate, audio->ac3flags );
+ "flags = 0x%x", audio->id, audio->lang.description, audio->in.samplerate,
+ audio->in.bitrate, audio->flags.ac3 );
}
@@ -1879,7 +1879,7 @@
// remember the pcr across calls to this routine
stream->ts_lastpcr = pcr;
}
-
+
if ( pcr == -1 )
{
// don't accumulate data until we get a pcr
@@ -1903,7 +1903,7 @@
// so ignore the rest.
continue;
}
- if ( !start && (stream->ts_streamcont[curstream] != -1) &&
+ if ( !start && (stream->ts_streamcont[curstream] != -1) &&
(continuity != ( (stream->ts_streamcont[curstream] + 1) & 0xf ) ) )
{
ts_err( stream, curstream, "continuity error: got %d expected %d",
@@ -1933,7 +1933,7 @@
stream->ts_skipbad[curstream] = 0;
}
- // If we don't have video yet, check to see if this is an
+ // If we don't have video yet, check to see if this is an
// i_frame (group of picture start)
if ( curstream == 0 )
{
Index: libhb/decdca.c
===================================================================
--- libhb/decdca.c (revision 1364)
+++ libhb/decdca.c (working copy)
@@ -61,6 +61,7 @@
int decdcaInit( hb_work_object_t * w, hb_job_t * job )
{
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ hb_audio_t * audio = w->audio;
w->private_data = pv;
pv->job = job;
@@ -71,11 +72,11 @@
/* Decide what format we want out of libdca
work.c has already done some of this deduction for us in do_job() */
- pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT(w->amixdown);
+ pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT(audio->out.mixdown);
/* pass the number of channels used into the private work data */
/* will only be actually used if we're not doing AC3 passthru */
- pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown);
pv->level = 32768.0;
Index: libhb/muxogm.c
===================================================================
--- libhb/muxogm.c (revision 1364)
+++ libhb/muxogm.c (working copy)
@@ -135,7 +135,7 @@
{
audio = hb_list_item( title->list_audio, i );
mux_data = malloc( sizeof( hb_mux_data_t ) );
- mux_data->codec = job->acodec;
+ mux_data->codec = audio->out.codec;
mux_data->i_packet_no = 0;
audio->mux_data = mux_data;
ogg_stream_init( &mux_data->os, i + 1 );
@@ -202,7 +202,7 @@
audio = hb_list_item( title->list_audio, i );
mux_data = audio->mux_data;
memset( &h, 0, sizeof( ogg_stream_header_t ) );
- switch( job->acodec )
+ switch( audio->out.codec )
{
case HB_ACODEC_LAME:
{
@@ -212,7 +212,7 @@
SetDWLE( &h.i_size, sizeof( ogg_stream_header_t ) - 1);
SetQWLE( &h.i_time_unit, 0 );
- SetQWLE( &h.i_samples_per_unit, job->arate );
+ SetQWLE( &h.i_samples_per_unit, audio->out.samplerate );
SetDWLE( &h.i_default_len, 1 );
SetDWLE( &h.i_buffer_size, 30 * 1024 );
SetWLE ( &h.i_bits_per_sample, 0 );
@@ -220,7 +220,7 @@
SetDWLE( &h.header.audio.i_channels, 2 );
SetDWLE( &h.header.audio.i_block_align, 0 );
SetDWLE( &h.header.audio.i_avgbytespersec,
- job->abitrate / 8 );
+ audio->out.bitrate / 8 );
op.packet = (unsigned char*) &h;
op.bytes = sizeof( ogg_stream_header_t );
@@ -275,7 +275,7 @@
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
audio = hb_list_item( title->list_audio, i );
- if( job->acodec == HB_ACODEC_VORBIS )
+ if( audio->out.codec == HB_ACODEC_VORBIS )
{
int j;
mux_data = audio->mux_data;
Index: libhb/sync.c
===================================================================
--- libhb/sync.c (revision 1364)
+++ libhb/sync.c (working copy)
@@ -130,6 +130,7 @@
hb_work_private_t * pv = w->private_data;
hb_job_t * job = pv->job;
hb_title_t * title = job->title;
+ hb_audio_t * audio = NULL;
int i;
@@ -144,8 +145,8 @@
pv->sync_audio[i].start_silence) / 90), i );
}
- if( job->acodec & HB_ACODEC_AC3 ||
- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+ audio = hb_list_item( title->list_audio, i );
+ if( audio->out.codec == HB_ACODEC_AC3 )
{
free( pv->sync_audio[i].ac3_buf );
}
@@ -207,8 +208,7 @@
sync = &pv->sync_audio[i];
sync->audio = hb_list_item( title->list_audio, i );
- if( job->acodec & HB_ACODEC_AC3 ||
- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+ if( sync->audio->out.codec == HB_ACODEC_AC3 )
{
/* Have a silent AC-3 frame ready in case we have to fill a
gap */
@@ -219,9 +219,9 @@
codec = avcodec_find_encoder( CODEC_ID_AC3 );
c = avcodec_alloc_context();
- c->bit_rate = sync->audio->bitrate;
- c->sample_rate = sync->audio->rate;
- c->channels = 2;
+ c->bit_rate = sync->audio->in.bitrate;
+ c->sample_rate = sync->audio->in.samplerate;
+ c->channels = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( sync->audio->in.channel_layout );
if( avcodec_open( c, codec ) < 0 )
{
@@ -231,8 +231,8 @@
zeros = calloc( AC3_SAMPLES_PER_FRAME *
sizeof( short ) * c->channels, 1 );
- sync->ac3_size = sync->audio->bitrate * AC3_SAMPLES_PER_FRAME /
- sync->audio->rate / 8;
+ sync->ac3_size = sync->audio->in.bitrate * AC3_SAMPLES_PER_FRAME /
+ sync->audio->in.samplerate / 8;
sync->ac3_buf = malloc( sync->ac3_size );
if( avcodec_encode_audio( c, sync->ac3_buf, sync->ac3_size,
@@ -249,7 +249,7 @@
{
/* Initialize libsamplerate */
int error;
- sync->state = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown), &error );
+ sync->state = src_new( SRC_LINEAR, HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->out.mixdown), &error );
sync->data.end_of_input = 0;
}
}
@@ -432,9 +432,9 @@
* Subtitle is on for less than three seconds, extend
* the time that it is displayed to make it easier
* to read. Make it 3 seconds or until the next
- * subtitle is displayed.
+ * subtitle is displayed.
*
- * This is in response to Indochine which only
+ * This is in response to Indochine which only
* displays subs for 1 second - too fast to read.
*/
sub->stop = sub->start + ( 3 * 90000 );
@@ -558,22 +558,22 @@
{
int64_t start = sync->next_start;
int64_t duration = buf->stop - buf->start;
- if (duration <= 0 ||
- duration > ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->rate )
+ if (duration <= 0 ||
+ duration > ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->out.samplerate )
{
hb_log("sync: audio %d weird duration %lld, start %lld, stop %lld, next %lld",
i, duration, buf->start, buf->stop, sync->next_pts);
if ( duration <= 0 )
{
- duration = ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->rate;
+ duration = ( 90000 * AC3_SAMPLES_PER_FRAME ) / audio->out.samplerate;
buf->stop = buf->start + duration;
}
}
sync->next_pts += duration;
if( /* audio->rate == job->arate || This should work but doesn't */
- job->acodec & HB_ACODEC_AC3 ||
- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+ audio->out.codec == HB_ACODEC_AC3 ||
+ audio->out.codec == HB_ACODEC_DCA )
{
/*
* If we don't have to do sample rate conversion or this audio is AC3
@@ -586,11 +586,11 @@
/* Not pass-thru - do sample rate conversion */
int count_in, count_out;
hb_buffer_t * buf_raw = buf;
- int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown) *
+ int channel_count = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown) *
sizeof( float );
count_in = buf_raw->size / channel_count;
- count_out = ( buf_raw->stop - buf_raw->start ) * job->arate / 90000;
+ count_out = ( buf_raw->stop - buf_raw->start ) * audio->out.samplerate / 90000;
sync->data.input_frames = count_in;
sync->data.output_frames = count_out;
@@ -630,16 +630,15 @@
hb_fifo_t * fifo;
int rate;
- if( job->acodec & HB_ACODEC_AC3 ||
- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+ if( audio->out.codec == HB_ACODEC_AC3 )
{
fifo = audio->fifo_out;
- rate = audio->rate;
+ rate = audio->in.samplerate;
}
else
{
fifo = audio->fifo_sync;
- rate = job->arate;
+ rate = audio->out.samplerate;
}
while( !hb_fifo_is_full( fifo ) && ( buf = hb_fifo_see( audio->fifo_raw ) ) )
@@ -717,7 +716,7 @@
if( NeedSilence( w, audio, i ) )
{
- InsertSilence( w, i, (90000 * AC3_SAMPLES_PER_FRAME) / sync->audio->rate );
+ InsertSilence( w, i, (90000 * AC3_SAMPLES_PER_FRAME) / sync->audio->out.samplerate );
}
}
@@ -759,7 +758,7 @@
hb_sync_audio_t *sync = &pv->sync_audio[i];
hb_buffer_t *buf;
- if( job->acodec & HB_ACODEC_AC3 || job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
+ if( sync->audio->out.codec == HB_ACODEC_AC3 )
{
buf = hb_buffer_init( sync->ac3_size );
buf->start = sync->next_pts;
@@ -770,7 +769,7 @@
else
{
buf = hb_buffer_init( duration * sizeof( float ) *
- HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->amixdown) );
+ HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(sync->audio->out.mixdown) );
buf->start = sync->next_pts;
buf->stop = buf->start + duration;
memset( buf->data, 0, buf->size );
Index: libhb/encfaac.c
===================================================================
--- libhb/encfaac.c (revision 1364)
+++ libhb/encfaac.c (working copy)
@@ -45,6 +45,7 @@
int encfaacInit( hb_work_object_t * w, hb_job_t * job )
{
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ hb_audio_t * audio = w->audio;
faacEncConfigurationPtr cfg;
uint8_t * bytes;
unsigned long length;
@@ -54,9 +55,9 @@
pv->job = job;
/* pass the number of channels used into the private work data */
- pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown);
- pv->faac = faacEncOpen( job->arate, pv->out_discrete_channels, &pv->input_samples,
+ pv->faac = faacEncOpen( audio->out.samplerate, pv->out_discrete_channels, &pv->input_samples,
&pv->output_bytes );
pv->buf = malloc( pv->input_samples * sizeof( float ) );
@@ -74,12 +75,12 @@
}
cfg->useTns = 0;
- cfg->bitRate = job->abitrate * 1000 / pv->out_discrete_channels; /* Per channel */
+ cfg->bitRate = audio->out.bitrate * 1000 / pv->out_discrete_channels; /* Per channel */
cfg->bandWidth = 0;
cfg->outputFormat = 0;
cfg->inputFormat = FAAC_INPUT_FLOAT;
- if (w->amixdown == HB_AMIXDOWN_6CH && w->source_acodec == HB_ACODEC_AC3)
+ if (audio->out.mixdown == HB_AMIXDOWN_6CH && audio->in.codec == HB_ACODEC_AC3)
{
/* we are preserving 5.1 AC-3 audio into 6-channel AAC, and need to
re-map the output of deca52 into our own mapping - the mapping
@@ -140,6 +141,7 @@
static hb_buffer_t * Encode( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
+ hb_audio_t * audio = w->audio;
hb_buffer_t * buf;
uint64_t pts, pos;
@@ -153,8 +155,8 @@
&pts, &pos );
buf = hb_buffer_init( pv->output_bytes );
- buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / pv->job->arate;
- buf->stop = buf->start + 90000 * pv->input_samples / pv->job->arate / pv->out_discrete_channels;
+ buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->out.samplerate;
+ buf->stop = buf->start + 90000 * pv->input_samples / audio->out.samplerate / pv->out_discrete_channels;
buf->size = faacEncEncode( pv->faac, (int32_t *) pv->buf,
pv->input_samples, buf->data, pv->output_bytes );
buf->frametype = HB_FRAME_AUDIO;
Index: libhb/work.c
===================================================================
--- libhb/work.c (revision 1364)
+++ libhb/work.c (working copy)
@@ -337,57 +337,53 @@
}
}
- if( job->audio_mixdowns[0] == HB_AMIXDOWN_AC3 || job->audio_mixdowns[1] == HB_AMIXDOWN_AC3 )
- {
- /* Hard set correct sample rate for AC3 when libhb
- mistakenly thinks the audio codec is AAC */
- job->arate = 48000;
- }
-
- if( job->acodec & HB_ACODEC_AC3 )
- {
- hb_log( " + audio AC3 passthrough" );
-
- /* Hard set correct sample rate for AC3 */
- job->arate = 48000;
- }
- else
- {
- hb_log( " + audio %d kbps, %d Hz", job->abitrate, job->arate );
- hb_log( " + encoder %s", ( job->acodec & HB_ACODEC_FAAC ) ?
- "faac" : ( ( job->acodec & HB_ACODEC_LAME ) ? "lame" :
- "vorbis" ) );
- }
-
- if ( job->dynamic_range_compression > 1 )
- hb_log(" + dynamic range compression: %f", job->dynamic_range_compression);
-
- /* if we are doing AC3 passthru (at the codec level, not pass-through),
- * then remove any non-AC3 audios from the job */
+ /* if we are doing passthru, and the input codec is not the same as the output
+ * codec, then remove this audio from the job */
/* otherwise, Bad Things will happen */
for( i = 0; i < hb_list_count( title->list_audio ); )
{
audio = hb_list_item( title->list_audio, i );
- if( ( job->acodec & HB_ACODEC_AC3 ) && ( audio->codec != HB_ACODEC_AC3 ) )
+ if( ( ( audio->out.codec == HB_ACODEC_AC3 ) && ( audio->in.codec != HB_ACODEC_AC3 ) ) ||
+ ( ( audio->out.codec == HB_ACODEC_DCA ) && ( audio->in.codec != HB_ACODEC_DCA ) ) )
{
+ hb_log( "Passthru requested and input codec is not the same as output codec for track %d", audio->out.track );
hb_list_rem( title->list_audio, audio );
free( audio );
continue;
}
- i++;
+ /* Adjust output track number, in case we removed one.
+ * Output tracks sadly still need to be in sequential order.
+ */
+ audio->out.track = i++;
}
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
audio = hb_list_item( title->list_audio, i );
- hb_log( " + %x, %s", audio->id, audio->lang );
+ hb_log( " + audio track %d", audio->out.track );
+ if( (audio->out.codec == HB_ACODEC_AC3) || (audio->out.codec == HB_ACODEC_DCA) )
+ {
+ hb_log( " + %s passthrough", (audio->out.codec == HB_ACODEC_AC3) ?
+ "AC3" : "DCA" );
+ }
+ else
+ {
+ hb_log( " + audio %d kbps, %d Hz", audio->out.bitrate, audio->out.samplerate );
+ hb_log( " + encoder %s", ( audio->out.codec == HB_ACODEC_FAAC ) ?
+ "faac" : ( ( audio->out.codec == HB_ACODEC_LAME ) ? "lame" :
+ "vorbis" ) );
+ if ( audio->out.dynamic_range_compression > 1 )
+ hb_log(" + dynamic range compression: %f", audio->out.dynamic_range_compression);
+ }
+ hb_log( " + %x, %s", audio->id, audio->lang.description );
+
/* sense-check the current mixdown options */
/* log the requested mixdown */
for (j = 0; j < hb_audio_mixdowns_count; j++) {
- if (hb_audio_mixdowns[j].amixdown == job->audio_mixdowns[i]) {
- hb_log( " + Requested mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
+ if (hb_audio_mixdowns[j].amixdown == audio->out.mixdown) {
+ hb_log( " + Requested mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
break;
}
}
@@ -396,33 +392,22 @@
/* audioCodecsSupportMono and audioCodecsSupport6Ch are the same for now,
but this may change in the future, so they are separated for flexibility */
- int audioCodecsSupportMono = ((audio->codec == HB_ACODEC_AC3 ||
- audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS));
- int audioCodecsSupport6Ch = ((audio->codec == HB_ACODEC_AC3 ||
- audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS));
+ int audioCodecsSupportMono = ( (audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA) &&
+ (audio->out.codec == HB_ACODEC_FAAC || audio->out.codec == HB_ACODEC_VORBIS) );
+ int audioCodecsSupport6Ch = ( (audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA) &&
+ (audio->out.codec == HB_ACODEC_FAAC || audio->out.codec == HB_ACODEC_VORBIS));
- if( audio->codec != HB_ACODEC_AC3 && job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
- {
- /*
- * Sanity check that we haven't asked for AC3 from a non AC3 track - drop this track
- * to stereo to avoid a crash later.
- */
- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
- }
-
- if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )
- {
/* find out what the format of our source audio is */
- switch (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) {
+ switch (audio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) {
/* mono sources */
case HB_INPUT_CH_LAYOUT_MONO:
/* regardless of what stereo mixdown we've requested, a mono source always get mixed down
to mono if we can, and mixed up to stereo if we can't */
- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;
+ if (audio->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
+ audio->out.mixdown = HB_AMIXDOWN_MONO;
} else {
- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+ audio->out.mixdown = HB_AMIXDOWN_STEREO;
}
break;
@@ -430,11 +415,11 @@
case HB_INPUT_CH_LAYOUT_STEREO:
/* if we've requested a mono mixdown, and it is supported, then do the mix */
/* use stereo if not supported */
- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+ if (audio->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+ audio->out.mixdown = HB_AMIXDOWN_STEREO;
/* otherwise, preserve stereo regardless of if we requested something higher */
- } else if (job->audio_mixdowns[i] > HB_AMIXDOWN_STEREO) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+ } else if (audio->out.mixdown > HB_AMIXDOWN_STEREO) {
+ audio->out.mixdown = HB_AMIXDOWN_STEREO;
}
break;
@@ -444,12 +429,12 @@
case HB_INPUT_CH_LAYOUT_DOLBY:
/* if we've requested a mono mixdown, and it is supported, then do the mix */
/* preserve dolby if not supported */
- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+ if (audio->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+ audio->out.mixdown = HB_AMIXDOWN_DOLBY;
/* otherwise, preserve dolby even if we requested something higher */
/* a stereo mixdown will still be honoured here */
- } else if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBY) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+ } else if (audio->out.mixdown > HB_AMIXDOWN_DOLBY) {
+ audio->out.mixdown = HB_AMIXDOWN_DOLBY;
}
break;
@@ -457,21 +442,21 @@
case HB_INPUT_CH_LAYOUT_3F2R:
/* if we've requested a mono mixdown, and it is supported, then do the mix */
/* use dpl2 if not supported */
- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;
+ if (audio->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+ audio->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
} else {
/* check if we have 3F2R input and also have an LFE - i.e. we have a 5.1 source) */
- if (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE) {
+ if (audio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE) {
/* we have a 5.1 source */
/* if we requested 6ch, but our audio format doesn't support it, then mix to DPLII instead */
- if (job->audio_mixdowns[i] == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;
+ if (audio->out.mixdown == HB_AMIXDOWN_6CH && audioCodecsSupport6Ch == 0) {
+ audio->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
}
} else {
/* we have a 5.0 source, so we can't do 6ch conversion
default to DPL II instead */
- if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBYPLII) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBYPLII;
+ if (audio->out.mixdown > HB_AMIXDOWN_DOLBYPLII) {
+ audio->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
}
}
}
@@ -482,13 +467,13 @@
case HB_INPUT_CH_LAYOUT_3F1R:
/* if we've requested a mono mixdown, and it is supported, then do the mix */
/* use dpl1 if not supported */
- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+ if (audio->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 0) {
+ audio->out.mixdown = HB_AMIXDOWN_DOLBY;
} else {
/* we have a 4.0 or 4.1 source, so we can't do DPLII or 6ch conversion
default to DPL I instead */
- if (job->audio_mixdowns[i] > HB_AMIXDOWN_DOLBY) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_DOLBY;
+ if (audio->out.mixdown > HB_AMIXDOWN_DOLBY) {
+ audio->out.mixdown = HB_AMIXDOWN_DOLBY;
}
}
/* all other mixdowns will have been preserved here */
@@ -496,30 +481,26 @@
default:
/* if we've requested a mono mixdown, and it is supported, then do the mix */
- if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
- job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;
+ if (audio->out.mixdown == HB_AMIXDOWN_MONO && audioCodecsSupportMono == 1) {
+ audio->out.mixdown = HB_AMIXDOWN_MONO;
/* mix everything else down to stereo */
} else {
- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+ audio->out.mixdown = HB_AMIXDOWN_STEREO;
}
}
- }
/* log the output mixdown */
for (j = 0; j < hb_audio_mixdowns_count; j++) {
- if (hb_audio_mixdowns[j].amixdown == job->audio_mixdowns[i]) {
- hb_log( " + Actual mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
+ if (hb_audio_mixdowns[j].amixdown == audio->out.mixdown) {
+ hb_log( " + Actual mixdown: %s (%s)", hb_audio_mixdowns[j].human_readable_name, hb_audio_mixdowns[j].internal_name );
break;
}
}
- /* we now know we have a valid mixdown for the input source and the audio output format */
- /* remember the mixdown for this track */
- audio->amixdown = job->audio_mixdowns[i];
+ if (audio->out.codec == HB_ACODEC_VORBIS)
+ audio->config.vorbis.language = audio->lang.simple;
- audio->config.vorbis.language = audio->lang_simple;
-
/* set up the audio work structures */
audio->fifo_in = hb_fifo_init( 2048 );
audio->fifo_raw = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
@@ -530,7 +511,7 @@
/*
* Audio Decoder Thread
*/
- switch( audio->codec )
+ switch( audio->in.codec )
{
case HB_ACODEC_AC3:
w = getWork( WORK_DECA52 );
@@ -544,12 +525,16 @@
case HB_ACODEC_LPCM:
w = getWork( WORK_DECLPCM );
break;
+ default:
+ /* Invalid input codec */
+ hb_error("Invalid input codec: %d", audio->in.codec);
+ *job->die = 1;
+ goto cleanup;
}
w->fifo_in = audio->fifo_in;
w->fifo_out = audio->fifo_raw;
w->config = &audio->config;
- w->amixdown = audio->amixdown;
- w->source_acodec = audio->codec;
+ w->audio = audio;
/* FIXME: This feels really hackish, anything better? */
audio_w = calloc( sizeof( hb_work_object_t ), 1 );
@@ -560,10 +545,8 @@
/*
* Audio Encoder Thread
*/
- if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )
+ switch( audio->out.codec )
{
- switch( job->acodec )
- {
case HB_ACODEC_FAAC:
w = getWork( WORK_ENCFAAC );
break;
@@ -573,11 +556,17 @@
case HB_ACODEC_VORBIS:
w = getWork( WORK_ENCVORBIS );
break;
- }
+ case HB_ACODEC_AC3:
+ break;
+ case HB_ACODEC_DCA: /* These are all invalid output codecs. */
+ default:
+ hb_error("Invalid audio codec: %d", audio->out.codec);
+ w = NULL;
+ *job->die = 1;
+ goto cleanup;
}
- if( job->acodec != HB_ACODEC_AC3 &&
- job->audio_mixdowns[i] != HB_AMIXDOWN_AC3)
+ if( audio->out.codec != HB_ACODEC_AC3 )
{
/*
* Add the encoder thread if not doing AC-3 pass through
@@ -585,8 +574,7 @@
w->fifo_in = audio->fifo_sync;
w->fifo_out = audio->fifo_out;
w->config = &audio->config;
- w->amixdown = audio->amixdown;
- w->source_acodec = audio->codec;
+ w->audio = audio;
/* FIXME: This feels really hackish, anything better? */
audio_w = calloc( sizeof( hb_work_object_t ), 1 );
@@ -640,12 +628,16 @@
w->close( w );
job->done = 1;
+cleanup:
/* Close work objects */
while( ( w = hb_list_item( job->list_work, 0 ) ) )
{
hb_list_rem( job->list_work, w );
- hb_thread_close( &w->thread );
- w->close( w );
+ if( w != NULL && w->thread != NULL )
+ {
+ hb_thread_close( &w->thread );
+ w->close( w );
+ }
/* FIXME: This feels really hackish, anything better? */
if ( w->id == WORK_DECA52 ||
@@ -663,8 +655,10 @@
hb_list_close( &job->list_work );
/* Stop read & write threads */
- hb_thread_close( &job->reader );
- hb_thread_close( &job->muxer );
+ if( job->reader != NULL )
+ hb_thread_close( &job->reader );
+ if( job->muxer != NULL )
+ hb_thread_close( &job->muxer );
/* Close fifos */
hb_fifo_close( &job->fifo_mpeg2 );
@@ -684,10 +678,14 @@
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
audio = hb_list_item( title->list_audio, i );
- hb_fifo_close( &audio->fifo_in );
- hb_fifo_close( &audio->fifo_raw );
- hb_fifo_close( &audio->fifo_sync );
- hb_fifo_close( &audio->fifo_out );
+ if( audio->fifo_in != NULL )
+ hb_fifo_close( &audio->fifo_in );
+ if( audio->fifo_raw != NULL )
+ hb_fifo_close( &audio->fifo_raw );
+ if( audio->fifo_sync != NULL )
+ hb_fifo_close( &audio->fifo_sync );
+ if( audio->fifo_out != NULL )
+ hb_fifo_close( &audio->fifo_out );
}
if( job->indepth_scan )
Index: libhb/scan.c
===================================================================
--- libhb/scan.c (revision 1364)
+++ libhb/scan.c (working copy)
@@ -147,8 +147,8 @@
for( j = 0; j < hb_list_count( title->list_audio ); )
{
audio = hb_list_item( title->list_audio, j );
- if( audio->codec == HB_ACODEC_AC3 &&
- !audio->bitrate )
+ if( audio->in.codec == HB_ACODEC_AC3 &&
+ !audio->in.bitrate )
{
hb_list_rem( title->list_audio, audio );
free( audio );
@@ -162,11 +162,11 @@
for( j = 0; j < hb_list_count( title->list_audio ); )
{
audio = hb_list_item( title->list_audio, j );
- if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
- !audio->bitrate )
+ if( ( audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA ) &&
+ !audio->in.bitrate )
{
hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
- audio->codec );
+ audio->in.codec );
hb_list_rem( title->list_audio, audio );
free( audio );
continue;
@@ -188,9 +188,9 @@
for( j = 0; j < hb_list_count( title->list_audio ); j++ )
{
audio = hb_list_item( title->list_audio, j );
- if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )
+ if( audio->in.codec == HB_ACODEC_LPCM || audio->in.codec == HB_ACODEC_MPGA )
{
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
}
}
@@ -247,13 +247,8 @@
job->vrate = title->rate;
job->vrate_base = title->rate_base;
- job->audios[0] = 0;
- job->audios[1] = -1;
+ job->list_audio = hb_list_init();
- job->acodec = HB_ACODEC_FAAC;
- job->abitrate = 128;
- job->arate = 44100;
-
job->subtitle = -1;
job->mux = HB_MUX_MP4;
@@ -451,14 +446,14 @@
}
buf_raw = hb_list_item( list_raw, 0 );
-
+
/* Check preview for interlacing artifacts */
if( hb_detect_comb( buf_raw, title->width, title->height, 10, 30, 9 ) )
{
hb_log("Interlacing detected in preview frame %i", i);
interlaced_preview_count++;
}
-
+
hb_get_tempory_filename( data->h, filename, "%x%d",
(intptr_t)title, i );
@@ -584,7 +579,7 @@
{
audio = hb_list_item( title->list_audio, i );
/* check if we have an AC3 or DCA which we recognise */
- if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
+ if( ( audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA ) &&
audio->id == b->id )
{
break;
@@ -599,7 +594,7 @@
return;
}
- if( audio->bitrate )
+ if( audio->in.bitrate )
{
/* Already done for this track */
return;
@@ -608,59 +603,59 @@
for( i = 0; i < b->size - 7; i++ )
{
- if ( audio->codec == HB_ACODEC_AC3 )
+ if ( audio->in.codec == HB_ACODEC_AC3 )
{
/* check for a52 */
if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
{
hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
- audio->rate = rate;
- audio->bitrate = bitrate;
+ audio->in.samplerate = rate;
+ audio->in.bitrate = bitrate;
switch( flags & A52_CHANNEL_MASK )
{
/* mono sources */
case A52_MONO:
case A52_CHANNEL1:
case A52_CHANNEL2:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_MONO;
break;
/* stereo input */
case A52_CHANNEL:
case A52_STEREO:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
break;
/* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
case A52_DOLBY:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
break;
/* 3F/2R input */
case A52_3F2R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
break;
/* 3F/1R input */
case A52_3F1R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
break;
/* other inputs */
case A52_3F:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
break;
case A52_2F1R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
break;
case A52_2F2R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
break;
/* unknown */
default:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
}
/* add in our own LFE flag if the source has LFE */
if (flags & A52_LFE)
{
- audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
+ audio->in.channel_layout = audio->in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
}
/* store the AC3 flags for future reference
@@ -668,18 +663,18 @@
audio->config.a52.ac3flags = flags;
/* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
- audio->ac3flags = audio->config.a52.ac3flags;
+ audio->flags.ac3 = audio->config.a52.ac3flags;
/* XXX */
if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
- sprintf( audio->lang + strlen( audio->lang ),
+ sprintf( audio->lang.description + strlen( audio->lang.description ),
" (Dolby Surround)" );
} else {
- sprintf( audio->lang + strlen( audio->lang ),
+ sprintf( audio->lang.description + strlen( audio->lang.description ),
" (%d.%d ch)",
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->in.channel_layout) +
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->in.channel_layout),
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->in.channel_layout));
}
break;
@@ -687,7 +682,7 @@
}
}
- else if ( audio->codec == HB_ACODEC_DCA )
+ else if ( audio->in.codec == HB_ACODEC_DCA )
{
hb_log( "scan: checking for DCA syncinfo" );
@@ -697,51 +692,51 @@
if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
{
hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
- audio->rate = rate;
- audio->bitrate = bitrate;
+ audio->in.samplerate = rate;
+ audio->in.bitrate = bitrate;
switch( flags & DCA_CHANNEL_MASK )
{
/* mono sources */
case DCA_MONO:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_MONO;
break;
/* stereo input */
case DCA_CHANNEL:
case DCA_STEREO:
case DCA_STEREO_SUMDIFF:
case DCA_STEREO_TOTAL:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
break;
/* 3F/2R input */
case DCA_3F2R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
break;
/* 3F/1R input */
case DCA_3F1R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
break;
/* other inputs */
case DCA_3F:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_3F;
break;
case DCA_2F1R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
break;
case DCA_2F2R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
break;
case DCA_4F2R:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
break;
/* unknown */
default:
- audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
+ audio->in.channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
}
/* add in our own LFE flag if the source has LFE */
if (flags & DCA_LFE)
{
- audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
+ audio->in.channel_layout = audio->in.channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
}
/* store the DCA flags for future reference
@@ -749,18 +744,18 @@
audio->config.dca.dcaflags = flags;
/* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
- audio->dcaflags = audio->config.dca.dcaflags;
+ audio->flags.dca = audio->config.dca.dcaflags;
/* XXX */
if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
- sprintf( audio->lang + strlen( audio->lang ),
+ sprintf( audio->lang.description + strlen( audio->lang.description ),
" (Dolby Surround)" );
} else {
- sprintf( audio->lang + strlen( audio->lang ),
+ sprintf( audio->lang.description + strlen( audio->lang.description ),
" (%d.%d ch)",
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
- HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->in.channel_layout) +
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->in.channel_layout),
+ HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->in.channel_layout));
}
break;
@@ -778,8 +773,8 @@
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
audio = hb_list_item( title->list_audio, i );
- if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
- !audio->bitrate )
+ if( ( audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA ) &&
+ !audio->in.bitrate )
{
return 0;
}
Index: libhb/muxmkv.c
===================================================================
--- libhb/muxmkv.c (revision 1364)
+++ libhb/muxmkv.c (working copy)
@@ -29,6 +29,7 @@
mk_Track * track;
uint64_t prev_chapter_tc;
uint16_t current_chapter;
+ int codec;
};
/**********************************************************************
@@ -160,7 +161,9 @@
mux_data = malloc( sizeof( hb_mux_data_t ) );
audio->mux_data = mux_data;
- switch (job->acodec)
+ mux_data->codec = audio->out.codec;
+
+ switch (audio->out.codec)
{
case HB_ACODEC_AC3:
track->codecPrivate = NULL;
@@ -195,22 +198,13 @@
}
break;
case HB_ACODEC_FAAC:
- if( job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 )
- {
- track->codecPrivate = NULL;
- track->codecPrivateSize = 0;
- track->codecID = MK_ACODEC_AC3;
- }
- else
- {
- track->codecPrivate = audio->config.aac.bytes;
- track->codecPrivateSize = audio->config.aac.length;
- track->codecID = MK_ACODEC_AAC;
- }
+ track->codecPrivate = audio->config.aac.bytes;
+ track->codecPrivateSize = audio->config.aac.length;
+ track->codecID = MK_ACODEC_AAC;
break;
default:
*job->die = 1;
- hb_error("muxmkv: Unknown audio codec: %x", job->acodec);
+ hb_error("muxmkv: Unknown audio codec: %x", audio->out.codec);
return 0;
}
@@ -221,12 +215,12 @@
}
track->flagEnabled = 1;
track->trackType = MK_TRACK_AUDIO;
- track->language = audio->iso639_2;
- track->extra.audio.samplingFreq = (float)job->arate;
- track->extra.audio.channels = (job->acodec == HB_ACODEC_AC3 || job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->input_channel_layout) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->amixdown);
+ track->language = audio->lang.iso639_2;
+ track->extra.audio.samplingFreq = (float)audio->out.samplerate;
+ track->extra.audio.channels = (audio->out.codec == HB_ACODEC_AC3 ) ? HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT(audio->in.channel_layout) : HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown);
// track->defaultDuration = job->arate * 1000;
mux_data->track = mk_createTrack(m->file, track);
- if (job->acodec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)
+ if (audio->out.codec == HB_ACODEC_VORBIS && track->codecPrivate != NULL)
free(track->codecPrivate);
}
@@ -308,7 +302,7 @@
{
/* Audio */
timecode = buf->start * TIMECODE_SCALE;
- if (job->acodec == HB_ACODEC_VORBIS)
+ if (mux_data->codec == HB_ACODEC_VORBIS)
{
/* ughhh, vorbis is a pain :( */
op = (ogg_packet *)buf->data;
Index: libhb/common.c
===================================================================
--- libhb/common.c (revision 1364)
+++ libhb/common.c (working copy)
@@ -43,9 +43,7 @@
{ "Stereo", "HB_AMIXDOWN_STEREO", "stereo", HB_AMIXDOWN_STEREO },
{ "Dolby Surround", "HB_AMIXDOWN_DOLBY", "dpl1", HB_AMIXDOWN_DOLBY },
{ "Dolby Pro Logic II", "HB_AMIXDOWN_DOLBYPLII", "dpl2", HB_AMIXDOWN_DOLBYPLII },
- { "6-channel discrete", "HB_AMIXDOWN_6CH", "6ch", HB_AMIXDOWN_6CH },
- { "AC-3 Pass-through", "HB_AMIXDOWN_AC3", "ac-3", HB_AMIXDOWN_AC3 },
- { "Dolby Pro Logic II + AC-3", "HB_AMIXDOWN_DOLBYPLII_AC3", "dpl2+ac3", HB_AMIXDOWN_DOLBYPLII_AC3 },
+ { "6-channel discrete", "HB_AMIXDOWN_6CH", "6ch", HB_AMIXDOWN_6CH }
};
int hb_audio_mixdowns_count = sizeof( hb_audio_mixdowns ) /
sizeof( hb_mixdown_t );
@@ -115,7 +113,7 @@
if ( title->height == 0 || title->width == 0 || title->aspect == 0 )
{
hb_log( "hb_fix_aspect: incomplete info for title %d: "
- "height = %d, width = %d, aspect = %d",
+ "height = %d, width = %d, aspect = %d",
title->height, title->width, title->aspect );
return;
}
@@ -202,23 +200,6 @@
return 0;
}
- /* How many audio samples we put in each frame */
- switch( job->acodec )
- {
- case HB_ACODEC_FAAC:
- case HB_ACODEC_VORBIS:
- samples_per_frame = 1024;
- break;
- case HB_ACODEC_LAME:
- samples_per_frame = 1152;
- break;
- case HB_ACODEC_AC3:
- samples_per_frame = 1536;
- break;
- default:
- return 0;
- }
-
/* Get the duration in seconds */
length = 0;
for( i = job->chapter_start; i <= job->chapter_end; i++ )
@@ -232,19 +213,37 @@
/* Video overhead */
avail -= length * job->vrate * overhead / job->vrate_base;
- for( i = 0; job->audios[i] >= 0; i++ )
+ for( i = 0; i < hb_list_count(job->list_audio); i++ )
{
/* Audio data */
int abitrate;
- if( job->acodec & HB_ACODEC_AC3 ||
- job->audio_mixdowns[i] == HB_AMIXDOWN_AC3)
+ audio = hb_list_item( job->list_audio, i);
+
+ /* How many audio samples we put in each frame */
+ switch( audio->out.codec )
{
+ case HB_ACODEC_FAAC:
+ case HB_ACODEC_VORBIS:
+ samples_per_frame = 1024;
+ break;
+ case HB_ACODEC_LAME:
+ samples_per_frame = 1152;
+ break;
+ case HB_ACODEC_AC3:
+ samples_per_frame = 1536;
+ break;
+ default:
+ return 0;
+ }
+
+ if( audio->out.codec == HB_ACODEC_AC3 ||
+ audio->out.codec == HB_ACODEC_DCA)
+ {
/*
- * For AC-3 we take the bitrate from the input audio
+ * For pass through we take the bitrate from the input audio
* bitrate as we are simply passing it through.
*/
- audio = hb_list_item( title->list_audio, job->audios[i] );
- abitrate = audio->bitrate / 8;
+ abitrate = audio->in.bitrate / 8;
}
else
{
@@ -252,12 +251,12 @@
* Where we are transcoding the audio we use the destination
* bitrate.
*/
- abitrate = job->abitrate * 1000 / 8;
+ abitrate = audio->out.bitrate * 1000 / 8;
}
avail -= length * abitrate;
/* Audio overhead */
- avail -= length * job->arate * overhead / samples_per_frame;
+ avail -= length * audio->out.samplerate * overhead / samples_per_frame;
}
if( avail < 0 )
@@ -654,3 +653,33 @@
*_f = NULL;
}
+/**********************************************************************
+ * hb_audio_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_audio_t *hb_audio_copy(const hb_audio_t *src)
+{
+ hb_audio_t *audio = hb_audio_new();
+ memcpy(audio, src, sizeof(*audio));
+ return audio;
+}
+
+/**********************************************************************
+ * hb_audio_new
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_audio_t *hb_audio_new(void)
+{
+ hb_audio_t *audio = calloc(1, sizeof(*audio));
+ /* Initalize some sensable defaults */
+ audio->in.codec = 0;
+ audio->out.codec = HB_ACODEC_FAAC;
+ audio->out.bitrate = 128;
+ audio->out.samplerate = 44100;
+ audio->out.mixdown = HB_AMIXDOWN_DOLBYPLII;
+ audio->out.dynamic_range_compression = 0;
+
+ return audio;
+}
Index: libhb/encvorbis.c
===================================================================
--- libhb/encvorbis.c (revision 1364)
+++ libhb/encvorbis.c (working copy)
@@ -44,13 +44,14 @@
int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
{
+ hb_audio_t * audio = w->audio;
int i;
ogg_packet header[3];
struct ovectl_ratemanage2_arg ctl_rate_arg;
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
- pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown);
+ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->out.mixdown);
pv->job = job;
@@ -58,17 +59,18 @@
/* 28kbps/channel seems to be the minimum for 6ch vorbis. */
int min_bitrate = 28 * pv->out_discrete_channels;
- if (pv->out_discrete_channels > 2 && job->abitrate < min_bitrate)
+ if (pv->out_discrete_channels > 2 && audio->out.bitrate < min_bitrate)
{
- hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", job->abitrate, pv->out_discrete_channels);
+ hb_log( "encvorbis: Selected bitrate (%d kbps) too low for %d channel audio.", audio->out.bitrate, pv->out_discrete_channels);
hb_log( "encvorbis: Resetting bitrate to %d kbps", min_bitrate);
- job->abitrate = min_bitrate;
+ /* Naughty! We shouldn't modify the audio from here. */
+ audio->out.bitrate = min_bitrate;
}
/* init */
vorbis_info_init( &pv->vi );
if( vorbis_encode_setup_managed( &pv->vi, pv->out_discrete_channels,
- job->arate, -1, 1000 * job->abitrate, -1 ) )
+ audio->out.samplerate, -1, 1000 * audio->out.bitrate, -1 ) )
{
hb_error( "encvorbis: vorbis_encode_setup_managed failed.\n" );
*job->die = 1;
@@ -80,7 +82,7 @@
hb_log( "encvorbis: vorbis_encode_ctl( ratemanage2_get ) failed" );
}
- ctl_rate_arg.bitrate_average_kbps = job->abitrate;
+ ctl_rate_arg.bitrate_average_kbps = audio->out.bitrate;
ctl_rate_arg.management_active = 1;
if( vorbis_encode_ctl( &pv->vi, OV_ECTL_RATEMANAGE2_SET, &ctl_rate_arg ) ||
Index: libhb/common.h
===================================================================
--- libhb/common.h (revision 1364)
+++ libhb/common.h (working copy)
@@ -70,6 +70,9 @@
int hb_calc_bitrate( hb_job_t *, int size );
+hb_audio_t *hb_audio_copy(const hb_audio_t *src);
+hb_audio_t *hb_audio_new();
+
struct hb_rate_s
{
char * string;
@@ -175,77 +178,9 @@
int areBframes;
int vfr;
- /* Audio tracks:
- audios: Indexes in hb_title_t's audios list, starting from 0.
- -1 indicates the end of the list
- audio_mixdowns: The mixdown to be used for each audio track in audios[] */
+ /* List of audio settings. */
+ hb_list_t * list_audio;
-/* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
-#define HB_AMIXDOWN_DCA_FORMAT_MASK 0x00FFF000
-#define HB_AMIXDOWN_A52_FORMAT_MASK 0x00000FF0
-#define HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK 0x0000000F
-
-/* define the HB_AMIXDOWN_XXXX values */
-
-#define HB_AMIXDOWN_MONO 0x01000001
-// DCA_FORMAT of DCA_MONO = 0 = 0x000
-// A52_FORMAT of A52_MONO = 1 = 0x01
-// discrete channel count of 1
-
-#define HB_AMIXDOWN_STEREO 0x02002022
-// DCA_FORMAT of DCA_STEREO = 2 = 0x002
-// A52_FORMAT of A52_STEREO = 2 = 0x02
-// discrete channel count of 2
-
-#define HB_AMIXDOWN_DOLBY 0x042070A2
-// DCA_FORMAT of DCA_3F1R | DCA_OUT_DPLI = 519 = 0x207
-// A52_FORMAT of A52_DOLBY = 10 = 0x0A
-// discrete channel count of 2
-
-#define HB_AMIXDOWN_DOLBYPLII 0x084094A2
-// DCA_FORMAT of DCA_3F2R | DCA_OUT_DPLII = 1033 = 0x409
-// A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74 = 0x4A
-// discrete channel count of 2
-
-#define HB_AMIXDOWN_6CH 0x10089176
-// DCA_FORMAT of DCA_3F2R | DCA_LFE = 137 = 0x089
-// A52_FORMAT of A52_3F2R | A52_LFE = 23 = 0x17
-// discrete channel count of 6
-
-#define HB_AMIXDOWN_AC3 0x20000000
-
-#define HB_AMIXDOWN_DOLBYPLII_AC3 0x404094A2
-// DCA_FORMAT of DCA_3F2R | DCA_OUT_DPLII = 1033 = 0x409
-// A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74 = 0x4A
-// discrete channel count of 2
-
-/* define some macros to extract the various information from the HB_AMIXDOWN_XXXX values */
-#define HB_AMIXDOWN_GET_DCA_FORMAT( a ) ( ( a & HB_AMIXDOWN_DCA_FORMAT_MASK ) >> 12 )
-#define HB_AMIXDOWN_GET_A52_FORMAT( a ) ( ( a & HB_AMIXDOWN_A52_FORMAT_MASK ) >> 4 )
-#define HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK ) )
-
- int audios[8];
- int audio_mixdowns[8];
-
- /* Audio settings:
- acodec: output codec
- abitrate: output bitrate (kbps)
- arate: output samplerate (Hz)
- HB_ACODEC_AC3 means pass-through, then abitrate and arate are
- ignored */
-#define HB_ACODEC_MASK 0x00FF00
-#define HB_ACODEC_FAAC 0x000100
-#define HB_ACODEC_LAME 0x000200
-#define HB_ACODEC_VORBIS 0x000400
-#define HB_ACODEC_AC3 0x000800
-#define HB_ACODEC_MPGA 0x001000
-#define HB_ACODEC_LPCM 0x002000
-#define HB_ACODEC_DCA 0x004000
- int acodec;
- int abitrate;
- int arate;
- float dynamic_range_compression;
-
/* Subtitle settings:
subtitle: index in hb_title_t's subtitles list, starting
from 0. -1 means no subtitle */
@@ -300,22 +235,38 @@
#endif
};
-struct hb_audio_s
-{
- int id;
- char lang[1024];
- char lang_simple[1024];
- char iso639_2[4];
- int codec;
- int rate;
- int bitrate;
+/* Audio Mixdown */
+/* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
+#define HB_AMIXDOWN_DCA_FORMAT_MASK 0x00FFF000
+#define HB_AMIXDOWN_A52_FORMAT_MASK 0x00000FF0
+#define HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK 0x0000000F
+/* define the HB_AMIXDOWN_XXXX values */
+#define HB_AMIXDOWN_MONO 0x01000001
+// DCA_FORMAT of DCA_MONO = 0 = 0x000
+// A52_FORMAT of A52_MONO = 1 = 0x01
+// discrete channel count of 1
+#define HB_AMIXDOWN_STEREO 0x02002022
+// DCA_FORMAT of DCA_STEREO = 2 = 0x002
+// A52_FORMAT of A52_STEREO = 2 = 0x02
+// discrete channel count of 2
+#define HB_AMIXDOWN_DOLBY 0x042070A2
+// DCA_FORMAT of DCA_3F1R | DCA_OUT_DPLI = 519 = 0x207
+// A52_FORMAT of A52_DOLBY = 10 = 0x0A
+// discrete channel count of 2
+#define HB_AMIXDOWN_DOLBYPLII 0x084094A2
+// DCA_FORMAT of DCA_3F2R | DCA_OUT_DPLII = 1033 = 0x409
+// A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74 = 0x4A
+// discrete channel count of 2
+#define HB_AMIXDOWN_6CH 0x10089176
+// DCA_FORMAT of DCA_3F2R | DCA_LFE = 137 = 0x089
+// A52_FORMAT of A52_3F2R | A52_LFE = 23 = 0x17
+// discrete channel count of 6
+/* define some macros to extract the various information from the HB_AMIXDOWN_XXXX values */
+#define HB_AMIXDOWN_GET_DCA_FORMAT( a ) ( ( a & HB_AMIXDOWN_DCA_FORMAT_MASK ) >> 12 )
+#define HB_AMIXDOWN_GET_A52_FORMAT( a ) ( ( a & HB_AMIXDOWN_A52_FORMAT_MASK ) >> 4 )
+#define HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK ) )
- /* ac3flags is only set when the source audio format is HB_ACODEC_AC3 */
- int ac3flags;
-
- /* dcaflags is only set when the source audio format is HB_ACODEC_DCA */
- int dcaflags;
-
+/* Input Channel Layout */
/* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
#define HB_INPUT_CH_LAYOUT_DISCRETE_FRONT_MASK 0x00F0000
#define HB_INPUT_CH_LAYOUT_DISCRETE_REAR_MASK 0x000F000
@@ -323,7 +274,6 @@
#define HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK 0xFFFF0FF
#define HB_INPUT_CH_LAYOUT_ENCODED_FRONT_MASK 0x00000F0
#define HB_INPUT_CH_LAYOUT_ENCODED_REAR_MASK 0x000000F
-
/* define the input channel layouts used to describe the channel layout of this audio */
#define HB_INPUT_CH_LAYOUT_MONO 0x0110010
#define HB_INPUT_CH_LAYOUT_STEREO 0x0220020
@@ -335,7 +285,6 @@
#define HB_INPUT_CH_LAYOUT_3F2R 0x0832032
#define HB_INPUT_CH_LAYOUT_4F2R 0x0942042
#define HB_INPUT_CH_LAYOUT_HAS_LFE 0x0000100
-
/* define some macros to extract the various information from the HB_AMIXDOWN_XXXX values */
#define HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT( a ) ( ( a & HB_INPUT_CH_LAYOUT_DISCRETE_FRONT_MASK ) >> 16 )
#define HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT( a ) ( ( a & HB_INPUT_CH_LAYOUT_DISCRETE_REAR_MASK ) >> 12 )
@@ -344,12 +293,64 @@
#define HB_INPUT_CH_LAYOUT_GET_ENCODED_FRONT_COUNT( a ) ( ( a & HB_INPUT_CH_LAYOUT_ENCODED_FRONT_MASK ) >> 4 )
#define HB_INPUT_CH_LAYOUT_GET_ENCODED_REAR_COUNT( a ) ( ( a & HB_INPUT_CH_LAYOUT_ENCODED_REAR_MASK ) )
- /* input_channel_layout is the channel layout of this audio */
- /* this is used to provide a common way of describing the source audio */
- int input_channel_layout;
+struct hb_audio_s
+{
+#define HB_ACODEC_MASK 0x00FF00
+#define HB_ACODEC_FAAC 0x000100
+#define HB_ACODEC_LAME 0x000200
+#define HB_ACODEC_VORBIS 0x000400
+#define HB_ACODEC_AC3 0x000800
+#define HB_ACODEC_MPGA 0x001000
+#define HB_ACODEC_LPCM 0x002000
+#define HB_ACODEC_DCA 0x004000
+ /* Input */
+ struct
+ {
+ int track; /* Input track number */
+ uint32_t codec; /* Input audio codec */
+ int samplerate; /* Input sample rate (Hz) */
+ int bitrate; /* Input bitrate (kbps) */
+ int channel_layout;
+ /* channel_layout is the channel layout of this audio this is used to
+ * provide a common way of describing the source audio
+ */
+ } in;
+
+ /* Output */
+ struct
+ {
+ int track; /* Output track number */
+ uint32_t codec; /* Output audio codec.
+ * HB_ACODEC_AC3 means pass-through, then bitrate and samplerate
+ * are ignored.
+ */
+ int samplerate; /* Output sample rate (Hz) */
+ int bitrate; /* Output bitrate (kbps) */
+ int mixdown; /* The mixdown format to be used for this audio track (see HB_AMIXDOWN_*) */
+ double dynamic_range_compression; /* Amount of DRC that gets applied to this track */
+ } out;
+
+ /* Misc. */
+ union
+ {
+ int ac3; /* flags.ac3 is only set when the source audio format is HB_ACODEC_AC3 */
+ int dca; /* flags.dca is only set when the source audio format is HB_ACODEC_DCA */
+ } flags;
+
+ struct
+ {
+ char description[1024];
+ char simple[1024];
+ char iso639_2[4];
+ } lang;
+
#ifdef __LIBHB__
/* Internal data */
+ /* Input */
+ int id;
+
+ /* Misc. */
hb_fifo_t * fifo_in; /* AC3/MPEG/LPCM ES */
hb_fifo_t * fifo_raw; /* Raw audio */
hb_fifo_t * fifo_sync; /* Resampled, synced raw audio */
@@ -357,9 +358,6 @@
hb_esconfig_t config;
hb_mux_data_t * mux_data;
-
- /* amixdown is the mixdown format to be used for this audio track */
- int amixdown;
#endif
};
@@ -506,10 +504,8 @@
hb_fifo_t * fifo_out;
hb_esconfig_t * config;
- /* amixdown is the mixdown format to be used if the work object is an audio track */
- int amixdown;
- /* source_acodec is the source audio codec if the work object is an audio track */
- int source_acodec;
+ /* Pointer hb_audio_t so we have access to the info in the audio worker threads. */
+ hb_audio_t *audio;
hb_work_private_t * private_data;
Index: macosx/Controller.mm
===================================================================
--- macosx/Controller.mm (revision 1364)
+++ macosx/Controller.mm (working copy)
@@ -81,7 +81,7 @@
outputPanel = [[HBOutputPanelController alloc] init];
fPictureController = [[PictureController alloc] initWithDelegate:self];
- fQueueController = [[HBQueueController alloc] init];
+ //*DISABLE QUEUE* fQueueController = [[HBQueueController alloc] init];
fAdvancedOptions = [[HBAdvancedController alloc] init];
/* we init the HBPresets class which currently is only used
* for updating built in presets, may move more functionality
@@ -1467,8 +1467,8 @@
hb_title_t * title = (hb_title_t *) hb_list_item( list,
[fSrcTitlePopUp indexOfSelectedItem] );
hb_job_t * job = title->job;
- //int i;
-
+ hb_audio_t *audio;
+
/* Chapter selection */
job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
job->chapter_end = [fSrcChapterEndPopUp indexOfSelectedItem] + 1;
@@ -1478,7 +1478,8 @@
int codecs = [fDstCodecsPopUp indexOfSelectedItem];
job->mux = FormatSettings[format][codecs] & HB_MUX_MASK;
job->vcodec = FormatSettings[format][codecs] & HB_VCODEC_MASK;
- job->acodec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+
+
/* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
if ([fDstFormatPopUp indexOfSelectedItem] == 0)
{
@@ -1594,67 +1595,78 @@
job->subtitle = [fSubPopUp indexOfSelectedItem] - 2;
/* Audio tracks and mixdowns */
- /* check for the condition where track 2 has an audio selected, but track 1 does not */
- /* we will use track 2 as track 1 in this scenario */
- if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+ /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/
+ int num_audio_tracks = hb_list_count(job->list_audio);
+ for( int i = 0; i < num_audio_tracks;i++)
{
- job->audios[0] = [fAudLang1PopUp indexOfSelectedItem] - 1;
- job->audios[1] = [fAudLang2PopUp indexOfSelectedItem] - 1; /* will be -1 if "none" is selected */
- job->audios[2] = -1;
- job->audio_mixdowns[0] = [[fAudTrack1MixPopUp selectedItem] tag];
- job->audio_mixdowns[1] = [[fAudTrack2MixPopUp selectedItem] tag];
+ audio = hb_audio_copy( (hb_audio_t *) hb_list_item( job->list_audio, i ) );
+ hb_list_rem(job->list_audio, audio); // issue, this give us a memory crash ... FIX ME!!!
}
- else if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+ /* Now lets add our new tracks to the audio list here */
+ if ([fAudLang1PopUp indexOfSelectedItem] > 0)
{
- job->audios[0] = [fAudLang2PopUp indexOfSelectedItem] - 1;
- job->audio_mixdowns[0] = [[fAudTrack2MixPopUp selectedItem] tag];
- job->audios[1] = -1;
+ /* First we copy the source audio structure (remember, in the popup 0 is "None" so we subtract 1 to match the list->audio*/
+ audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang1PopUp indexOfSelectedItem] - 1 ) );
+ /* We go ahead and assign values to our audio->out.<properties> */
+ audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+ audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+ audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+ audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+ audio->out.mixdown = [[fAudTrack1MixPopUp selectedItem] tag];
+ audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+ /* We add the newly modified audio track to job->list_audio */
+ hb_list_add(job->list_audio, audio );
+
+ /*HACK: We use the format and codecs popups to determine if we should slide in the extra ac3 passthru track for the atv hybrid mp4 */
+ if (format == 0 && codecs == 2 && audio->in.codec != HB_ACODEC_DCA) // if mp4 and aac + ac3 and input is NOT DTS (dts cannot be passed through as ac3)
+ {
+ audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang1PopUp indexOfSelectedItem] - 1 ) );
+ /* We go ahead and assign values to our audio->out.<properties> */
+ audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+ audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+ audio->out.codec = audio->in.codec; // <-- HB_ACODEC_AC3
+ audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+ audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+ audio->out.mixdown = HB_ACODEC_AC3;//<-- Lets manually set the mixdown int
+ audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+ /* We add the newly modified audio track to job->list_audio */
+ hb_list_add(job->list_audio, audio );
+ }
+
}
- else
+ if ([fAudLang2PopUp indexOfSelectedItem] > 0)
{
- job->audios[0] = -1;
+ /* First we copy the source audio structure (remember, in the popup 0 is "None" so we subtract 1 to match the list->audio*/
+ audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang2PopUp indexOfSelectedItem] - 1 ) );
+ /* Now we modify it according to the gui settings for the specified track number */
+ /* We go ahead and assign values to our audio->out.<properties> */
+ audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+ audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+ audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+ audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+ audio->out.mixdown = [[fAudTrack2MixPopUp selectedItem] tag];
+ audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+ /* We add the newly modified audio track to job->list_audio */
+ hb_list_add(job->list_audio, audio );
+
+ /*HACK: We use the format and codecs popups to determine if we should slide in the extra ac3 passthru track for the atv hybrid mp4 */
+ if (format == 0 && codecs == 2 && audio->in.codec != HB_ACODEC_DCA) // if mp4 and aac + ac3 and input is NOT DTS (dts cannot be passed through as ac3)
+ {
+ audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, [fAudLang2PopUp indexOfSelectedItem] - 1 ) );
+ /* We go ahead and assign values to our audio->out.<properties> */
+ audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+ audio->out.codec = FormatSettings[format][codecs] & HB_ACODEC_MASK;
+ audio->out.codec = audio->in.codec; // <-- HB_ACODEC_AC3
+ audio->out.samplerate = hb_audio_rates[[fAudRatePopUp indexOfSelectedItem]].rate;
+ audio->out.bitrate = [[fAudBitratePopUp selectedItem] tag];
+ audio->out.mixdown = HB_ACODEC_AC3;//<-- Lets manually input the mixdown int
+ audio->out.dynamic_range_compression = [fAudDrcField floatValue];
+ /* We add the newly modified audio track to job->list_audio */
+ hb_list_add(job->list_audio, audio );
+ }
}
- /*
- * Where one or more of the audio tracks has a mixdown of DPLII+AC3 we need to create an extra
- * track for each.
- */
- if (job->audio_mixdowns[0] == HB_AMIXDOWN_DOLBYPLII_AC3)
- {
- /*
- * Make space for the AC3 track by moving 1 to 2
- */
- job->audios[2] = job->audios[1];
- job->audio_mixdowns[2] = job->audio_mixdowns[1];
- job->audios[1] = job->audios[0];
- job->audio_mixdowns[0] = HB_AMIXDOWN_DOLBYPLII;
- job->audio_mixdowns[1] = HB_AMIXDOWN_AC3;
- }
-
- if (job->audio_mixdowns[1] == HB_AMIXDOWN_DOLBYPLII_AC3)
- {
- job->audios[2] = job->audios[1];
- job->audio_mixdowns[1] = HB_AMIXDOWN_DOLBYPLII;
- job->audio_mixdowns[2] = HB_AMIXDOWN_AC3;
- job->audios[3] = -1;
- }
-
- if (job->audio_mixdowns[2] == HB_AMIXDOWN_DOLBYPLII_AC3)
- {
- job->audios[3] = job->audios[2];
- job->audio_mixdowns[2] = HB_AMIXDOWN_DOLBYPLII;
- job->audio_mixdowns[3] = HB_AMIXDOWN_AC3;
- job->audios[4] = -1;
- }
-
- /* Audio settings */
- job->arate = hb_audio_rates[[fAudRatePopUp
- indexOfSelectedItem]].rate;
- job->abitrate = [[fAudBitratePopUp selectedItem] tag];
- /* Dynamic Range Compression */
- job->dynamic_range_compression = [fAudDrcField floatValue];
-
/* set vfr according to the Picture Window */
if ([fPictureController vfr])
{
@@ -1785,16 +1797,16 @@
// Create a Queue Controller job group. Each job that we submit to libhb will also
// get added to the job group so that the queue can track the jobs.
- HBJobGroup * jobGroup = [HBJobGroup jobGroup];
+ //*DISABLE QUEUE* HBJobGroup * jobGroup = [HBJobGroup jobGroup];
// The job group can maintain meta data that libhb can not...
- [jobGroup setPresetName: [fPresetSelectedDisplay stringValue]];
+ //*DISABLE QUEUE* [jobGroup setPresetName: [fPresetSelectedDisplay stringValue]];
// Job groups require that each job within the group be assigned a unique id so
// that the queue can xref between itself and the private jobs that libhb
// maintains. The ID is composed a group id number and a "sequence" number. libhb
// does not use this id.
- static int jobGroupID = 0;
- jobGroupID++;
+ //*DISABLE QUEUE* static int jobGroupID = 0;
+ //*DISABLE QUEUE* jobGroupID++;
// A sequence number, starting at zero, is used to identifiy to each pass. This is
// used by the queue UI to determine if a pass if the first pass of an encode.
@@ -1835,9 +1847,9 @@
/*
* Add the pre-scan job
*/
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+ //*DISABLE QUEUE* job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
+ //*DISABLE QUEUE* [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
job->x264opts = x264opts_tmp;
}
@@ -1861,12 +1873,12 @@
job->select_subtitle = NULL;
job->pass = 1;
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+ //*DISABLE QUEUE* job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
+ //*DISABLE QUEUE* [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
job->pass = 2;
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+ //*DISABLE QUEUE* job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */
strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]);
@@ -1874,22 +1886,22 @@
job->select_subtitle = subtitle_tmp;
hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
+ //*DISABLE QUEUE* [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
}
else
{
job->indepth_scan = 0;
job->pass = 0;
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
+ //*DISABLE QUEUE* job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
+ //*DISABLE QUEUE* [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
}
NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
[[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
// Let the queue controller know about the job group
- [fQueueController addJobGroup:jobGroup];
+ //*DISABLE QUEUE* [fQueueController addJobGroup:jobGroup];
}
/* Rip: puts up an alert before ultimately calling doRip
@@ -1941,7 +1953,7 @@
otherwise, just rip the queue */
if( hb_count( fHandle ) == 0)
{
- [self doAddToQueue];
+ [self doAddToQueue];
}
NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
@@ -2787,17 +2799,15 @@
- (IBAction) setEnabledStateOfAudioMixdownControls: (id) sender
{
-
/* enable/disable the mixdown text and popupbutton for audio track 1 */
- [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES];
- [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ?
- [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
-
- /* enable/disable the mixdown text and popupbutton for audio track 2 */
- [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES];
- [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ?
- [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
-
+ [fAudTrack1MixPopUp setEnabled: ([fAudLang1PopUp indexOfSelectedItem] == 0) ? NO : YES];
+ [fAudTrack1MixLabel setTextColor: ([fAudLang1PopUp indexOfSelectedItem] == 0) ?
+ [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
+
+ /* enable/disable the mixdown text and popupbutton for audio track 2 */
+ [fAudTrack2MixPopUp setEnabled: ([fAudLang2PopUp indexOfSelectedItem] == 0) ? NO : YES];
+ [fAudTrack2MixLabel setTextColor: ([fAudLang2PopUp indexOfSelectedItem] == 0) ?
+ [NSColor disabledControlTextColor] : [NSColor controlTextColor]];
}
- (IBAction) addAllAudioTracksToPopUp: (id) sender
@@ -2808,14 +2818,14 @@
hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
hb_audio_t * audio;
-
+
[sender removeAllItems];
[sender addItemWithTitle: _( @"None" )];
for( int i = 0; i < hb_list_count( title->list_audio ); i++ )
{
- audio = (hb_audio_t *) hb_list_item( title->list_audio, i );
+ audio = hb_audio_copy( (hb_audio_t *) hb_list_item( title->list_audio, i ) );
[[sender menu] addItemWithTitle:
- [NSString stringWithCString: audio->lang]
+ [NSString stringWithCString: audio->lang.description]
action: NULL keyEquivalent: @""];
}
[sender selectItemAtIndex: 0];
@@ -2863,17 +2873,17 @@
- (IBAction) audioTrackPopUpChanged: (id) sender mixdownToUse: (int) mixdownToUse
{
-
+
/* make sure we have a selected title before continuing */
if (fTitle == NULL) return;
-
+
/* find out if audio track 1 or 2 was changed - this is passed to us in the tag of the sender */
/* the sender will have been either fAudLang1PopUp (tag = 0) or fAudLang2PopUp (tag = 1) */
int thisAudio = [sender tag];
-
+
/* get the index of the selected audio */
int thisAudioIndex = [sender indexOfSelectedItem] - 1;
-
+
#if 0
/* Handbrake can't currently cope with ripping the same source track twice */
/* So, if this audio is also selected in the other audio track popup, set that popup's selection to "none" */
@@ -2887,10 +2897,10 @@
[self audioTrackPopUpChanged: otherAudioPopUp];
}
#endif
-
+
/* pointer for the hb_audio_s struct we will use later on */
hb_audio_t * audio;
-
+
/* find out what the currently-selected output audio codec is */
int format = [fDstFormatPopUp indexOfSelectedItem];
int codecs = [fDstCodecsPopUp indexOfSelectedItem];
@@ -2900,17 +2910,17 @@
bool mp4AacAc3;
if (format == 0 && codecs == 2) // if mp4 and aac + ac3
{
- mp4AacAc3 = 1;
+ mp4AacAc3 = 1;
}
else
{
- mp4AacAc3 = 0;
+ mp4AacAc3 = 0;
}
-
+
/* pointer to this track's mixdown NSPopUpButton */
NSTextField * mixdownTextField;
NSPopUpButton * mixdownPopUp;
-
+
/* find our mixdown NSTextField and NSPopUpButton */
if (thisAudio == 0)
{
@@ -2922,125 +2932,124 @@
mixdownTextField = fAudTrack2MixLabel;
mixdownPopUp = fAudTrack2MixPopUp;
}
-
+
/* delete the previous audio mixdown options */
[mixdownPopUp removeAllItems];
-
+
/* check if the audio mixdown controls need their enabled state changing */
[self setEnabledStateOfAudioMixdownControls: NULL];
-
+
if (thisAudioIndex != -1)
{
-
+
/* get the audio */
- audio = (hb_audio_t *) hb_list_item( fTitle->list_audio, thisAudioIndex );
+ audio = hb_audio_copy( (hb_audio_t *) hb_list_item( fTitle->list_audio, thisAudioIndex ) );// Should "fTitle" be title and be setup ?
if (audio != NULL)
{
-
+
/* find out if our selected output audio codec supports mono and / or 6ch */
/* we also check for an input codec of AC3 or DCA,
- as they are the only libraries able to do the mixdown to mono / conversion to 6-ch */
+ as they are the only libraries able to do the mixdown to mono / conversion to 6-ch */
/* audioCodecsSupportMono and audioCodecsSupport6Ch are the same for now,
- but this may change in the future, so they are separated for flexibility */
- int audioCodecsSupportMono = ((audio->codec == HB_ACODEC_AC3 ||
- audio->codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC);
- int audioCodecsSupport6Ch = ((audio->codec == HB_ACODEC_AC3 ||
- audio->codec == HB_ACODEC_DCA) && (acodec == HB_ACODEC_FAAC ||
- acodec == HB_ACODEC_VORBIS));
-
+ but this may change in the future, so they are separated for flexibility */
+ int audioCodecsSupportMono = ((audio->in.codec == HB_ACODEC_AC3 ||
+ audio->in.codec == HB_ACODEC_DCA) && acodec == HB_ACODEC_FAAC);
+ int audioCodecsSupport6Ch = ((audio->in.codec == HB_ACODEC_AC3 ||
+ audio->in.codec == HB_ACODEC_DCA) && (acodec == HB_ACODEC_FAAC ||
+ acodec == HB_ACODEC_VORBIS));
+
/* check for AC-3 passthru */
- if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
+ if (audio->in.codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
{
-
- [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: "AC3 Passthru"]
- action: NULL keyEquivalent: @""];
+
+ [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: "AC3 Passthru"]
+ action: NULL keyEquivalent: @""];
}
else
{
-
+
/* add the appropriate audio mixdown menuitems to the popupbutton */
/* in each case, we set the new menuitem's tag to be the amixdown value for that mixdown,
- so that we can reference the mixdown later */
-
+ so that we can reference the mixdown later */
+
/* keep a track of the min and max mixdowns we used, so we can select the best match later */
int minMixdownUsed = 0;
int maxMixdownUsed = 0;
/* get the input channel layout without any lfe channels */
- int layout = audio->input_channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
+ int layout = audio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
- /* do we want to add a mono option? */
- if (!mp4AacAc3 && audioCodecsSupportMono == 1) {
- NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: hb_audio_mixdowns[0].human_readable_name]
- action: NULL keyEquivalent: @""];
- [menuItem setTag: hb_audio_mixdowns[0].amixdown];
- if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[0].amixdown;
- maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[0].amixdown);
- }
-
- /* do we want to add a stereo option? */
- /* offer stereo if we have a mono source and non-mono-supporting codecs, as otherwise we won't have a mixdown at all */
- /* also offer stereo if we have a stereo-or-better source */
- if (((!mp4AacAc3 || audio->codec == HB_ACODEC_MPGA || audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_DCA) && ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO))) {
- NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: hb_audio_mixdowns[1].human_readable_name]
- action: NULL keyEquivalent: @""];
- [menuItem setTag: hb_audio_mixdowns[1].amixdown];
- if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[1].amixdown;
- maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[1].amixdown);
- }
-
- /* do we want to add a dolby surround (DPL1) option? */
- if (!mp4AacAc3 && (layout == HB_INPUT_CH_LAYOUT_3F1R || layout == HB_INPUT_CH_LAYOUT_3F2R || layout == HB_INPUT_CH_LAYOUT_DOLBY)) {
- NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: hb_audio_mixdowns[2].human_readable_name]
- action: NULL keyEquivalent: @""];
- [menuItem setTag: hb_audio_mixdowns[2].amixdown];
- if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[2].amixdown;
- maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[2].amixdown);
- }
-
- /* do we want to add a dolby pro logic 2 (DPL2) option? */
- if ((!mp4AacAc3 || audio->codec == HB_ACODEC_DCA) && layout == HB_INPUT_CH_LAYOUT_3F2R) {
- NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: hb_audio_mixdowns[3].human_readable_name]
- action: NULL keyEquivalent: @""];
- [menuItem setTag: hb_audio_mixdowns[3].amixdown];
- if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[3].amixdown;
- maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[3].amixdown);
- }
-
- /* do we want to add a 6-channel discrete option? */
- if (!mp4AacAc3 && (audioCodecsSupport6Ch == 1 && layout == HB_INPUT_CH_LAYOUT_3F2R && (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE))) {
- NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: hb_audio_mixdowns[4].human_readable_name]
- action: NULL keyEquivalent: @""];
- [menuItem setTag: hb_audio_mixdowns[4].amixdown];
- if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[4].amixdown;
- maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[4].amixdown);
- }
-
- /* do we want to add an AC-3 passthrough option? */
- if (audio->codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3) {
- NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: hb_audio_mixdowns[5].human_readable_name]
- action: NULL keyEquivalent: @""];
- [menuItem setTag: hb_audio_mixdowns[5].amixdown];
- if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[5].amixdown;
- maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
- }
-
- /* do we want to add the DPLII+AC3 passthrough option? */
- if (mp4AacAc3 && audio->codec == HB_ACODEC_AC3) {
- NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
- [NSString stringWithCString: hb_audio_mixdowns[6].human_readable_name]
- action: NULL keyEquivalent: @""];
- [menuItem setTag: hb_audio_mixdowns[6].amixdown];
- if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[6].amixdown;
- maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[6].amixdown);
- }
+ /* do we want to add a mono option? */
+ //if (!mp4AacAc3 && audioCodecsSupportMono == 1)
+ if (audioCodecsSupportMono == 1)
+ {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: hb_audio_mixdowns[0].human_readable_name]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: hb_audio_mixdowns[0].amixdown];
+ if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[0].amixdown;
+ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[0].amixdown);
+ }
+
+ /* do we want to add a stereo option? */
+ /* offer stereo if we have a mono source and non-mono-supporting codecs, as otherwise we won't have a mixdown at all */
+ /* also offer stereo if we have a stereo-or-better source */
+ //if (((!mp4AacAc3 || audio->in.codec == HB_ACODEC_MPGA || audio->in.codec == HB_ACODEC_LPCM || audio->in.codec == HB_ACODEC_DCA) && ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO)))
+ //if (((audio->in.codec == HB_ACODEC_MPGA || audio->in.codec == HB_ACODEC_LPCM || audio->in.codec == HB_ACODEC_DCA) && ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO)))
+ if ((layout == HB_INPUT_CH_LAYOUT_MONO && audioCodecsSupportMono == 0) || layout >= HB_INPUT_CH_LAYOUT_STEREO)
+ {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: hb_audio_mixdowns[1].human_readable_name]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: hb_audio_mixdowns[1].amixdown];
+ if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[1].amixdown;
+ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[1].amixdown);
+ }
+
+ /* do we want to add a dolby surround (DPL1) option? */
+ if (layout == HB_INPUT_CH_LAYOUT_3F1R || layout == HB_INPUT_CH_LAYOUT_3F2R || layout == HB_INPUT_CH_LAYOUT_DOLBY)
+ {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: hb_audio_mixdowns[2].human_readable_name]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: hb_audio_mixdowns[2].amixdown];
+ if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[2].amixdown;
+ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[2].amixdown);
+ }
+
+ /* do we want to add a dolby pro logic 2 (DPL2) option? */
+ if (layout == HB_INPUT_CH_LAYOUT_3F2R)
+ {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: hb_audio_mixdowns[3].human_readable_name]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: hb_audio_mixdowns[3].amixdown];
+ if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[3].amixdown;
+ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[3].amixdown);
+ }
+
+ /* do we want to add a 6-channel discrete option? */
+ if (!mp4AacAc3 && (audioCodecsSupport6Ch == 1 && layout == HB_INPUT_CH_LAYOUT_3F2R && (audio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE)))
+ {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: hb_audio_mixdowns[4].human_readable_name]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: hb_audio_mixdowns[4].amixdown];
+ if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[4].amixdown;
+ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[4].amixdown);
+ }
+
+ /* do we want to add an AC-3 passthrough option? */
+ if (audio->in.codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3) {
+ NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+ [NSString stringWithCString: hb_audio_mixdowns[5].human_readable_name]
+ action: NULL keyEquivalent: @""];
+ [menuItem setTag: hb_audio_mixdowns[5].amixdown];
+ if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[5].amixdown;
+ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
+ }
+
/* auto-select the best mixdown based on our saved mixdown preference */
/* for now, this is hard-coded to a "best" mixdown of HB_AMIXDOWN_DOLBYPLII */
@@ -3059,24 +3068,24 @@
/* if useMixdown > maxMixdownUsed, then use maxMixdownUsed */
if (useMixdown > maxMixdownUsed) useMixdown = maxMixdownUsed;
-
+
/* if useMixdown < minMixdownUsed, then use minMixdownUsed */
if (useMixdown < minMixdownUsed) useMixdown = minMixdownUsed;
-
+
/* select the (possibly-amended) preferred mixdown */
[mixdownPopUp selectItemWithTag: useMixdown];
/* lets call the audioTrackMixdownChanged method here to determine appropriate bitrates, etc. */
[self audioTrackMixdownChanged: NULL];
}
-
+
}
}
-
+
/* see if the new audio track choice will change the bitrate we need */
[self calculateBitrate: sender];
-
+
}
- (IBAction) audioTrackMixdownChanged: (id) sender
{
@@ -3095,9 +3104,7 @@
case HB_ACODEC_FAAC:
/* check if we have a 6ch discrete conversion in either audio track */
if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH ||
- [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH ||
- [[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3 ||
- [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3)
+ [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
{
/* FAAC is happy using our min bitrate of 32 kbps, even for 6ch */
minbitrate = 32;
@@ -3164,9 +3171,7 @@
/* select the default bitrate (but use 384 for 6-ch AAC) */
if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH ||
- [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH ||
- [[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3 ||
- [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_AC3)
+ [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
{
[fAudBitratePopUp selectItemWithTag: 384];
}
Index: macosx/HandBrake.plist
===================================================================
--- macosx/HandBrake.plist (revision 1364)
+++ macosx/HandBrake.plist (working copy)
@@ -9,7 +9,7 @@
<key>CFBundleExecutable</key>
<string>HandBrake</string>
<key>CFBundleGetInfoString</key>
- <string>0.9.2</string>
+ <string>0.9.3svn1364M</string>
<key>CFBundleIconFile</key>
<string>HandBrake</string>
<key>CFBundleIdentifier</key>
@@ -21,11 +21,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>0.9.2</string>
+ <string>0.9.3svn1364M</string>
<key>CFBundleSignature</key>
<string>HB##</string>
<key>CFBundleVersion</key>
- <string>2008021900</string>
+ <string>2008032501</string>
<key>NSHumanReadableCopyright</key>
<string>HandBrake Devs</string>
<key>NSMainNibFile</key>
Index: macosx/HBQueueController.mm
===================================================================
--- macosx/HBQueueController.mm (revision 1364)
+++ macosx/HBQueueController.mm (working copy)
@@ -141,10 +141,21 @@
crf = job->crf;
if (job->x264opts)
x264opts = [[NSString stringWithUTF8String:job->x264opts] retain];
- memcpy(audio_mixdowns, job->audio_mixdowns, sizeof(audio_mixdowns));
- acodec = job->acodec;
- abitrate = job->abitrate;
- arate = job->arate;
+ /* we need to get the job_list_item out of (hb_job_t *) job which we have above */
+ /* ... and now that we store these variables in job->list_audio, we need to get it and
+ display it appropriately, though I do not have the foggiest how to do it. :) */
+ //hb_audio_t * audio;
+ //for( int i = 0; i < hb_list_count(job->list_audio); i++ )
+ //{
+ //audio = hb_audio_copy( (hb_audio_t *) hb_list_item( job->list_audio, i ) );
+ //acodec = audio->out.codec;
+ //abitrate = audio->out.bitrate;
+ //arate = audio->out.samplerate;
+ //}
+ //memcpy(audio_mixdowns, job->audio_mixdowns, sizeof(audio_mixdowns));
+ //acodec = job->acodec;
+ //abitrate = job->abitrate;
+ //arate = job->arate;
subtitle = job->subtitle;
mux = job->mux;
if (job->file)
@@ -517,8 +528,8 @@
jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Surround", ai + 1]];
if (audio_mixdowns[ai] == HB_AMIXDOWN_DOLBYPLII)
jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Track %d: Dolby Pro Logic II", ai + 1]];
- if (audio_mixdowns[ai] == HB_AMIXDOWN_AC3)
- jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Pass-Through", ai + 1]];
+ //if (audio_mixdowns[ai] == HB_AMIXDOWN_AC3)
+ // jobAudioInfo = [jobAudioInfo stringByAppendingString:[NSString stringWithFormat:@", Pass-Through", ai + 1]];
}
if (withIcon) // implies indent the info