summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 )