OSDN Git Service

Added support for DTS audio. DTS audio streams (of 5.1 audio and below) will be...
authormaurj <maurj@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 2 May 2007 15:56:39 +0000 (15:56 +0000)
committermaurj <maurj@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 2 May 2007 15:56:39 +0000 (15:56 +0000)
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://localhost/HandBrake/trunk@559 b64f7644-9d1e-0410-96f1-a4d463321fa5

18 files changed:
Jamfile
MacOsXContribBinariesVersion.txt
contrib/Jamfile
contrib/patch-libdca.patch [new file with mode: 0644]
contrib/version_libdca.txt [new file with mode: 0644]
libhb/Jamfile
libhb/Makefile
libhb/common.h
libhb/deca52.c
libhb/decdca.c [new file with mode: 0644]
libhb/dvd.c
libhb/hb.c
libhb/hb.h
libhb/internal.h
libhb/scan.c
libhb/work.c
macosx/HandBrake.xcodeproj/project.pbxproj
test/test.c

diff --git a/Jamfile b/Jamfile
index b0a2199..4f3fb04 100644 (file)
--- 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
 {
index 7254fc1..d7cb571 100644 (file)
@@ -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 (file)
index 0000000..92f2cfe
--- /dev/null
@@ -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 (file)
index 0000000..aaf0c05
--- /dev/null
@@ -0,0 +1 @@
+http://download.m0k.org/handbrake/contrib/libdca-r81.tar.gz
index afc775e..7765d01 100644 (file)
@@ -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) ;
index 9028775..6604ec4 100644 (file)
@@ -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)
index 278e34f..fd77999 100644 (file)
@@ -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;
index 5b5f080..2a8c53c 100644 (file)
@@ -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 (file)
index 0000000..669112f
--- /dev/null
@@ -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;
+}
+
index b26c559..5ec4d51 100644 (file)
@@ -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",
index e9d7aa1..4aa89fb 100644 (file)
@@ -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 ); 
index 8b5d469..af91637 100644 (file)
@@ -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 ); \
index f950205..0f0262e 100644 (file)
@@ -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,
index 763bc3a..9d229b6 100644 (file)
@@ -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;
index 3e5ec4a..8f3c1d0 100644 (file)
@@ -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 ||
index 4e3f229..43f2ccb 100644 (file)
                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 */; };
                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; };
                                0DFA5C9C0B8DD3B60020BC09 /* work.c */,
                                526FBC9B0B4CAB100064E04C /* common.c */,
                                526FBC9D0B4CAB100064E04C /* deca52.c */,
+                               5558B5680BE3BADF00E15E27 /* decdca.c */,
                                526FBC9E0B4CAB100064E04C /* decavcodec.c */,
                        );
                        name = "libhb Sources";
                                0D096E010B707D3400A845D4 /* common.c in Sources */,
                                0D096E020B707D3400A845D4 /* deca52.c in Sources */,
                                0D096E030B707D3400A845D4 /* decavcodec.c in Sources */,
+                               5558B56A0BE3BADF00E15E27 /* decdca.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                0DFF0B790B6BC72A00549488 /* deca52.c in Sources */,
                                0DFF0B7A0B6BC72A00549488 /* decavcodec.c in Sources */,
                                593034EC0BBA39A100172349 /* ChapterTitles.m in Sources */,
+                               5558B5690BE3BADF00E15E27 /* decdca.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                        "-ldl",
                                        "-flat_namespace",
                                        "-read_only_relocs",
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                        "-ldl",
                                        "-flat_namespace",
                                        "-read_only_relocs",
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                        "-ldl",
                                        "-flat_namespace",
                                        "-read_only_relocs",
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                        "-ldl",
                                        "-flat_namespace",
                                        "-read_only_relocs",
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PRODUCT_NAME = HandBrake;
                                SECTORDER_FLAGS = "";
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = "Instant HandBrake";
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
                                        "-lz",
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = HandBrakeCLI;
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
                                        "-lz",
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = HandBrakeCLI;
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
                                        "-lz",
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = HandBrakeCLI;
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
                                        "-lz",
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = HandBrakeCLI;
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = "Instant HandBrake";
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = "Instant HandBrake";
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PREBINDING = NO;
                                PRODUCT_NAME = "Instant HandBrake";
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PRODUCT_NAME = HandBrake;
                                SECTORDER_FLAGS = "";
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PRODUCT_NAME = HandBrake;
                                SECTORDER_FLAGS = "";
                                        ../contrib/lib/libsamplerate.a,
                                        ../contrib/lib/libx264.a,
                                        ../contrib/lib/libxvidcore.a,
+                                       ../contrib/lib/libdca.a,
                                );
                                PRODUCT_NAME = HandBrake;
                                SECTORDER_FLAGS = "";
index 967cd9c..3ed30e4 100644 (file)
@@ -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 );