diff options
-rw-r--r-- | libhb/common.c | 16 | ||||
-rw-r--r-- | libhb/common.h | 7 | ||||
-rw-r--r-- | libhb/deca52.c | 3 | ||||
-rw-r--r-- | libhb/muxmp4.c | 3 | ||||
-rw-r--r-- | libhb/sync.c | 15 | ||||
-rw-r--r-- | libhb/work.c | 26 | ||||
-rw-r--r-- | macosx/Controller.mm | 63 |
7 files changed, 116 insertions, 17 deletions
diff --git a/libhb/common.c b/libhb/common.c index 5608abe6f..dab7fb48f 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -43,7 +43,10 @@ hb_mixdown_t hb_audio_mixdowns[] = { "Stereo", "HB_AMIXDOWN_STEREO", "stereo", HB_AMIXDOWN_STEREO }, { "Dolby Surround", "HB_AMIXDOWN_DOLBY", "dpl1", HB_AMIXDOWN_DOLBY }, { "Dolby Pro Logic II", "HB_AMIXDOWN_DOLBYPLII", "dpl2", HB_AMIXDOWN_DOLBYPLII }, - { "6-channel discrete", "HB_AMIXDOWN_6CH", "6ch", HB_AMIXDOWN_6CH } }; + { "6-channel discrete", "HB_AMIXDOWN_6CH", "6ch", HB_AMIXDOWN_6CH }, + { "AC-3 Pass-through", "HB_AMIXDOWN_AC3", "ac-3", HB_AMIXDOWN_AC3 }, + { "Dolby PLII + AC-3", "HB_AMIXDOWN_DOLBYPLII_AC3", "dpl2+ac3", HB_AMIXDOWN_DOLBYPLII_AC3 }, +}; int hb_audio_mixdowns_count = sizeof( hb_audio_mixdowns ) / sizeof( hb_mixdown_t ); @@ -224,13 +227,22 @@ int hb_calc_bitrate( hb_job_t * job, int size ) { /* Audio data */ int abitrate; - if( job->acodec & HB_ACODEC_AC3 ) + if( job->acodec & HB_ACODEC_AC3 || + job->audio_mixdowns[i] == HB_AMIXDOWN_AC3) { + /* + * For AC-3 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; } else { + /* + * Where we are transcoding the audio we use the destination + * bitrate. + */ abitrate = job->abitrate * 1000 / 8; } avail -= length * abitrate; diff --git a/libhb/common.h b/libhb/common.h index 682b60c89..3dce71923 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -211,6 +211,13 @@ struct hb_job_s // 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 ) diff --git a/libhb/deca52.c b/libhb/deca52.c index 116ec7698..55d7b836d 100644 --- a/libhb/deca52.c +++ b/libhb/deca52.c @@ -215,7 +215,8 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) hb_list_getbytes( pv->list, pv->frame, pv->size, &pts, &pos ); /* AC3 passthrough: don't decode the AC3 frame */ - if( pv->job->acodec & HB_ACODEC_AC3 ) + if( pv->job->acodec & HB_ACODEC_AC3 || + w->amixdown == HB_AMIXDOWN_AC3 ) { buf = hb_buffer_init( pv->size ); memcpy( buf->data, pv->frame, pv->size ); diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c index f91482ee6..ff30bd9fe 100644 --- a/libhb/muxmp4.c +++ b/libhb/muxmp4.c @@ -303,7 +303,8 @@ static int MP4Init( hb_mux_object_t * m ) mux_data = malloc( sizeof( hb_mux_data_t ) ); audio->mux_data = mux_data; - if( job->acodec & HB_ACODEC_AC3 ) + if( job->acodec & HB_ACODEC_AC3 || + job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) { mux_data->track = MP4AddAC3AudioTrack( m->file, diff --git a/libhb/sync.c b/libhb/sync.c index 4f04c224f..8bdf0c20c 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -144,7 +144,8 @@ void syncClose( hb_work_object_t * w ) for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { - if( job->acodec & HB_ACODEC_AC3 ) + if( job->acodec & HB_ACODEC_AC3 || + job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) { free( pv->sync_audio[i].ac3_buf ); } @@ -206,7 +207,8 @@ static void InitAudio( hb_work_object_t * w, int i ) sync = &pv->sync_audio[i]; sync->audio = hb_list_item( title->list_audio, i ); - if( job->acodec & HB_ACODEC_AC3 ) + if( job->acodec & HB_ACODEC_AC3 || + job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) { /* Have a silent AC-3 frame ready in case we have to fill a gap */ @@ -637,7 +639,8 @@ static void SyncAudio( hb_work_object_t * w, int i ) sync = &pv->sync_audio[i]; audio = sync->audio; - if( job->acodec & HB_ACODEC_AC3 ) + if( job->acodec & HB_ACODEC_AC3 || + job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) { fifo = audio->fifo_out; rate = audio->rate; @@ -799,7 +802,8 @@ static void SyncAudio( hb_work_object_t * w, int i ) } } - if( job->acodec & HB_ACODEC_AC3 ) + if( job->acodec & HB_ACODEC_AC3 || + job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) { buf = hb_fifo_get( audio->fifo_raw ); buf->start = start; @@ -915,7 +919,8 @@ static void InsertSilence( hb_work_object_t * w, int i ) job = pv->job; sync = &pv->sync_audio[i]; - if( job->acodec & HB_ACODEC_AC3 ) + if( job->acodec & HB_ACODEC_AC3 || + job->audio_mixdowns[i] == HB_AMIXDOWN_AC3 ) { buf = hb_buffer_init( sync->ac3_size ); buf->start = sync->count_frames * 90000 / sync->audio->rate; diff --git a/libhb/work.c b/libhb/work.c index 45a67b226..10f7a04d6 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -351,7 +351,8 @@ static void do_job( hb_job_t * job, int cpu_count ) if ( job->dynamic_range_compression ) hb_log(" + dynamic range compression: %f", job->dynamic_range_compression); - /* if we are doing AC3 passthru, then remove any non-AC3 audios from the job */ + /* if we are doing AC3 passthru (at the codec level, not pass-through), + * then remove any non-AC3 audios from the job */ /* otherwise, Bad Things will happen */ for( i = 0; i < hb_list_count( title->list_audio ); ) { @@ -389,6 +390,8 @@ static void do_job( hb_job_t * job, int cpu_count ) int audioCodecsSupport6Ch = ((audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS)); + 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) { @@ -481,6 +484,7 @@ static void do_job( hb_job_t * job, int cpu_count ) } } + } /* log the output mixdown */ for (j = 0; j < hb_audio_mixdowns_count; j++) { @@ -496,12 +500,16 @@ static void do_job( hb_job_t * job, int cpu_count ) audio->config.vorbis.language = audio->lang_simple; - /* set up the audio work structures */ + /* set up the audio work structures */ audio->fifo_in = hb_fifo_init( 2048 ); audio->fifo_raw = hb_fifo_init( FIFO_CPU_MULT * cpu_count ); audio->fifo_sync = hb_fifo_init( FIFO_CPU_MULT * cpu_count ); audio->fifo_out = hb_fifo_init( FIFO_CPU_MULT * cpu_count ); + + /* + * Audio Decoder Thread + */ switch( audio->codec ) { case HB_ACODEC_AC3: @@ -529,8 +537,13 @@ static void do_job( hb_job_t * job, int cpu_count ) hb_list_add( job->list_work, audio_w ); - switch( job->acodec ) + /* + * Audio Encoder Thread + */ + if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 ) { + switch( job->acodec ) + { case HB_ACODEC_FAAC: w = getWork( WORK_ENCFAAC ); break; @@ -540,10 +553,15 @@ static void do_job( hb_job_t * job, int cpu_count ) case HB_ACODEC_VORBIS: w = getWork( WORK_ENCVORBIS ); break; + } } - if( job->acodec != HB_ACODEC_AC3 ) + if( job->acodec != HB_ACODEC_AC3 && + job->audio_mixdowns[i] != HB_AMIXDOWN_AC3) { + /* + * Add the encoder thread if not doing AC-3 pass through + */ w->fifo_in = audio->fifo_sync; w->fifo_out = audio->fifo_out; w->config = &audio->config; diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 8ef13d725..510fd21c1 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -21,7 +21,6 @@ static int FormatSettings[4][10] = { { HB_MUX_MP4 | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC, HB_MUX_MP4 | HB_VCODEC_X264 | HB_ACODEC_FAAC, - HB_MUX_MP4 | HB_VCODEC_X264 | HB_ACODEC_AC3, 0, 0 }, { HB_MUX_MKV | HB_VCODEC_FFMPEG | HB_ACODEC_FAAC, @@ -1550,6 +1549,38 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It job->audios[0] = -1; } + /* + * 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; @@ -2223,7 +2254,6 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It [fDstCodecsPopUp addItemWithTitle:_( @"MPEG-4 Video / AAC Audio" )]; [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AAC Audio" )]; - [fDstCodecsPopUp addItemWithTitle:_( @"AVC/H.264 Video / AC-3 Audio" )]; /* We enable the create chapters checkbox here since we are .mp4*/ [fCreateChapterMarkers setEnabled: YES]; /* We show the Large File (64 bit formatting) checkbox since we are .mp4 @@ -2922,6 +2952,25 @@ the user is using "Custom" settings by determining the sender*/ maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[4].amixdown); } + /* do we want to add an AC-3 passthrough option? */ + if (audio->codec == 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 (audio->codec == HB_ACODEC_AC3) { + NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle: + [NSString stringWithCString: hb_audio_mixdowns[6].human_readable_name] + action: NULL keyEquivalent: @""]; + [menuItem setTag: hb_audio_mixdowns[6].amixdown]; + if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[6].amixdown; + maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[6].amixdown); + } /* auto-select the best mixdown based on our saved mixdown preference */ /* for now, this is hard-coded to a "best" mixdown of HB_AMIXDOWN_DOLBYPLII */ @@ -2975,7 +3024,10 @@ the user is using "Custom" settings by determining the sender*/ { 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) + 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) { /* FAAC is happy using our min bitrate of 32 kbps, even for 6ch */ minbitrate = 32; @@ -3041,7 +3093,10 @@ the user is using "Custom" settings by determining the sender*/ } /* select the default bitrate (but use 384 for 6-ch AAC) */ - if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH || [[fAudTrack2MixPopUp selectedItem] tag] == HB_AMIXDOWN_6CH) + 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) { [fAudBitratePopUp selectItemWithTag: 384]; } |