summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormaurj <[email protected]>2007-05-02 15:56:39 +0000
committermaurj <[email protected]>2007-05-02 15:56:39 +0000
commit7800f22f054d4a96731c94bc71310c09a2b8235f (patch)
treeccee5caab83f8bda1057985f71145ef83bbfb0be
parent3a55755f5bd2fb02d5e87f100b83f81e61f7bf82 (diff)
Added support for DTS audio. DTS audio streams (of 5.1 audio and below) will be detected and decoded. This requires a new library - libdca (and patch) - which is included (in patched form) in a new version of the pre-built UB Darwin contribs (0012). These have been uploaded to download.m0k.org/handbrake/contrib/ .
I haven't yet added any code to Controller.mm to recognise the DTS streams as supporting mono / 6ch DPL1 / DPL2 downmixes. Note: running Jam on the new library required me to update some tools on Mac OS X - possibly libtool, autoconf, automake. Not sure which made the difference, but these were the ones I updated. it won't jam successfully without this. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@559 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--Jamfile12
-rw-r--r--MacOsXContribBinariesVersion.txt2
-rw-r--r--contrib/Jamfile18
-rw-r--r--contrib/patch-libdca.patch809
-rw-r--r--contrib/version_libdca.txt1
-rw-r--r--libhb/Jamfile2
-rw-r--r--libhb/Makefile38
-rw-r--r--libhb/common.h55
-rw-r--r--libhb/deca52.c3
-rw-r--r--libhb/decdca.c215
-rw-r--r--libhb/dvd.c8
-rw-r--r--libhb/hb.c1
-rw-r--r--libhb/hb.h2
-rw-r--r--libhb/internal.h7
-rw-r--r--libhb/scan.c291
-rw-r--r--libhb/work.c131
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj22
-rw-r--r--test/test.c2
18 files changed, 1475 insertions, 144 deletions
diff --git a/Jamfile b/Jamfile
index b0a219958..4f3fb0471 100644
--- a/Jamfile
+++ b/Jamfile
@@ -10,12 +10,12 @@ SubDir TOP ;
HANDBRAKE_LIBS = libhb.a
contrib/lib/liba52.a contrib/lib/libavformat.a
contrib/lib/libavcodec.a contrib/lib/libavutil.a
- contrib/lib/libdvdread.a contrib/lib/libmp4v2.a
- contrib/lib/libfaac.a contrib/lib/libmp3lame.a
- contrib/lib/libmpeg2.a contrib/lib/libvorbis.a
- contrib/lib/libvorbisenc.a contrib/lib/libogg.a
- contrib/lib/libsamplerate.a contrib/lib/libx264.a
- contrib/lib/libxvidcore.a ;
+ contrib/lib/libdca.a contrib/lib/libdvdread.a
+ contrib/lib/libmp4v2.a contrib/lib/libfaac.a
+ contrib/lib/libmp3lame.a contrib/lib/libmpeg2.a
+ contrib/lib/libvorbis.a contrib/lib/libvorbisenc.a
+ contrib/lib/libogg.a contrib/lib/libsamplerate.a
+ contrib/lib/libx264.a contrib/lib/libxvidcore.a ;
if $(OS) = UNKNOWN
{
diff --git a/MacOsXContribBinariesVersion.txt b/MacOsXContribBinariesVersion.txt
index af68ed919..5d2bc74e7 100644
--- a/MacOsXContribBinariesVersion.txt
+++ b/MacOsXContribBinariesVersion.txt
@@ -1 +1 @@
-0011
+0012
diff --git a/contrib/Jamfile b/contrib/Jamfile
index 7254fc163..d7cb57151 100644
--- a/contrib/Jamfile
+++ b/contrib/Jamfile
@@ -107,6 +107,24 @@ if $(OS) != CYGWIN
LibDvdCss $(SUBDIR)/lib/libdvdcss.a : $(SUBDIR)/libdvdcss.tar.gz ;
}
+# libdca
+rule LibDCA
+{
+ Depends $(<) : $(>) ;
+ Depends lib : $(<) ;
+}
+actions LibDCA
+{
+ cd `dirname $(>)` && CONTRIB=`pwd` &&
+ rm -rf libdca && tar xzf libdca.tar.gz && cd libdca && patch -p1 < ../patch-libdca.patch
+ ./bootstrap && ./configure && make &&
+ cp libdca/.libs/libdca.a $CONTRIB/lib &&
+ cp include/dca.h $CONTRIB/include &&
+ strip -S $CONTRIB/lib/libdca.a
+}
+Wget $(SUBDIR)/libdca.tar.gz : $(SUBDIR)/version_libdca.txt ;
+LibDCA $(SUBDIR)/lib/libdca.a : $(SUBDIR)/libdca.tar.gz ;
+
# libdvdread
rule LibDvdRead
{
diff --git a/contrib/patch-libdca.patch b/contrib/patch-libdca.patch
new file mode 100644
index 000000000..92f2cfe2f
--- /dev/null
+++ b/contrib/patch-libdca.patch
@@ -0,0 +1,809 @@
+diff -Naur libdca/include/audio_out.h libdca_patched/include/audio_out.h
+--- libdca/include/audio_out.h 2007-05-02 10:05:03.000000000 +0100
++++ libdca_patched/include/audio_out.h 2007-05-02 10:09:42.000000000 +0100
+@@ -26,8 +26,8 @@
+
+ struct ao_instance_s {
+ int (* setup) (ao_instance_t * instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias);
+- int (* play) (ao_instance_t * instance, int flags, sample_t * samples);
++ dca_level_t * level, dca_sample_t * bias);
++ int (* play) (ao_instance_t * instance, int flags, dca_sample_t * samples);
+ void (* close) (ao_instance_t * instance);
+ };
+
+diff -Naur libdca/include/dca.h libdca_patched/include/dca.h
+--- libdca/include/dca.h 2007-05-02 10:05:03.000000000 +0100
++++ libdca_patched/include/dca.h 2007-05-02 10:09:36.000000000 +0100
+@@ -32,14 +32,14 @@
+ uint32_t mm_accel (void);
+
+ #if defined(LIBDCA_FIXED)
+-typedef int32_t sample_t;
+-typedef int32_t level_t;
++typedef int32_t dca_sample_t;
++typedef int32_t dca_level_t;
+ #elif defined(LIBDCA_DOUBLE)
+-typedef double sample_t;
+-typedef double level_t;
++typedef double dca_sample_t;
++typedef double dca_level_t;
+ #else
+-typedef float sample_t;
+-typedef float level_t;
++typedef float dca_sample_t;
++typedef float dca_level_t;
+ #endif
+
+ typedef struct dca_state_s dca_state_t;
+@@ -65,21 +65,24 @@
+ #define DCA_LFE 0x80
+ #define DCA_ADJUST_LEVEL 0x100
+
++#define DCA_OUT_DPLI 0x200
++#define DCA_OUT_DPLII 0x400
++
+ dca_state_t * dca_init (uint32_t mm_accel);
+
+ int dca_syncinfo (dca_state_t *state, uint8_t * buf, int * flags,
+ int * sample_rate, int * bit_rate, int *frame_length);
+
+ int dca_frame (dca_state_t * state, uint8_t * buf, int * flags,
+- level_t * level, sample_t bias);
++ dca_level_t * level, dca_sample_t bias);
+
+ void dca_dynrng (dca_state_t * state,
+- level_t (* call) (level_t, void *), void * data);
++ dca_level_t (* call) (dca_level_t, void *), void * data);
+
+ int dca_blocks_num (dca_state_t * state);
+ int dca_block (dca_state_t * state);
+
+-sample_t * dca_samples (dca_state_t * state);
++dca_sample_t * dca_samples (dca_state_t * state);
+
+ void dca_free (dca_state_t * state);
+
+diff -Naur libdca/libao/audio_out_aif.c libdca_patched/libao/audio_out_aif.c
+--- libdca/libao/audio_out_aif.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_aif.c 2007-05-02 10:09:41.000000000 +0100
+@@ -49,7 +49,7 @@
+ };
+
+ static int aif_setup (ao_instance_t * _instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ aif_instance_t * instance = (aif_instance_t *) _instance;
+
+@@ -78,7 +78,7 @@
+ buf[1] = value;
+ }
+
+-static int aif_play (ao_instance_t * _instance, int flags, sample_t * _samples)
++static int aif_play (ao_instance_t * _instance, int flags, dca_sample_t * _samples)
+ {
+ aif_instance_t * instance = (aif_instance_t *) _instance;
+ int16_t int16_samples[256*2];
+diff -Naur libdca/libao/audio_out_al.c libdca_patched/libao/audio_out_al.c
+--- libdca/libao/audio_out_al.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_al.c 2007-05-02 10:09:41.000000000 +0100
+@@ -44,7 +44,7 @@
+ } al_instance_t;
+
+ static int al_setup (ao_instance_t * _instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ al_instance_t * instance = (al_instance_t *) _instance;
+
+@@ -59,7 +59,7 @@
+ return 0;
+ }
+
+-static int al_play (ao_instance_t * _instance, int flags, sample_t * _samples)
++static int al_play (ao_instance_t * _instance, int flags, dca_sample_t * _samples)
+ {
+ al_instance_t * instance = (al_instance_t *) _instance;
+ int16_t int16_samples[256*6];
+diff -Naur libdca/libao/audio_out_float.c libdca_patched/libao/audio_out_float.c
+--- libdca/libao/audio_out_float.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_float.c 2007-05-02 10:09:40.000000000 +0100
+@@ -32,7 +32,7 @@
+ #include "audio_out_internal.h"
+
+ static int float_setup (ao_instance_t * instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ (void)instance;
+ (void)sample_rate;
+@@ -44,7 +44,7 @@
+ }
+
+ static int float_play (ao_instance_t * instance, int flags,
+- sample_t * _samples)
++ dca_sample_t * _samples)
+ {
+ #if defined(LIBDCA_FIXED)
+ float samples[256 * 2];
+diff -Naur libdca/libao/audio_out_internal.h libdca_patched/libao/audio_out_internal.h
+--- libdca/libao/audio_out_internal.h 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_internal.h 2007-05-02 10:09:40.000000000 +0100
+@@ -25,7 +25,7 @@
+ #ifdef LIBDCA_DOUBLE
+ typedef float convert_t;
+ #else
+-typedef sample_t convert_t;
++typedef dca_sample_t convert_t;
+ #endif
+
+ #ifdef LIBDCA_FIXED
+diff -Naur libdca/libao/audio_out_null.c libdca_patched/libao/audio_out_null.c
+--- libdca/libao/audio_out_null.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_null.c 2007-05-02 10:09:39.000000000 +0100
+@@ -36,7 +36,7 @@
+ } null_instance_t;
+
+ static int null_setup (ao_instance_t * _instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ null_instance_t * instance = (null_instance_t *) _instance;
+
+@@ -48,7 +48,7 @@
+ return 0;
+ }
+
+-static int null_play (ao_instance_t * instance, int flags, sample_t * samples)
++static int null_play (ao_instance_t * instance, int flags, dca_sample_t * samples)
+ {
+ (void)instance; (void)flags; (void)samples;
+ return 0;
+diff -Naur libdca/libao/audio_out_oss.c libdca_patched/libao/audio_out_oss.c
+--- libdca/libao/audio_out_oss.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_oss.c 2007-05-02 10:09:38.000000000 +0100
+@@ -68,7 +68,7 @@
+ } oss_instance_t;
+
+ static int oss_setup (ao_instance_t * _instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ oss_instance_t * instance = (oss_instance_t *) _instance;
+
+@@ -83,7 +83,7 @@
+ return 0;
+ }
+
+-static int oss_play (ao_instance_t * _instance, int flags, sample_t * _samples)
++static int oss_play (ao_instance_t * _instance, int flags, dca_sample_t * _samples)
+ {
+ oss_instance_t * instance = (oss_instance_t *) _instance;
+ int16_t int16_samples[256*6];
+diff -Naur libdca/libao/audio_out_peak.c libdca_patched/libao/audio_out_peak.c
+--- libdca/libao/audio_out_peak.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_peak.c 2007-05-02 10:09:38.000000000 +0100
+@@ -16,7 +16,7 @@
+ } peak_instance_t;
+
+ static int peak_setup (ao_instance_t * _instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ peak_instance_t * instance = (peak_instance_t *) _instance;
+
+@@ -29,7 +29,7 @@
+ return 0;
+ }
+
+-static int peak_play (ao_instance_t * _instance, int flags, sample_t * samples)
++static int peak_play (ao_instance_t * _instance, int flags, dca_sample_t * samples)
+ {
+ peak_instance_t * instance = (peak_instance_t *) _instance;
+ int i;
+diff -Naur libdca/libao/audio_out_solaris.c libdca_patched/libao/audio_out_solaris.c
+--- libdca/libao/audio_out_solaris.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_solaris.c 2007-05-02 10:09:37.000000000 +0100
+@@ -47,7 +47,7 @@
+ } solaris_instance_t;
+
+ static int solaris_setup (ao_instance_t * _instance, int sample_rate,
+- int * flags, level_t * level, sample_t * bias)
++ int * flags, dca_level_t * level, dca_sample_t * bias)
+ {
+ solaris_instance_t * instance = (solaris_instance_t *) _instance;
+
+@@ -63,7 +63,7 @@
+ }
+
+ static int solaris_play (ao_instance_t * _instance, int flags,
+- sample_t * _samples)
++ dca_sample_t * _samples)
+ {
+ solaris_instance_t * instance = (solaris_instance_t *) _instance;
+ int16_t int16_samples[256*2];
+diff -Naur libdca/libao/audio_out_wav.c libdca_patched/libao/audio_out_wav.c
+--- libdca/libao/audio_out_wav.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_wav.c 2007-05-02 10:09:37.000000000 +0100
+@@ -87,7 +87,7 @@
+ };
+
+ static int wav_setup (ao_instance_t * _instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ wav_instance_t * instance = (wav_instance_t *) _instance;
+
+@@ -157,7 +157,7 @@
+
+ #include <stdio.h>
+
+-static int wav_play (ao_instance_t * _instance, int flags, sample_t * _samples)
++static int wav_play (ao_instance_t * _instance, int flags, dca_sample_t * _samples)
+ {
+ wav_instance_t * instance = (wav_instance_t *) _instance;
+ union
+diff -Naur libdca/libao/audio_out_win.c libdca_patched/libao/audio_out_win.c
+--- libdca/libao/audio_out_win.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/libao/audio_out_win.c 2007-05-02 10:09:36.000000000 +0100
+@@ -55,7 +55,7 @@
+ } win_instance_t;
+
+ static int win_setup (ao_instance_t * _instance, int sample_rate, int * flags,
+- level_t * level, sample_t * bias)
++ dca_level_t * level, dca_sample_t * bias)
+ {
+ win_instance_t * instance = (win_instance_t *) _instance;
+
+@@ -70,7 +70,7 @@
+ return 0;
+ }
+
+-static int win_play (ao_instance_t * _instance, int flags, sample_t * _samples)
++static int win_play (ao_instance_t * _instance, int flags, dca_sample_t * _samples)
+ {
+ win_instance_t * instance = (win_instance_t *) _instance;
+ int current_buffer;
+diff -Naur libdca/libdca/dca_internal.h libdca_patched/libdca/dca_internal.h
+--- libdca/libdca/dca_internal.h 2007-05-02 10:05:05.000000000 +0100
++++ libdca_patched/libdca/dca_internal.h 2007-05-02 10:09:35.000000000 +0100
+@@ -116,20 +116,20 @@
+ double subband_fir_noidea[DCA_PRIM_CHANNELS_MAX][64];
+
+ /* Audio output */
+- level_t clev; /* centre channel mix level */
+- level_t slev; /* surround channels mix level */
++ dca_level_t clev; /* centre channel mix level */
++ dca_level_t slev; /* surround channels mix level */
+
+ int output; /* type of output */
+- level_t level; /* output level */
+- sample_t bias; /* output bias */
++ dca_level_t level; /* output level */
++ dca_sample_t bias; /* output bias */
+
+- sample_t * samples; /* pointer to the internal audio samples buffer */
++ dca_sample_t * samples; /* pointer to the internal audio samples buffer */
+ int downmixed;
+
+ int dynrnge; /* apply dynamic range */
+- level_t dynrng; /* dynamic range */
++ dca_level_t dynrng; /* dynamic range */
+ void * dynrngdata; /* dynamic range callback funtion and data */
+- level_t (* dynrngcall) (level_t range, void * dynrngdata);
++ dca_level_t (* dynrngcall) (dca_level_t range, void * dynrngdata);
+
+ /* Bitstream handling */
+ uint32_t * buffer_start;
+@@ -155,19 +155,23 @@
+ #define LEVEL_45DB 0.5946035575013605
+ #define LEVEL_6DB 0.5
+
+-int dca_downmix_init (int input, int flags, level_t * level,
+- level_t clev, level_t slev);
+-int dca_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
+- level_t clev, level_t slev);
+-void dca_downmix (sample_t * samples, int acmod, int output, sample_t bias,
+- level_t clev, level_t slev);
+-void dca_upmix (sample_t * samples, int acmod, int output);
++// these next two constants are used for DPL matrix encoding in downmix.c
++#define LEVEL_SQRT_1_2 0.5
++#define LEVEL_SQRT_3_4 0.8660254037844386
++
++int dca_downmix_init (int input, int flags, dca_level_t * level,
++ dca_level_t clev, dca_level_t slev);
++int dca_downmix_coeff (dca_level_t * coeff, int acmod, int output, dca_level_t level,
++ dca_level_t clev, dca_level_t slev);
++void dca_downmix (dca_sample_t * samples, int acmod, int output, dca_sample_t bias,
++ dca_level_t clev, dca_level_t slev);
++void dca_upmix (dca_sample_t * samples, int acmod, int output);
+
+ #define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5)))
+
+ #ifndef LIBDCA_FIXED
+
+-typedef sample_t quantizer_t;
++typedef dca_sample_t quantizer_t;
+ #define SAMPLE(x) (x)
+ #define LEVEL(x) (x)
+ #define MUL(a,b) ((a) * (b))
+@@ -179,8 +183,8 @@
+ #else /* LIBDCA_FIXED */
+
+ typedef int16_t quantizer_t;
+-#define SAMPLE(x) (sample_t)((x) * (1 << 30))
+-#define LEVEL(x) (level_t)((x) * (1 << 26))
++#define SAMPLE(x) (dca_sample_t)((x) * (1 << 30))
++#define LEVEL(x) (dca_level_t)((x) * (1 << 26))
+
+ #if 0
+ #define MUL(a,b) ((int)(((int64_t)(a) * (b) + (1 << 29)) >> 30))
+diff -Naur libdca/libdca/downmix.c libdca_patched/libdca/downmix.c
+--- libdca/libdca/downmix.c 2007-05-02 10:05:05.000000000 +0100
++++ libdca_patched/libdca/downmix.c 2007-05-02 10:09:34.000000000 +0100
+@@ -33,8 +33,8 @@
+
+ #define CONVERT(acmod,output) (((output) << DCA_CHANNEL_BITS) + (acmod))
+
+-int dca_downmix_init (int input, int flags, level_t * level,
+- level_t clev, level_t slev)
++int dca_downmix_init (int input, int flags, dca_level_t * level,
++ dca_level_t clev, dca_level_t slev)
+ {
+ static uint8_t table[11][10] = {
+ /* DCA_MONO */
+@@ -96,7 +96,7 @@
+ output = DCA_DOLBY;
+
+ if (flags & DCA_ADJUST_LEVEL) {
+- level_t adjust;
++ dca_level_t adjust;
+
+ switch (CONVERT (input & 7, output)) {
+
+@@ -181,13 +181,16 @@
+ *level = MUL_L (*level, adjust);
+ }
+
++ // add the DPLI/DPLII flag back into the output if one was passed in
++ output = output | (flags & DCA_OUT_DPLI) | (flags & DCA_OUT_DPLII);
++
+ return output;
+ }
+
+-int dca_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
+- level_t clev, level_t slev)
++int dca_downmix_coeff (dca_level_t * coeff, int acmod, int output, dca_level_t level,
++ dca_level_t clev, dca_level_t slev)
+ {
+- level_t level_3db;
++ dca_level_t level_3db;
+
+ level_3db = MUL_C (level, LEVEL_3DB);
+
+@@ -344,7 +347,7 @@
+ return -1; /* NOTREACHED */
+ }
+
+-static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias)
++static void mix2to1 (dca_sample_t * dest, dca_sample_t * src, dca_sample_t bias)
+ {
+ int i;
+
+@@ -352,7 +355,7 @@
+ dest[i] += BIAS (src[i]);
+ }
+
+-static void mix3to1 (sample_t * samples, sample_t bias)
++static void mix3to1 (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+
+@@ -360,7 +363,7 @@
+ samples[i] += BIAS (samples[i + 256] + samples[i + 512]);
+ }
+
+-static void mix4to1 (sample_t * samples, sample_t bias)
++static void mix4to1 (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+
+@@ -369,7 +372,7 @@
+ samples[i + 768]);
+ }
+
+-static void mix5to1 (sample_t * samples, sample_t bias)
++static void mix5to1 (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+
+@@ -378,10 +381,10 @@
+ samples[i + 768] + samples[i + 1024]);
+ }
+
+-static void mix3to2 (sample_t * samples, sample_t bias)
++static void mix3to2 (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+- sample_t common;
++ dca_sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i]);
+@@ -390,10 +393,10 @@
+ }
+ }
+
+-static void mix21to2 (sample_t * left, sample_t * right, sample_t bias)
++static void mix21to2 (dca_sample_t * left, dca_sample_t * right, dca_sample_t bias)
+ {
+ int i;
+- sample_t common;
++ dca_sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (right[i + 256]);
+@@ -402,10 +405,10 @@
+ }
+ }
+
+-static void mix21toS (sample_t * samples, sample_t bias)
++static void mix21toS (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+- sample_t surround;
++ dca_sample_t surround;
+
+ for (i = 0; i < 256; i++) {
+ surround = samples[i + 512];
+@@ -414,10 +417,10 @@
+ }
+ }
+
+-static void mix31to2 (sample_t * samples, sample_t bias)
++static void mix31to2 (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+- sample_t common;
++ dca_sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i] + samples[i + 768]);
+@@ -426,10 +429,10 @@
+ }
+ }
+
+-static void mix31toS (sample_t * samples, sample_t bias)
++static void mix31toS (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+- sample_t common, surround;
++ dca_sample_t common, surround;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i]);
+@@ -439,10 +442,10 @@
+ }
+ }
+
+-static void mix22toS (sample_t * samples, sample_t bias)
++static void mix22toS (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+- sample_t surround;
++ dca_sample_t surround;
+
+ for (i = 0; i < 256; i++) {
+ surround = samples[i + 512] + samples[i + 768];
+@@ -451,10 +454,10 @@
+ }
+ }
+
+-static void mix32to2 (sample_t * samples, sample_t bias)
++static void mix32to2 (dca_sample_t * samples, dca_sample_t bias)
+ {
+ int i;
+- sample_t common;
++ dca_sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i]);
+@@ -463,20 +466,48 @@
+ }
+ }
+
+-static void mix32toS (sample_t * samples, sample_t bias)
++static void mix32toS (dca_sample_t * samples, dca_sample_t bias, int use_dpl2)
+ {
+- int i;
+- sample_t common, surround;
+
+- for (i = 0; i < 256; i++) {
+- common = BIAS (samples[i]);
+- surround = samples[i + 768] + samples[i + 1024];
+- samples[i] = samples[i + 256] + common - surround;
+- samples[i + 256] = samples[i + 512] + common + surround;
+- }
+-}
++ if (use_dpl2 == 1) {
++
++ int i;
++ dca_sample_t cc, Lt, Rt, Ls, Rs, Lss, Rss;
++
++ for (i = 0; i < 256; i++) {
++
++ cc = samples[i + 256] * LEVEL_3DB;
++
++ Lt = samples[i] + cc;
++ Rt = samples[i + 512] + cc;
++
++ Ls = samples[i + 768];
++ Rs = samples[i + 1024];
++
++ Lss = (LEVEL_SQRT_3_4 * Ls) - (LEVEL_SQRT_1_2 * Rs);
++ Rss = -(LEVEL_SQRT_1_2 * Ls) + (LEVEL_SQRT_3_4 * Rs);
++
++ samples[i] = Lt + Lss;
++ samples[i + 256] = Rt + Rss;
++
++ }
++
++ } else {
++
++ int i;
++ dca_sample_t common, surround;
++
++ for (i = 0; i < 256; i++) {
++ common = samples[i + 256] + bias;
++ surround = samples[i + 768] + samples[i + 1024];
++ samples[i] += common - surround;
++ samples[i + 256] = samples[i + 512] + common + surround;
++ }
+
+-static void move2to1 (sample_t * src, sample_t * dest, sample_t bias)
++ }
++
++}
++static void move2to1 (dca_sample_t * src, dca_sample_t * dest, dca_sample_t bias)
+ {
+ int i;
+
+@@ -484,7 +515,7 @@
+ dest[i] = BIAS (src[i] + src[i + 256]);
+ }
+
+-static void zero (sample_t * samples)
++static void zero (dca_sample_t * samples)
+ {
+ int i;
+
+@@ -492,8 +523,8 @@
+ samples[i] = 0;
+ }
+
+-void dca_downmix (sample_t * samples, int acmod, int output, sample_t bias,
+- level_t clev, level_t slev)
++void dca_downmix (dca_sample_t * samples, int acmod, int output, dca_sample_t bias,
++ dca_level_t clev, dca_level_t slev)
+ {
+ (void)clev;
+
+@@ -529,7 +560,7 @@
+ break;
+
+ case CONVERT (DCA_MONO, DCA_DOLBY):
+- memcpy (samples + 256, samples, 256 * sizeof (sample_t));
++ memcpy (samples + 256, samples, 256 * sizeof (dca_sample_t));
+ break;
+
+ case CONVERT (DCA_3F, DCA_STEREO):
+@@ -576,7 +607,7 @@
+ break;
+
+ case CONVERT (DCA_3F2R, DCA_DOLBY):
+- mix32toS (samples, bias);
++ mix32toS (samples, bias, 0);
+ break;
+
+ case CONVERT (DCA_3F1R, DCA_3F):
+@@ -594,7 +625,7 @@
+
+ case CONVERT (DCA_3F1R, DCA_2F1R):
+ mix3to2 (samples, bias);
+- memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
++ memcpy (samples + 512, samples + 768, 256 * sizeof (dca_sample_t));
+ break;
+
+ case CONVERT (DCA_2F2R, DCA_2F1R):
+@@ -608,30 +639,52 @@
+
+ case CONVERT (DCA_3F2R, DCA_3F1R):
+ mix2to1 (samples + 768, samples + 1024, bias);
++ /* deal with the special-case 5.0 to 4.0 DPL mix */
++ if (output & DCA_OUT_DPLI)
++ {
++ mix31toS (samples, bias);
++ }
+ break;
+
+ case CONVERT (DCA_2F1R, DCA_2F2R):
+- memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
++ memcpy (samples + 768, samples + 512, 256 * sizeof (dca_sample_t));
+ break;
+
+ case CONVERT (DCA_3F1R, DCA_2F2R):
+ mix3to2 (samples, bias);
+- memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
++ memcpy (samples + 512, samples + 768, 256 * sizeof (dca_sample_t));
+ break;
+
+ case CONVERT (DCA_3F2R, DCA_2F2R):
+ mix3to2 (samples, bias);
+- memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
+- memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t));
++ memcpy (samples + 512, samples + 768, 256 * sizeof (dca_sample_t));
++ memcpy (samples + 768, samples + 1024, 256 * sizeof (dca_sample_t));
+ break;
+
+ case CONVERT (DCA_3F1R, DCA_3F2R):
+- memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
++ memcpy (samples + 1024, samples + 768, 256 * sizeof (dca_sample_t));
++ break;
++
++ /* deal with the special-case DPL mixes */
++
++ case CONVERT (DCA_3F1R, DCA_3F1R):
++ if (output & DCA_OUT_DPLI)
++ {
++ mix31toS (samples, bias);
++ }
+ break;
++
++ case CONVERT (DCA_3F2R, DCA_3F2R):
++ if (output & DCA_OUT_DPLII)
++ {
++ mix32toS (samples, bias, 1);
++ }
++ break;
++
+ }
+ }
+
+-void dca_upmix (sample_t * samples, int acmod, int output)
++void dca_upmix (dca_sample_t * samples, int acmod, int output)
+ {
+ switch (CONVERT (acmod, output & DCA_CHANNEL_MASK)) {
+
+@@ -657,7 +710,7 @@
+ case CONVERT (DCA_3F, DCA_STEREO):
+ case CONVERT (DCA_3F, DCA_DOLBY):
+ mix_3to2:
+- memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t));
++ memcpy (samples + 512, samples + 256, 256 * sizeof (dca_sample_t));
+ zero (samples + 256);
+ break;
+
+@@ -684,11 +737,11 @@
+ zero (samples + 1024);
+ case CONVERT (DCA_3F1R, DCA_2F1R):
+ mix_31to21:
+- memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
++ memcpy (samples + 768, samples + 512, 256 * sizeof (dca_sample_t));
+ goto mix_3to2;
+
+ case CONVERT (DCA_3F2R, DCA_2F2R):
+- memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
++ memcpy (samples + 1024, samples + 768, 256 * sizeof (dca_sample_t));
+ goto mix_31to21;
+ }
+ }
+diff -Naur libdca/libdca/parse.c libdca_patched/libdca/parse.c
+--- libdca/libdca/parse.c 2007-05-02 10:05:05.000000000 +0100
++++ libdca_patched/libdca/parse.c 2007-05-02 10:09:33.000000000 +0100
+@@ -59,12 +59,12 @@
+ static int decode_blockcode (int code, int levels, int *values);
+
+ static void qmf_32_subbands (dca_state_t * state, int chans,
+- double samples_in[32][8], sample_t *samples_out,
+- double rScale, sample_t bias);
++ double samples_in[32][8], dca_sample_t *samples_out,
++ double rScale, dca_sample_t bias);
+
+ static void lfe_interpolation_fir (int nDecimationSelect, int nNumDeciSample,
+- double *samples_in, sample_t *samples_out,
+- double rScale, sample_t bias );
++ double *samples_in, dca_sample_t *samples_out,
++ double rScale, dca_sample_t bias );
+
+ static void pre_calc_cosmod( dca_state_t * state );
+
+@@ -80,7 +80,7 @@
+
+ memset (state, 0, sizeof(dca_state_t));
+
+- state->samples = (sample_t *) memalign (16, 256 * 12 * sizeof (sample_t));
++ state->samples = (dca_sample_t *) memalign (16, 256 * 12 * sizeof (dca_sample_t));
+ if (state->samples == NULL) {
+ free (state);
+ return NULL;
+@@ -97,7 +97,7 @@
+ return state;
+ }
+
+-sample_t * dca_samples (dca_state_t * state)
++dca_sample_t * dca_samples (dca_state_t * state)
+ {
+ return state->samples;
+ }
+@@ -207,7 +207,7 @@
+ }
+
+ int dca_frame (dca_state_t * state, uint8_t * buf, int * flags,
+- level_t * level, sample_t bias)
++ dca_level_t * level, dca_sample_t bias)
+ {
+ int i, j;
+ static float adj_table[] = { 1.0, 1.1250, 1.2500, 1.4375 };
+@@ -996,7 +996,7 @@
+ {
+ dca_upmix (state->samples, state->amode, state->output);
+ } else
+- if (state->prim_channels > dca_channels[state->output & DCA_CHANNEL_MASK])
++ if (state->prim_channels >= dca_channels[state->output & DCA_CHANNEL_MASK])
+ {
+ dca_downmix (state->samples, state->amode, state->output, state->bias,
+ state->clev, state->slev);
+@@ -1142,8 +1142,8 @@
+ }
+
+ static void qmf_32_subbands (dca_state_t * state, int chans,
+- double samples_in[32][8], sample_t *samples_out,
+- double scale, sample_t bias)
++ double samples_in[32][8], dca_sample_t *samples_out,
++ double scale, dca_sample_t bias)
+ {
+ double *prCoeff;
+ int i, j, k;
+@@ -1224,8 +1224,8 @@
+ }
+
+ static void lfe_interpolation_fir (int nDecimationSelect, int nNumDeciSample,
+- double *samples_in, sample_t *samples_out,
+- double scale, sample_t bias)
++ double *samples_in, dca_sample_t *samples_out,
++ double scale, dca_sample_t bias)
+ {
+ /* samples_in: An array holding decimated samples.
+ * Samples in current subframe starts from samples_in[0],
+@@ -1275,7 +1275,7 @@
+ }
+
+ void dca_dynrng (dca_state_t * state,
+- level_t (* call) (level_t, void *), void * data)
++ dca_level_t (* call) (dca_level_t, void *), void * data)
+ {
+ state->dynrange = 0;
+ if (call) {
+diff -Naur libdca/src/dcadec.c libdca_patched/src/dcadec.c
+--- libdca/src/dcadec.c 2007-05-02 10:05:04.000000000 +0100
++++ libdca_patched/src/dcadec.c 2007-05-02 10:09:35.000000000 +0100
+@@ -280,15 +280,15 @@
+ }
+ bufpos = buf + length;
+ } else {
+- level_t level;
+- sample_t bias;
++ dca_level_t level;
++ dca_sample_t bias;
+ int i;
+
+ if (output->setup (output, sample_rate, &flags, &level, &bias))
+ goto error;
+ if (!disable_adjust)
+ flags |= DCA_ADJUST_LEVEL;
+- level = (level_t) (level * gain);
++ level = (dca_level_t) (level * gain);
+ if (dca_frame (state, buf, &flags, &level, bias))
+ goto error;
+ if (disable_dynrng)
diff --git a/contrib/version_libdca.txt b/contrib/version_libdca.txt
new file mode 100644
index 000000000..aaf0c058b
--- /dev/null
+++ b/contrib/version_libdca.txt
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/libdca-r81.tar.gz
diff --git a/libhb/Jamfile b/libhb/Jamfile
index afc775e48..7765d01c4 100644
--- a/libhb/Jamfile
+++ b/libhb/Jamfile
@@ -9,7 +9,7 @@ SubDir TOP libhb ;
LIBHB_SRC =
ipodutil.cpp common.c hb.c ports.c scan.c work.c decmpeg2.c encavcodec.c update.c
demuxmpeg.c fifo.c render.c reader.c muxcommon.c muxmp4.c sync.c
-decsub.c deca52.c encfaac.c declpcm.c encx264.c decavcodec.c encxvid.c
+decsub.c deca52.c decdca.c encfaac.c declpcm.c encx264.c decavcodec.c encxvid.c
muxavi.c enclame.c muxogm.c encvorbis.c dvd.c ;
Library libhb : $(LIBHB_SRC) ;
diff --git a/libhb/Makefile b/libhb/Makefile
index 902877561..6604ec428 100644
--- a/libhb/Makefile
+++ b/libhb/Makefile
@@ -22,33 +22,31 @@ ifeq ($(SYSTEM),Linux)
endif
SRCS = common.c hb.c ports.c scan.c work.c decmpeg2.c encavcodec.c \
- update.c demuxmpeg.c fifo.c render.c reader.c muxcommon.c \
- muxmp4.c sync.c decsub.c deca52.c encfaac.c declpcm.c encx264.c \
- decavcodec.c encxvid.c muxavi.c enclame.c muxogm.c encvorbis.c \
- dvd.c ipodutil.cpp
+ update.c demuxmpeg.c fifo.c render.c reader.c muxcommon.c \
+ muxmp4.c sync.c decsub.c deca52.c decdca.c encfaac.c declpcm.c encx264.c \
+ decavcodec.c encxvid.c muxavi.c enclame.c muxogm.c encvorbis.c \
+ dvd.c ipodutil.cpp
OTMP = $(SRCS:%.c=%.o)
OBJS = $(OTMP:%.cpp=%.o)
ifeq ($(SYSTEM),CYGWIN_NT-5.1)
CONTRIBS = ../contrib/lib/liba52.a ../contrib/lib/libavformat.a \
- ../contrib/lib/libavcodec.a ../contrib/lib/libavutil.a \
- ../contrib/lib/libdvdread.a \
- ../contrib/lib/libfaac.a ../contrib/lib/libmp3lame.a \
- ../contrib/lib/libmpeg2.a ../contrib/lib/libmpeg2convert.a \
- ../contrib/lib/libvorbis.a ../contrib/lib/libvorbisenc.a \
- ../contrib/lib/libvorbisfile.a ../contrib/lib/libogg.a \
- ../contrib/lib/libsamplerate.a ../contrib/lib/libx264.a \
- ../contrib/lib/libxvidcore.a ../contrib/lib/libmp4v2.a
+ ../contrib/lib/libavcodec.a ../contrib/lib/libavutil.a \
+ ../contrib/lib/libdca.a ../contrib/lib/libdvdread.a \
+ ../contrib/lib/libfaac.a ../contrib/lib/libmp3lame.a \
+ ../contrib/lib/libmpeg2.a ../contrib/lib/libmpeg2convert.a \
+ ../contrib/lib/libvorbis.a ../contrib/lib/libvorbisenc.a \
+ ../contrib/lib/libvorbisfile.a ../contrib/lib/libogg.a \
+ ../contrib/lib/libsamplerate.a ../contrib/lib/libx264.a \
+ ../contrib/lib/libxvidcore.a ../contrib/lib/libmp4v2.a
else
CONTRIBS = ../contrib/lib/liba52.a ../contrib/lib/libavformat.a \
- ../contrib/lib/libavcodec.a ../contrib/lib/libavutil.a \
- ../contrib/lib/libdvdread.a ../contrib/lib/libdvdcss.a \
- ../contrib/lib/libfaac.a ../contrib/lib/libmp3lame.a \
- ../contrib/lib/libmpeg2.a ../contrib/lib/libmpeg2convert.a \
- ../contrib/lib/libvorbis.a ../contrib/lib/libvorbisenc.a \
- ../contrib/lib/libvorbisfile.a ../contrib/lib/libogg.a \
- ../contrib/lib/libsamplerate.a ../contrib/lib/libx264.a \
- ../contrib/lib/libxvidcore.a ../contrib/lib/libmp4v2.a
+ ../contrib/lib/libavcodec.a ../contrib/lib/libavutil.a \
+ ../contrib/lib/libdca.a ../contrib/lib/libdvdread.a \
+ ../contrib/lib/libdvdcss.a ../contrib/lib/libfaac.a \
+ ../contrib/lib/libmp3lame.a ../contrib/lib/libmpeg2.a \ ../contrib/lib/libmpeg2convert.a ../contrib/lib/libvorbis.a \ ../contrib/lib/libvorbisenc.a ../contrib/lib/libvorbisfile.a \ ../contrib/lib/libogg.a ../contrib/lib/libsamplerate.a \
+ ../contrib/lib/libx264.a ../contrib/lib/libxvidcore.a \
+ ../contrib/lib/libmp4v2.a
endif
CFLAGS += -I../contrib/include -D__LIBHB__ -DUSE_PTHREAD -DHB_VERSION=\"$(HB_VERSION)\" -DHB_BUILD=$(HB_BUILD) $(SYSDEF)
diff --git a/libhb/common.h b/libhb/common.h
index 278e34f88..fd77999fc 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -169,24 +169,42 @@ struct hb_job_s
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_A52_FORMAT_MASK 0x00FF0000
-#define HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK 0x0000F000
-#define HB_AMIXDOWN_FRONT_CHANNEL_COUNT_MASK 0x00000F00
-#define HB_AMIXDOWN_REAR_CHANNEL_COUNT_MASK 0x000000F0
-#define HB_AMIXDOWN_LFE_CHANNEL_COUNT_MASK 0x0000000F
+#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 0x01011100 // A52_FORMAT of A52_MONO = 1 = 0x01
-#define HB_AMIXDOWN_STEREO 0x02022200 // A52_FORMAT of A52_STEREO = 2 = 0x02
-#define HB_AMIXDOWN_DOLBY 0x040A2310 // A52_FORMAT of A52_DOLBY = 10 = 0x0A
-#define HB_AMIXDOWN_DOLBYPLII 0x084A2320 // A52_FORMAT of A52_DOLBY | A52_USE_DPLII = 74 = 0x4A
-#define HB_AMIXDOWN_6CH 0x10176321 // A52_FORMAT of A52_3F2R | A52_LFE = 23 = 0x17
+
+#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_A52_FORMAT( a ) ( ( a & HB_AMIXDOWN_A52_FORMAT_MASK ) >> 16 )
-#define HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK ) >> 12 )
-#define HB_AMIXDOWN_GET_FRONT_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_FRONT_CHANNEL_COUNT_MASK ) >> 8 )
-#define HB_AMIXDOWN_GET_REAR_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_REAR_CHANNEL_COUNT_MASK ) >> 4 )
-#define HB_AMIXDOWN_GET_LFE_CHANNEL_COUNT( a ) ( ( a & HB_AMIXDOWN_LFE_CHANNEL_COUNT_MASK ) )
-#define HB_AMIXDOWN_GET_NORMAL_CHANNEL_COUNT( a ) ( (( a & HB_AMIXDOWN_FRONT_CHANNEL_COUNT_MASK ) >> 8) + (( a & HB_AMIXDOWN_REAR_CHANNEL_COUNT_MASK ) >> 4) )
+#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];
@@ -203,6 +221,7 @@ struct hb_job_s
#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;
@@ -273,6 +292,9 @@ struct hb_audio_s
/* ac3flags is only set when the source audio format is HB_ACODEC_AC3 */
int ac3flags;
+ /* dcaflags is only set when the source audio format is HB_ACODEC_DCA */
+ int dcaflags;
+
#ifdef __LIBHB__
/* Internal data */
hb_fifo_t * fifo_in; /* AC3/MPEG/LPCM ES */
@@ -448,6 +470,7 @@ extern hb_work_object_t hb_encavcodec;
extern hb_work_object_t hb_encxvid;
extern hb_work_object_t hb_encx264;
extern hb_work_object_t hb_deca52;
+extern hb_work_object_t hb_decdca;
extern hb_work_object_t hb_decavcodec;
extern hb_work_object_t hb_declpcm;
extern hb_work_object_t hb_encfaac;
diff --git a/libhb/deca52.c b/libhb/deca52.c
index 5b5f080bc..2a8c53c31 100644
--- a/libhb/deca52.c
+++ b/libhb/deca52.c
@@ -208,9 +208,10 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
{
for ( k = 0; k < pv->out_discrete_channels; k++ )
{
- samples_out[(pv->out_discrete_channels*j)+k] = samples_in[(256*k)+j]; // DJA
+ samples_out[(pv->out_discrete_channels*j)+k] = samples_in[(256*k)+j];
}
}
+
}
pv->sync = 0;
diff --git a/libhb/decdca.c b/libhb/decdca.c
new file mode 100644
index 000000000..669112f5b
--- /dev/null
+++ b/libhb/decdca.c
@@ -0,0 +1,215 @@
+/* $Id: decdca.c,v 1.14 2005/03/03 17:21:57 titer Exp $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.m0k.org/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include "hb.h"
+#include "dca.h"
+
+struct hb_work_private_s
+{
+ hb_job_t * job;
+
+ /* libdca handle */
+ dca_state_t * state;
+
+ int flags_in;
+ int flags_out;
+ int rate;
+ int bitrate;
+ int frame_length;
+ float level;
+
+ int error;
+ int sync;
+ int size;
+
+ /* max frame size of the 16 bits version is 16384 */
+ /* max frame size of the 14 bits version is 18726 */
+ uint8_t frame[18726];
+
+ hb_list_t * list;
+
+ int out_discrete_channels;
+
+};
+
+int decdcaInit( hb_work_object_t *, hb_job_t * );
+int decdcaWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void decdcaClose( hb_work_object_t * );
+
+hb_work_object_t hb_decdca =
+{
+ WORK_DECDCA,
+ "DCA decoder",
+ decdcaInit,
+ decdcaWork,
+ decdcaClose
+};
+
+/***********************************************************************
+ * Local prototypes
+ **********************************************************************/
+static hb_buffer_t * Decode( hb_work_object_t * w );
+
+/***********************************************************************
+ * hb_work_decdca_init
+ ***********************************************************************
+ * Allocate the work object, initialize libdca
+ **********************************************************************/
+int decdcaInit( hb_work_object_t * w, hb_job_t * job )
+{
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
+
+ pv->job = job;
+
+ pv->list = hb_list_init();
+ pv->state = dca_init( 0 );
+
+ /* 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);
+
+ /* 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->level = 32768.0;
+
+ return 0;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ * Free memory
+ **********************************************************************/
+void decdcaClose( hb_work_object_t * w )
+{
+ hb_work_private_t * pv = w->private_data;
+ dca_free( pv->state );
+ hb_list_empty( &pv->list );
+ free( pv );
+ w->private_data = NULL;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ * Add the given buffer to the data we already have, and decode as much
+ * as we can
+ **********************************************************************/
+int decdcaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
+{
+ hb_work_private_t * pv = w->private_data;
+ hb_buffer_t * buf;
+
+ hb_list_add( pv->list, *buf_in );
+ *buf_in = NULL;
+
+ /* If we got more than a frame, chain raw buffers */
+ *buf_out = buf = Decode( w );
+ while( buf )
+ {
+ buf->next = Decode( w );
+ buf = buf->next;
+ }
+
+ return HB_WORK_OK;
+}
+
+/***********************************************************************
+ * Decode
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_buffer_t * Decode( hb_work_object_t * w )
+{
+ hb_work_private_t * pv = w->private_data;
+ hb_buffer_t * buf;
+ int i, j, k;
+ uint64_t pts, pos;
+ int num_blocks;
+
+ /* Get a frame header if don't have one yet */
+ if( !pv->sync )
+ {
+ while( hb_list_bytes( pv->list ) >= 14 )
+ {
+ /* We have 14 bytes, check if this is a correct header */
+ hb_list_seebytes( pv->list, pv->frame, 14 );
+ pv->size = dca_syncinfo( pv->state, pv->frame, &pv->flags_in, &pv->rate,
+ &pv->bitrate, &pv->frame_length );
+ if( pv->size )
+ {
+ /* It is. W00t. */
+ if( pv->error )
+ {
+ hb_log( "dca_syncinfo ok" );
+ }
+ pv->error = 0;
+ pv->sync = 1;
+ break;
+ }
+
+ /* It is not */
+ if( !pv->error )
+ {
+ hb_log( "dca_syncinfo failed" );
+ pv->error = 1;
+ }
+
+ /* Try one byte later */
+ hb_list_getbytes( pv->list, pv->frame, 1, NULL, NULL );
+ }
+ }
+
+ if( !pv->sync ||
+ hb_list_bytes( pv->list ) < pv->size )
+ {
+ /* Need more data */
+ return NULL;
+ }
+
+ /* Get the whole frame */
+ hb_list_getbytes( pv->list, pv->frame, pv->size, &pts, &pos );
+
+ /* Feed libdca */
+ dca_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 );
+
+ /* find out how many blocks are in this frame */
+ num_blocks = dca_blocks_num( pv->state );
+
+ /* num_blocks blocks per frame, 256 samples per block, channelsused channels */
+ buf = hb_buffer_init( num_blocks * 256 * pv->out_discrete_channels * sizeof( float ) );
+ buf->start = pts + ( pos / pv->size ) * num_blocks * 256 * 90000 / pv->rate;
+ buf->stop = buf->start + num_blocks * 256 * 90000 / pv->rate;
+
+ for( i = 0; i < num_blocks; i++ )
+ {
+ dca_sample_t * samples_in;
+ float * samples_out;
+
+ dca_block( pv->state );
+ samples_in = dca_samples( pv->state );
+ samples_out = ((float *) buf->data) + 256 * pv->out_discrete_channels * i;
+
+ /* Interleave */
+ for( j = 0; j < 256; j++ )
+ {
+ for ( k = 0; k < pv->out_discrete_channels; k++ )
+ {
+ samples_out[(pv->out_discrete_channels*j)+k] = samples_in[(256*k)+j] * 16384;
+ }
+ }
+
+ }
+
+ pv->sync = 0;
+ return buf;
+}
+
diff --git a/libhb/dvd.c b/libhb/dvd.c
index b26c55995..5ec4d519b 100644
--- a/libhb/dvd.c
+++ b/libhb/dvd.c
@@ -252,6 +252,11 @@ hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
audio->codec = HB_ACODEC_LPCM;
break;
+ case 0x06:
+ audio->id = ( ( 0x88 + position ) << 8 ) | 0xbd;
+ audio->codec = HB_ACODEC_DCA;
+ break;
+
default:
audio->id = 0;
audio->codec = 0;
@@ -287,7 +292,8 @@ hb_title_t * hb_dvd_title_scan( hb_dvd_t * d, int t )
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" : "LPCM" ) );
+ HB_ACODEC_DCA ? "DTS" : ( audio->codec ==
+ HB_ACODEC_MPGA ? "MPEG" : "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",
diff --git a/libhb/hb.c b/libhb/hb.c
index e9d7aa129..4aa89fb05 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -204,6 +204,7 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
hb_register( &hb_encxvid );
hb_register( &hb_encx264 );
hb_register( &hb_deca52 );
+ hb_register( &hb_decdca );
hb_register( &hb_decavcodec );
hb_register( &hb_declpcm );
hb_register( &hb_encfaac );
diff --git a/libhb/hb.h b/libhb/hb.h
index 8b5d4696a..af9163718 100644
--- a/libhb/hb.h
+++ b/libhb/hb.h
@@ -26,6 +26,7 @@ hb_register( &hb_encavcodec ); \
hb_register( &hb_encxvid ); \
hb_register( &hb_encx264 ); \
hb_register( &hb_deca52 ); \
+hb_register( &hb_decdca ); \
hb_register( &hb_decavcodec ); \
hb_register( &hb_declpcm ); \
hb_register( &hb_encfaac ); \
@@ -41,6 +42,7 @@ hb_register( &hb_render ); \
hb_register( &hb_encavcodec ); \
hb_register( &hb_encx264 ); \
hb_register( &hb_deca52 ); \
+hb_register( &hb_decdca ); \
hb_register( &hb_decavcodec ); \
hb_register( &hb_declpcm ); \
hb_register( &hb_encfaac ); \
diff --git a/libhb/internal.h b/libhb/internal.h
index f950205d5..0f0262e7c 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -154,6 +154,12 @@ union hb_esconfig_u
int ac3flags;
} a52;
+ struct
+ {
+ /* dcaflags stores the flags from the DCA source, as found in scan.c */
+ int dcaflags;
+ } dca;
+
};
enum
@@ -166,6 +172,7 @@ enum
WORK_ENCXVID,
WORK_ENCX264,
WORK_DECA52,
+ WORK_DECDCA,
WORK_DECAVCODEC,
WORK_DECLPCM,
WORK_ENCFAAC,
diff --git a/libhb/scan.c b/libhb/scan.c
index 763bc3a1c..9d229b6cf 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -6,6 +6,7 @@
#include "hb.h"
#include "a52dec/a52.h"
+#include "dca.h"
typedef struct
{
@@ -21,8 +22,8 @@ typedef struct
static void ScanFunc( void * );
static int DecodePreviews( hb_scan_t *, hb_title_t * title );
-static void LookForAC3( hb_title_t * title, hb_buffer_t * b );
-static int AllAC3OK( hb_title_t * title );
+static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b );
+static int AllAC3AndDCAOK( hb_title_t * title );
hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
int title_index, hb_list_t * list_title )
@@ -127,6 +128,7 @@ static void ScanFunc( void * _data )
#undef p
/* Decode previews */
+ /* this will also detect more AC3 / DTS information */
if( !DecodePreviews( data, title ) )
{
/* TODO: free things */
@@ -134,13 +136,15 @@ static void ScanFunc( void * _data )
continue;
}
- /* Make sure we found AC3 rates and bitrates */
+ /* Make sure we found AC3 / DCA rates and bitrates */
for( j = 0; j < hb_list_count( title->list_audio ); )
{
audio = hb_list_item( title->list_audio, j );
- if( audio->codec == HB_ACODEC_AC3 &&
+ if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
!audio->bitrate )
{
+ hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
+ audio->codec );
hb_list_rem( title->list_audio, audio );
free( audio );
continue;
@@ -284,12 +288,12 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
}
else if( !i )
{
- LookForAC3( title, buf_es );
+ LookForAC3AndDCA( title, buf_es );
}
hb_buffer_close( &buf_es );
if( hb_list_count( list_raw ) &&
- ( i || AllAC3OK( title ) ) )
+ ( i || AllAC3AndDCAOK( title ) ) )
{
/* We got a picture */
break;
@@ -297,7 +301,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
}
if( hb_list_count( list_raw ) &&
- ( i || AllAC3OK( title ) ) )
+ ( i || AllAC3AndDCAOK( title ) ) )
{
break;
}
@@ -423,19 +427,21 @@ cleanup:
return ret;
}
-static void LookForAC3( hb_title_t * title, hb_buffer_t * b )
+static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
{
int i;
int flags;
int rate;
int bitrate;
+ int frame_length;
+ dca_state_t * state;
- /* Figure out if this is a AC3 buffer for a known track */
+ /* Figure out if this is a AC3 or DCA buffer for a known track */
hb_audio_t * audio = NULL;
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 &&
+ if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
audio->id == b->id )
{
break;
@@ -458,95 +464,202 @@ static void LookForAC3( hb_title_t * title, hb_buffer_t * b )
for( i = 0; i < b->size - 7; i++ )
{
- if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
+
+ if ( audio->codec == HB_ACODEC_AC3 )
{
- hb_log( "scan: rate=%dHz, bitrate=%d", rate, bitrate );
- audio->rate = rate;
- audio->bitrate = bitrate;
- switch( flags & A52_CHANNEL_MASK )
+
+ /* check for a52 */
+ if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
{
- case A52_MONO:
- case A52_CHANNEL1:
- case A52_CHANNEL2:
- audio->src_discrete_front_channels = 1;
- audio->src_discrete_rear_channels = 0;
- audio->src_encoded_front_channels = 1;
- audio->src_encoded_rear_channels = 0;
- break;
- case A52_STEREO:
- case A52_CHANNEL:
- audio->src_discrete_front_channels = 2;
- audio->src_discrete_rear_channels = 0;
- audio->src_encoded_front_channels = 2;
- audio->src_encoded_rear_channels = 0;
- break;
- case A52_DOLBY:
- audio->src_discrete_front_channels = 2;
- audio->src_discrete_rear_channels = 0;
- audio->src_encoded_front_channels = 3;
- audio->src_encoded_rear_channels = 1;
- break;
- case A52_3F:
- audio->src_discrete_front_channels = 3;
- audio->src_discrete_rear_channels = 0;
- audio->src_encoded_front_channels = 3;
- audio->src_encoded_rear_channels = 0;
- break;
- case A52_2F1R:
- audio->src_discrete_front_channels = 2;
- audio->src_discrete_rear_channels = 1;
- audio->src_encoded_front_channels = 2;
- audio->src_encoded_rear_channels = 1;
- break;
- case A52_3F1R:
- audio->src_discrete_front_channels = 3;
- audio->src_discrete_rear_channels = 1;
- audio->src_encoded_front_channels = 3;
- audio->src_encoded_rear_channels = 1;
- break;
- case A52_2F2R:
- audio->src_discrete_front_channels = 2;
- audio->src_discrete_rear_channels = 2;
- audio->src_encoded_front_channels = 2;
- audio->src_encoded_rear_channels = 2;
- break;
- case A52_3F2R:
- audio->src_discrete_front_channels = 3;
- audio->src_discrete_rear_channels = 2;
- audio->src_encoded_front_channels = 3;
- audio->src_encoded_rear_channels = 2;
- break;
+ hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
+ audio->rate = rate;
+ audio->bitrate = bitrate;
+ switch( flags & A52_CHANNEL_MASK )
+ {
+ case A52_MONO:
+ case A52_CHANNEL1:
+ case A52_CHANNEL2:
+ audio->src_discrete_front_channels = 1;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 1;
+ audio->src_encoded_rear_channels = 0;
+ break;
+ case A52_STEREO:
+ case A52_CHANNEL:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 2;
+ audio->src_encoded_rear_channels = 0;
+ break;
+ case A52_DOLBY:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 1;
+ break;
+ case A52_3F:
+ audio->src_discrete_front_channels = 3;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 0;
+ break;
+ case A52_2F1R:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 1;
+ audio->src_encoded_front_channels = 2;
+ audio->src_encoded_rear_channels = 1;
+ break;
+ case A52_3F1R:
+ audio->src_discrete_front_channels = 3;
+ audio->src_discrete_rear_channels = 1;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 1;
+ break;
+ case A52_2F2R:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 2;
+ audio->src_encoded_front_channels = 2;
+ audio->src_encoded_rear_channels = 2;
+ break;
+ case A52_3F2R:
+ audio->src_discrete_front_channels = 3;
+ audio->src_discrete_rear_channels = 2;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 2;
+ break;
+ }
+
+ if (flags & A52_LFE) {
+ audio->src_discrete_lfe_channels = 1;
+ } else {
+ audio->src_discrete_lfe_channels = 0;
+ }
+
+ /* 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;
+
+ /* XXX */
+ if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
+ sprintf( audio->lang + strlen( audio->lang ),
+ " (Dolby Surround)" );
+ } else {
+ sprintf( audio->lang + strlen( audio->lang ),
+ " (%d.%d ch)",
+ audio->src_discrete_front_channels + audio->src_discrete_rear_channels, audio->src_discrete_lfe_channels );
+ }
+
+ break;
+
}
- if (flags & A52_LFE) {
- audio->src_discrete_lfe_channels = 1;
- } else {
- audio->src_discrete_lfe_channels = 0;
- }
-
- /* 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;
+ }
+ else if ( audio->codec == HB_ACODEC_DCA )
+ {
- /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
- audio->ac3flags = audio->config.a52.ac3flags;
+ hb_log( "scan: checking for DCA syncinfo" );
- /* XXX */
- if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
- sprintf( audio->lang + strlen( audio->lang ),
- " (Dolby Surround)" );
- } else {
- sprintf( audio->lang + strlen( audio->lang ),
- " (%d.%d ch)",
- audio->src_discrete_front_channels + audio->src_discrete_rear_channels, audio->src_discrete_lfe_channels );
- }
+ /* check for dca */
+ state = dca_init( 0 );
+ 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;
+ switch( flags & DCA_CHANNEL_MASK )
+ {
+ case DCA_MONO:
+ audio->src_discrete_front_channels = 1;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 1;
+ audio->src_encoded_rear_channels = 0;
+ break;
+ case DCA_CHANNEL:
+ case DCA_STEREO:
+ case DCA_STEREO_SUMDIFF:
+ case DCA_STEREO_TOTAL:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 2;
+ audio->src_encoded_rear_channels = 0;
+ break;
+ case DCA_DOLBY:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 1;
+ break;
+ case DCA_3F:
+ audio->src_discrete_front_channels = 3;
+ audio->src_discrete_rear_channels = 0;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 0;
+ break;
+ case DCA_2F1R:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 1;
+ audio->src_encoded_front_channels = 2;
+ audio->src_encoded_rear_channels = 1;
+ break;
+ case DCA_3F1R:
+ audio->src_discrete_front_channels = 3;
+ audio->src_discrete_rear_channels = 1;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 1;
+ break;
+ case DCA_2F2R:
+ audio->src_discrete_front_channels = 2;
+ audio->src_discrete_rear_channels = 2;
+ audio->src_encoded_front_channels = 2;
+ audio->src_encoded_rear_channels = 2;
+ break;
+ case DCA_3F2R:
+ audio->src_discrete_front_channels = 3;
+ audio->src_discrete_rear_channels = 2;
+ audio->src_encoded_front_channels = 3;
+ audio->src_encoded_rear_channels = 2;
+ break;
+ case DCA_4F2R:
+ audio->src_discrete_front_channels = 4;
+ audio->src_discrete_rear_channels = 2;
+ audio->src_encoded_front_channels = 4;
+ audio->src_encoded_rear_channels = 2;
+ break;
+ }
- break;
+ if (flags & DCA_LFE) {
+ audio->src_discrete_lfe_channels = 1;
+ } else {
+ audio->src_discrete_lfe_channels = 0;
+ }
+
+ /* 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;
+
+ /* XXX */
+ if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
+ sprintf( audio->lang + strlen( audio->lang ),
+ " (Dolby Surround)" );
+ } else {
+ sprintf( audio->lang + strlen( audio->lang ),
+ " (%d.%d ch)",
+ audio->src_discrete_front_channels + audio->src_discrete_rear_channels, audio->src_discrete_lfe_channels );
+ }
+
+ break;
+ }
}
}
}
-static int AllAC3OK( hb_title_t * title )
+static int AllAC3AndDCAOK( hb_title_t * title )
{
int i;
hb_audio_t * audio;
@@ -554,7 +667,7 @@ static int AllAC3OK( 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 &&
+ if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
!audio->bitrate )
{
return 0;
diff --git a/libhb/work.c b/libhb/work.c
index 3e5ec4a78..8f3c1d03c 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -6,6 +6,7 @@
#include "hb.h"
#include "a52dec/a52.h"
+#include "dca.h"
typedef struct
{
@@ -230,13 +231,8 @@ static void do_job( hb_job_t * job, int cpu_count )
}
}
- if(audio->codec != HB_ACODEC_AC3) {
-
- /* assume a stereo input and output for non-AC3 audio input (LPCM, MP2),
- regardless of the mixdown passed to us */
- job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
-
- } else {
+ if (audio->codec == HB_ACODEC_AC3)
+ {
/* sense-check the AC3 mixdown */
@@ -339,7 +335,122 @@ static void do_job( hb_job_t * job, int cpu_count )
job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
}
- }
+ }
+
+ }
+ else if (audio->codec == HB_ACODEC_DCA)
+ {
+
+ /* sense-check the DCA mixdown */
+
+ /* audioCodecSupportsMono and audioCodecSupports6Ch are the same for now,
+ but this may change in the future, so they are separated for flexibility */
+ int audioCodecSupportsMono = (job->acodec == HB_ACODEC_FAAC);
+ int audioCodecSupports6Ch = (job->acodec == HB_ACODEC_FAAC);
+
+ /* find out what the format of our source DCA audio is */
+ switch (audio->config.dca.dcaflags & DCA_CHANNEL_MASK) {
+
+ /* mono sources */
+ case DCA_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 && audioCodecSupportsMono == 1) {
+ job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;
+ } else {
+ job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+ }
+ break;
+
+ /* stereo input */
+ case DCA_CHANNEL:
+ case DCA_STEREO:
+ case DCA_STEREO_SUMDIFF:
+ case DCA_STEREO_TOTAL:
+ /* 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 && audioCodecSupportsMono == 0) {
+ job->audio_mixdowns[i] = 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;
+ }
+ break;
+
+ /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
+ /* the A52 flags don't allow for a way to distinguish between DPL1 and DPL2 on a DVD,
+ so we always assume a DPL1 source for A52_DOLBY */
+ case DCA_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 && audioCodecSupportsMono == 0) {
+ job->audio_mixdowns[i] = 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;
+ }
+ break;
+
+ /* 3F/2R input */
+ case DCA_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 && audioCodecSupportsMono == 0) {
+ job->audio_mixdowns[i] = 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->config.dca.dcaflags & DCA_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 && audioCodecSupports6Ch == 0) {
+ job->audio_mixdowns[i] = 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;
+ }
+ }
+ }
+ /* all other mixdowns will have been preserved here */
+ break;
+
+ /* 3F/1R input */
+ case DCA_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 && audioCodecSupportsMono == 0) {
+ job->audio_mixdowns[i] = 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;
+ }
+ }
+ /* all other mixdowns will have been preserved here */
+ break;
+
+ default:
+ /* if we've requested a mono mixdown, and it is supported, then do the mix */
+ if (job->audio_mixdowns[i] == HB_AMIXDOWN_MONO && audioCodecSupportsMono == 1) {
+ job->audio_mixdowns[i] = HB_AMIXDOWN_MONO;
+ /* mix everything else down to stereo */
+ } else {
+ job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+ }
+ }
+
+ }
+ else
+ {
+
+ /* assume a stereo input and output for non-AC3/DCA audio input (LPCM, MP2),
+ regardless of the mixdown passed to us */
+ job->audio_mixdowns[i] = HB_AMIXDOWN_STEREO;
+
}
/* log the output mixdown */
@@ -367,6 +478,9 @@ static void do_job( hb_job_t * job, int cpu_count )
case HB_ACODEC_AC3:
w = getWork( WORK_DECA52 );
break;
+ case HB_ACODEC_DCA:
+ w = getWork( WORK_DECDCA );
+ break;
case HB_ACODEC_MPGA:
w = getWork( WORK_DECAVCODEC );
break;
@@ -466,6 +580,7 @@ static void do_job( hb_job_t * job, int cpu_count )
/* FIXME: This feels really hackish, anything better? */
if ( w->id == WORK_DECA52 ||
+ w->id == WORK_DECDCA ||
w->id == WORK_DECLPCM ||
w->id == WORK_ENCFAAC ||
w->id == WORK_ENCLAME ||
diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj
index 4e3f229c9..43f2ccb53 100644
--- a/macosx/HandBrake.xcodeproj/project.pbxproj
+++ b/macosx/HandBrake.xcodeproj/project.pbxproj
@@ -100,6 +100,8 @@
4DD93FA4082036E8008E1322 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DDE9724052B7B2B00C39CA9 /* OpenGL.framework */; };
52AFF86A0B59BD07000DA7C4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
52AFF86B0B59BD14000DA7C4 /* Express.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4D1EA2DC0993B01000FDC1A2 /* Express.plist */; };
+ 5558B5690BE3BADF00E15E27 /* decdca.c in Sources */ = {isa = PBXBuildFile; fileRef = 5558B5680BE3BADF00E15E27 /* decdca.c */; };
+ 5558B56A0BE3BADF00E15E27 /* decdca.c in Sources */ = {isa = PBXBuildFile; fileRef = 5558B5680BE3BADF00E15E27 /* decdca.c */; };
593034EB0BBA39A100172349 /* ChapterTitles.h in Headers */ = {isa = PBXBuildFile; fileRef = 593034E90BBA39A100172349 /* ChapterTitles.h */; };
593034EC0BBA39A100172349 /* ChapterTitles.m in Sources */ = {isa = PBXBuildFile; fileRef = 593034EA0BBA39A100172349 /* ChapterTitles.m */; };
59CBD2370BBB44DA004A3BE3 /* parsecsv.c in Sources */ = {isa = PBXBuildFile; fileRef = 59CBD2360BBB44DA004A3BE3 /* parsecsv.c */; };
@@ -212,6 +214,7 @@
526FBC9B0B4CAB100064E04C /* common.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = common.c; path = ../libhb/common.c; sourceTree = SOURCE_ROOT; };
526FBC9D0B4CAB100064E04C /* deca52.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = deca52.c; path = ../libhb/deca52.c; sourceTree = SOURCE_ROOT; };
526FBC9E0B4CAB100064E04C /* decavcodec.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = decavcodec.c; path = ../libhb/decavcodec.c; sourceTree = SOURCE_ROOT; };
+ 5558B5680BE3BADF00E15E27 /* decdca.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = decdca.c; path = ../libhb/decdca.c; sourceTree = SOURCE_ROOT; };
593034E90BBA39A100172349 /* ChapterTitles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChapterTitles.h; sourceTree = "<group>"; };
593034EA0BBA39A100172349 /* ChapterTitles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChapterTitles.m; sourceTree = "<group>"; };
59CBD2360BBB44DA004A3BE3 /* parsecsv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = parsecsv.c; path = ../test/parsecsv.c; sourceTree = SOURCE_ROOT; };
@@ -356,6 +359,7 @@
0DFA5C9C0B8DD3B60020BC09 /* work.c */,
526FBC9B0B4CAB100064E04C /* common.c */,
526FBC9D0B4CAB100064E04C /* deca52.c */,
+ 5558B5680BE3BADF00E15E27 /* decdca.c */,
526FBC9E0B4CAB100064E04C /* decavcodec.c */,
);
name = "libhb Sources";
@@ -608,6 +612,7 @@
0D096E010B707D3400A845D4 /* common.c in Sources */,
0D096E020B707D3400A845D4 /* deca52.c in Sources */,
0D096E030B707D3400A845D4 /* decavcodec.c in Sources */,
+ 5558B56A0BE3BADF00E15E27 /* decdca.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -644,6 +649,7 @@
0DFF0B790B6BC72A00549488 /* deca52.c in Sources */,
0DFF0B7A0B6BC72A00549488 /* decavcodec.c in Sources */,
593034EC0BBA39A100172349 /* ChapterTitles.m in Sources */,
+ 5558B5690BE3BADF00E15E27 /* decdca.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -768,6 +774,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
"-ldl",
"-flat_namespace",
"-read_only_relocs",
@@ -824,6 +831,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
"-ldl",
"-flat_namespace",
"-read_only_relocs",
@@ -878,6 +886,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
"-ldl",
"-flat_namespace",
"-read_only_relocs",
@@ -932,6 +941,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
"-ldl",
"-flat_namespace",
"-read_only_relocs",
@@ -1010,6 +1020,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PRODUCT_NAME = HandBrake;
SECTORDER_FLAGS = "";
@@ -1057,6 +1068,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = "Instant HandBrake";
@@ -1096,6 +1108,7 @@
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
"-lz",
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = HandBrakeCLI;
@@ -1236,6 +1249,7 @@
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
"-lz",
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = HandBrakeCLI;
@@ -1276,6 +1290,7 @@
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
"-lz",
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = HandBrakeCLI;
@@ -1314,6 +1329,7 @@
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
"-lz",
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = HandBrakeCLI;
@@ -1359,6 +1375,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = "Instant HandBrake";
@@ -1404,6 +1421,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = "Instant HandBrake";
@@ -1447,6 +1465,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PREBINDING = NO;
PRODUCT_NAME = "Instant HandBrake";
@@ -1497,6 +1516,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PRODUCT_NAME = HandBrake;
SECTORDER_FLAGS = "";
@@ -1549,6 +1569,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PRODUCT_NAME = HandBrake;
SECTORDER_FLAGS = "";
@@ -1599,6 +1620,7 @@
../contrib/lib/libsamplerate.a,
../contrib/lib/libx264.a,
../contrib/lib/libxvidcore.a,
+ ../contrib/lib/libdca.a,
);
PRODUCT_NAME = HandBrake;
SECTORDER_FLAGS = "";
diff --git a/test/test.c b/test/test.c
index 967cd9c11..3ed30e4af 100644
--- a/test/test.c
+++ b/test/test.c
@@ -231,7 +231,7 @@ static void PrintTitleInfo( 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 )
+ if( ( audio->codec & HB_ACODEC_AC3 ) || ( audio->codec & HB_ACODEC_DCA) )
{
fprintf( stderr, " + %d, %s, %dHz, %dbps\n", i + 1,
audio->lang, audio->rate, audio->bitrate );