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