diff options
author | maurj <[email protected]> | 2007-05-02 15:56:39 +0000 |
---|---|---|
committer | maurj <[email protected]> | 2007-05-02 15:56:39 +0000 |
commit | 7800f22f054d4a96731c94bc71310c09a2b8235f (patch) | |
tree | ccee5caab83f8bda1057985f71145ef83bbfb0be | |
parent | 3a55755f5bd2fb02d5e87f100b83f81e61f7bf82 (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-- | Jamfile | 12 | ||||
-rw-r--r-- | MacOsXContribBinariesVersion.txt | 2 | ||||
-rw-r--r-- | contrib/Jamfile | 18 | ||||
-rw-r--r-- | contrib/patch-libdca.patch | 809 | ||||
-rw-r--r-- | contrib/version_libdca.txt | 1 | ||||
-rw-r--r-- | libhb/Jamfile | 2 | ||||
-rw-r--r-- | libhb/Makefile | 38 | ||||
-rw-r--r-- | libhb/common.h | 55 | ||||
-rw-r--r-- | libhb/deca52.c | 3 | ||||
-rw-r--r-- | libhb/decdca.c | 215 | ||||
-rw-r--r-- | libhb/dvd.c | 8 | ||||
-rw-r--r-- | libhb/hb.c | 1 | ||||
-rw-r--r-- | libhb/hb.h | 2 | ||||
-rw-r--r-- | libhb/internal.h | 7 | ||||
-rw-r--r-- | libhb/scan.c | 291 | ||||
-rw-r--r-- | libhb/work.c | 131 | ||||
-rw-r--r-- | macosx/HandBrake.xcodeproj/project.pbxproj | 22 | ||||
-rw-r--r-- | test/test.c | 2 |
18 files changed, 1475 insertions, 144 deletions
@@ -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 ); |