diff options
-rw-r--r-- | contrib/a52dec/A00-a52-state-t-public.patch | 152 | ||||
-rw-r--r-- | contrib/a52dec/A00-dpl2.patch | 114 | ||||
-rw-r--r-- | contrib/a52dec/A01-thread-safe.patch | 41 | ||||
-rw-r--r-- | contrib/a52dec/A02-imdct-shutup.patch | 4 | ||||
-rw-r--r-- | libhb/audio_resample.c | 19 | ||||
-rw-r--r-- | libhb/audio_resample.h | 10 | ||||
-rw-r--r-- | libhb/common.c | 37 | ||||
-rw-r--r-- | libhb/deca52.c | 296 | ||||
-rw-r--r-- | libhb/decavcodec.c | 1 | ||||
-rw-r--r-- | libhb/declpcm.c | 3 | ||||
-rw-r--r-- | libhb/encavcodecaudio.c | 3 |
11 files changed, 376 insertions, 304 deletions
diff --git a/contrib/a52dec/A00-a52-state-t-public.patch b/contrib/a52dec/A00-a52-state-t-public.patch new file mode 100644 index 000000000..5e0af3577 --- /dev/null +++ b/contrib/a52dec/A00-a52-state-t-public.patch @@ -0,0 +1,152 @@ +diff -Naur a52dec.old/include/a52.h a52dec.new/include/a52.h +--- a52dec.old/include/a52.h 2002-01-28 06:37:54.000000000 +0100 ++++ a52dec.new/include/a52.h 2012-07-16 14:13:35.000000000 +0200 +@@ -30,7 +30,71 @@ + typedef double sample_t; + #endif + +-typedef struct a52_state_s a52_state_t; ++typedef struct { ++ uint8_t bai; /* fine SNR offset, fast gain */ ++ uint8_t deltbae; /* delta bit allocation exists */ ++ int8_t deltba[50]; /* per-band delta bit allocation */ ++} ba_t; ++ ++typedef struct { ++ uint8_t exp[256]; /* decoded channel exponents */ ++ int8_t bap[256]; /* derived channel bit allocation */ ++} expbap_t; ++ ++typedef struct { ++ uint8_t fscod; /* sample rate */ ++ uint8_t halfrate; /* halfrate factor */ ++ uint8_t acmod; /* coded channels */ ++ uint8_t lfeon; /* coded lfe channel */ ++ sample_t clev; /* centre channel mix level */ ++ sample_t slev; /* surround channels mix level */ ++ ++ int output; /* type of output */ ++ sample_t level; /* output level */ ++ sample_t bias; /* output bias */ ++ ++ int dynrnge; /* apply dynamic range */ ++ sample_t dynrng; /* dynamic range */ ++ void * dynrngdata; /* dynamic range callback funtion and data */ ++ sample_t (* dynrngcall) (sample_t range, void * dynrngdata); ++ ++ uint8_t chincpl; /* channel coupled */ ++ uint8_t phsflginu; /* phase flags in use (stereo only) */ ++ uint8_t cplstrtmant; /* coupling channel start mantissa */ ++ uint8_t cplendmant; /* coupling channel end mantissa */ ++ uint32_t cplbndstrc; /* coupling band structure */ ++ sample_t cplco[5][18]; /* coupling coordinates */ ++ ++ /* derived information */ ++ uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */ ++ uint8_t ncplbnd; /* number of coupling bands */ ++ ++ uint8_t rematflg; /* stereo rematrixing */ ++ ++ uint8_t endmant[5]; /* channel end mantissa */ ++ ++ uint16_t bai; /* bit allocation information */ ++ ++ uint32_t * buffer_start; ++ uint16_t lfsr_state; /* dither state */ ++ uint32_t bits_left; ++ uint32_t current_word; ++ ++ uint8_t csnroffst; /* coarse SNR offset */ ++ ba_t cplba; /* coupling bit allocation parameters */ ++ ba_t ba[5]; /* channel bit allocation parameters */ ++ ba_t lfeba; /* lfe bit allocation parameters */ ++ ++ uint8_t cplfleak; /* coupling fast leak init */ ++ uint8_t cplsleak; /* coupling slow leak init */ ++ ++ expbap_t cpl_expbap; ++ expbap_t fbw_expbap[5]; ++ expbap_t lfe_expbap; ++ ++ sample_t * samples; ++ int downmixed; ++} a52_state_t; + + #define A52_CHANNEL 0 + #define A52_MONO 1 +diff -Naur a52dec.old/liba52/a52_internal.h a52dec.new/liba52/a52_internal.h +--- a52dec.old/liba52/a52_internal.h 2002-07-28 03:52:06.000000000 +0200 ++++ a52dec.new/liba52/a52_internal.h 2012-07-16 14:11:47.000000000 +0200 +@@ -21,72 +21,6 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +-typedef struct { +- uint8_t bai; /* fine SNR offset, fast gain */ +- uint8_t deltbae; /* delta bit allocation exists */ +- int8_t deltba[50]; /* per-band delta bit allocation */ +-} ba_t; +- +-typedef struct { +- uint8_t exp[256]; /* decoded channel exponents */ +- int8_t bap[256]; /* derived channel bit allocation */ +-} expbap_t; +- +-struct a52_state_s { +- uint8_t fscod; /* sample rate */ +- uint8_t halfrate; /* halfrate factor */ +- uint8_t acmod; /* coded channels */ +- uint8_t lfeon; /* coded lfe channel */ +- sample_t clev; /* centre channel mix level */ +- sample_t slev; /* surround channels mix level */ +- +- int output; /* type of output */ +- sample_t level; /* output level */ +- sample_t bias; /* output bias */ +- +- int dynrnge; /* apply dynamic range */ +- sample_t dynrng; /* dynamic range */ +- void * dynrngdata; /* dynamic range callback funtion and data */ +- sample_t (* dynrngcall) (sample_t range, void * dynrngdata); +- +- uint8_t chincpl; /* channel coupled */ +- uint8_t phsflginu; /* phase flags in use (stereo only) */ +- uint8_t cplstrtmant; /* coupling channel start mantissa */ +- uint8_t cplendmant; /* coupling channel end mantissa */ +- uint32_t cplbndstrc; /* coupling band structure */ +- sample_t cplco[5][18]; /* coupling coordinates */ +- +- /* derived information */ +- uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */ +- uint8_t ncplbnd; /* number of coupling bands */ +- +- uint8_t rematflg; /* stereo rematrixing */ +- +- uint8_t endmant[5]; /* channel end mantissa */ +- +- uint16_t bai; /* bit allocation information */ +- +- uint32_t * buffer_start; +- uint16_t lfsr_state; /* dither state */ +- uint32_t bits_left; +- uint32_t current_word; +- +- uint8_t csnroffst; /* coarse SNR offset */ +- ba_t cplba; /* coupling bit allocation parameters */ +- ba_t ba[5]; /* channel bit allocation parameters */ +- ba_t lfeba; /* lfe bit allocation parameters */ +- +- uint8_t cplfleak; /* coupling fast leak init */ +- uint8_t cplsleak; /* coupling slow leak init */ +- +- expbap_t cpl_expbap; +- expbap_t fbw_expbap[5]; +- expbap_t lfe_expbap; +- +- sample_t * samples; +- int downmixed; +-}; +- + #define LEVEL_PLUS6DB 2.0 + #define LEVEL_PLUS3DB 1.4142135623730951 + #define LEVEL_3DB 0.7071067811865476 diff --git a/contrib/a52dec/A00-dpl2.patch b/contrib/a52dec/A00-dpl2.patch deleted file mode 100644 index cf1c8a64a..000000000 --- a/contrib/a52dec/A00-dpl2.patch +++ /dev/null @@ -1,114 +0,0 @@ -diff -Naur a52dec_original/include/a52.h a52dec_patched/include/a52.h ---- a52dec_original/include/a52.h 2002-01-28 05:37:54.000000000 +0000 -+++ a52dec_patched/include/a52.h 2007-04-04 19:12:57.000000000 +0100 -@@ -48,6 +48,10 @@ - #define A52_LFE 16 - #define A52_ADJUST_LEVEL 32 - -+// this next constant can be ORed with A52_DOLBY to tell liba52 to use 5.0 DPLII matrix encoding, -+// rather than just 4.0 Dolby Surround matrix encoding -+#define A52_USE_DPLII 64 -+ - a52_state_t * a52_init (uint32_t mm_accel); - sample_t * a52_samples (a52_state_t * state); - int a52_syncinfo (uint8_t * buf, int * flags, -diff -Naur a52dec_original/liba52/a52_internal.h a52dec_patched/liba52/a52_internal.h ---- a52dec_original/liba52/a52_internal.h 2002-07-28 02:52:06.000000000 +0100 -+++ a52dec_patched/liba52/a52_internal.h 2007-04-04 19:11:43.000000000 +0100 -@@ -93,6 +93,10 @@ - #define LEVEL_45DB 0.5946035575013605 - #define LEVEL_6DB 0.5 - -+// 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 -+ - #define EXP_REUSE (0) - #define EXP_D15 (1) - #define EXP_D25 (2) -diff -Naur a52dec_original/liba52/downmix.c a52dec_patched/liba52/downmix.c ---- a52dec_original/liba52/downmix.c 2002-01-28 05:37:54.000000000 +0000 -+++ a52dec_patched/liba52/downmix.c 2007-04-06 13:47:49.000000000 +0100 -@@ -34,6 +34,7 @@ - int a52_downmix_init (int input, int flags, sample_t * level, - sample_t clev, sample_t slev) - { -+ - static uint8_t table[11][8] = { - {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, - A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO}, -@@ -148,6 +149,9 @@ - break; - } - -+ // add the DPLII flag back into the output if it was passed in -+ output = output | (flags & A52_USE_DPLII); -+ - return output; - } - -@@ -418,17 +422,46 @@ - } - } - --static void mix32toS (sample_t * samples, sample_t bias) -+static void mix32toS (sample_t * samples, sample_t bias, int use_dpl2) - { -- int i; -- 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; -- } -+ if (use_dpl2 == 1) { -+ -+ int i; -+ 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] = bias + Lt + Lss; -+ samples[i + 256] = bias + Rt + Rss; -+ -+ } -+ -+ } else { -+ -+ int i; -+ 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) -@@ -533,7 +566,7 @@ - break; - - case CONVERT (A52_3F2R, A52_DOLBY): -- mix32toS (samples, bias); -+ mix32toS (samples, bias, ((output & A52_USE_DPLII) == A52_USE_DPLII)); - break; - - case CONVERT (A52_3F1R, A52_3F): diff --git a/contrib/a52dec/A01-thread-safe.patch b/contrib/a52dec/A01-thread-safe.patch index 0fa7f0a53..4ca2d1a08 100644 --- a/contrib/a52dec/A01-thread-safe.patch +++ b/contrib/a52dec/A01-thread-safe.patch @@ -1,19 +1,19 @@ -diff -Naur -x '*.o' -x '*.lo' -x '*.a' -x '*.la' a52dec/liba52/a52_internal.h ../a52dec.new/liba52/a52_internal.h ---- a52dec/liba52/a52_internal.h 2011-04-28 07:54:05.499052327 -0700 -+++ ../a52dec.new/liba52/a52_internal.h 2011-04-28 07:50:30.998845068 -0700 -@@ -32,6 +32,11 @@ - int8_t bap[256]; /* derived channel bit allocation */ +diff -Naur a52dec.old/include/a52.h a52dec.new/include/a52.h +--- a52dec.old/include/a52.h 2012-07-16 14:24:14.000000000 +0200 ++++ a52dec.new/include/a52.h 2012-07-16 14:31:37.000000000 +0200 +@@ -42,6 +42,11 @@ } expbap_t; -+typedef struct complex_s { + typedef struct { + sample_t real; + sample_t imag; +} complex_t; + - struct a52_state_s { - uint8_t fscod; /* sample rate */ - uint8_t halfrate; /* halfrate factor */ -@@ -85,6 +90,20 @@ ++typedef struct { + uint8_t fscod; /* sample rate */ + uint8_t halfrate; /* halfrate factor */ + uint8_t acmod; /* coded channels */ +@@ -94,6 +99,20 @@ sample_t * samples; int downmixed; @@ -31,10 +31,13 @@ diff -Naur -x '*.o' -x '*.lo' -x '*.a' -x '*.la' a52dec/liba52/a52_internal.h .. + complex_t * post2; // size 32 + + sample_t * a52_imdct_window; // size 256 - }; + } a52_state_t; - #define LEVEL_PLUS6DB 2.0 -@@ -119,6 +138,6 @@ + #define A52_CHANNEL 0 +diff -Naur a52dec.old/liba52/a52_internal.h a52dec.new/liba52/a52_internal.h +--- a52dec.old/liba52/a52_internal.h 2012-07-16 14:24:14.000000000 +0200 ++++ a52dec.new/liba52/a52_internal.h 2012-07-16 14:28:33.000000000 +0200 +@@ -49,6 +49,6 @@ sample_t clev, sample_t slev); void a52_upmix (sample_t * samples, int acmod, int output); @@ -44,9 +47,9 @@ diff -Naur -x '*.o' -x '*.lo' -x '*.a' -x '*.la' a52dec/liba52/a52_internal.h .. +void a52_imdct_init (a52_state_t * state, uint32_t mm_accel); +void a52_imdct_256 (a52_state_t * state, sample_t * data, sample_t * delay, sample_t bias); +void a52_imdct_512 (a52_state_t * state, sample_t * data, sample_t * delay, sample_t bias); -diff -Naur -x '*.o' -x '*.lo' -x '*.a' -x '*.la' a52dec/liba52/imdct.c ../a52dec.new/liba52/imdct.c ---- a52dec/liba52/imdct.c 2002-07-27 18:52:07.000000000 -0700 -+++ ../a52dec.new/liba52/imdct.c 2011-04-28 07:51:00.398624376 -0700 +diff -Naur a52dec.old/liba52/imdct.c a52dec.new/liba52/imdct.c +--- a52dec.old/liba52/imdct.c 2012-07-16 14:24:14.000000000 +0200 ++++ a52dec.new/liba52/imdct.c 2012-07-16 14:33:00.000000000 +0200 @@ -40,11 +40,6 @@ #include "a52_internal.h" #include "mm_accel.h" @@ -316,9 +319,9 @@ diff -Naur -x '*.o' -x '*.lo' -x '*.a' -x '*.la' a52dec/liba52/imdct.c ../a52dec } #ifdef LIBA52_DJBFFT -diff -Naur -x '*.o' -x '*.lo' -x '*.a' -x '*.la' a52dec/liba52/parse.c ../a52dec.new/liba52/parse.c ---- a52dec/liba52/parse.c 2002-07-27 18:52:07.000000000 -0700 -+++ ../a52dec.new/liba52/parse.c 2011-04-28 07:40:48.030435061 -0700 +diff -Naur a52dec.old/liba52/parse.c a52dec.new/liba52/parse.c +--- a52dec.old/liba52/parse.c 2012-07-16 14:24:14.000000000 +0200 ++++ a52dec.new/liba52/parse.c 2012-07-16 14:33:00.000000000 +0200 @@ -56,16 +56,53 @@ a52_state_t * state; int i; diff --git a/contrib/a52dec/A02-imdct-shutup.patch b/contrib/a52dec/A02-imdct-shutup.patch index 8d57ab7a3..a22e5979e 100644 --- a/contrib/a52dec/A02-imdct-shutup.patch +++ b/contrib/a52dec/A02-imdct-shutup.patch @@ -1,6 +1,6 @@ diff -Naur a52dec_original/liba52/imdct.c a52dec_patched/liba52/imdct.c ---- a52dec_original/liba52/imdct.c 2002-07-28 03:52:07.000000000 +0200 -+++ a52dec_patched/liba52/imdct.c 2011-07-15 20:29:09.000000000 +0200 +--- a52dec.old/liba52/imdct.c 2002-07-28 03:52:07.000000000 +0200 ++++ a52dec.new/liba52/imdct.c 2011-07-15 20:29:09.000000000 +0200 @@ -425,7 +425,6 @@ } else #endif diff --git a/libhb/audio_resample.c b/libhb/audio_resample.c index ea09b38a2..072351192 100644 --- a/libhb/audio_resample.c +++ b/libhb/audio_resample.c @@ -18,7 +18,10 @@ hb_audio_resample_t* hb_audio_resample_init(enum AVSampleFormat output_sample_fm { hb_audio_resample_t *resample = malloc(sizeof(hb_audio_resample_t)); if (resample == NULL) + { + hb_error("hb_audio_resample_init: failed to allocate resample"); return NULL; + } resample->out.sample_fmt = output_sample_fmt; resample->out.sample_size = @@ -37,6 +40,8 @@ hb_audio_resample_t* hb_audio_resample_init(enum AVSampleFormat output_sample_fm int hb_audio_resample_update(hb_audio_resample_t *resample, enum AVSampleFormat new_sample_fmt, uint64_t new_channel_layout, + double new_surroundmixlev, + double new_centermixlev, int new_channels) { if (resample == NULL) @@ -55,7 +60,9 @@ int hb_audio_resample_update(hb_audio_resample_t *resample, int resample_changed = (resample->resample_needed && (resample->in.sample_fmt != new_sample_fmt || - resample->in.channel_layout != new_channel_layout)); + resample->in.channel_layout != new_channel_layout || + resample->in.center_mix_level != new_centermixlev || + resample->in.surround_mix_level != new_surroundmixlev)); if (resample_changed || (resample->resample_needed && resample->avresample == NULL)) @@ -87,6 +94,10 @@ int hb_audio_resample_update(hb_audio_resample_t *resample, new_sample_fmt, 0); av_opt_set_int(resample->avresample, "in_channel_layout", new_channel_layout, 0); + av_opt_set_double(resample->avresample, "center_mix_level", + new_centermixlev, 0); + av_opt_set_double(resample->avresample, "surround_mix_level", + new_surroundmixlev, 0); if (avresample_open(resample->avresample) < 0) { @@ -96,8 +107,10 @@ int hb_audio_resample_update(hb_audio_resample_t *resample, return 1; } - resample->in.sample_fmt = new_sample_fmt; - resample->in.channel_layout = new_channel_layout; + resample->in.sample_fmt = new_sample_fmt; + resample->in.channel_layout = new_channel_layout; + resample->in.center_mix_level = new_centermixlev; + resample->in.surround_mix_level = new_surroundmixlev; } return 0; diff --git a/libhb/audio_resample.h b/libhb/audio_resample.h index 4b1586e73..29a7f91d0 100644 --- a/libhb/audio_resample.h +++ b/libhb/audio_resample.h @@ -17,10 +17,14 @@ #ifndef AUDIO_RESAMPLE_H #define AUDIO_RESAMPLE_H +#include <math.h> #include <stdint.h> #include "libavutil/audioconvert.h" #include "libavresample/avresample.h" +/* Default mix level for center and surround channels */ +#define HB_MIXLEV_DEFAULT ((double)M_SQRT1_2) + typedef struct { int resample_needed; @@ -31,6 +35,8 @@ typedef struct int channels; int linesize; uint64_t channel_layout; + double center_mix_level; + double surround_mix_level; enum AVSampleFormat sample_fmt; } in; @@ -46,7 +52,7 @@ typedef struct } out; } hb_audio_resample_t; -/* Initialize an hb_audio_resample_t to convert audio to the requested +/* Initialize an hb_audio_resample_t for converting audio to the requested * sample_fmt and channel_layout, using the specified matrix_encoding. * * Input characteristics are set via hb_audio_resample_update(). @@ -65,6 +71,8 @@ hb_audio_resample_t* hb_audio_resample_init(enum AVSampleFormat output_sample_fm int hb_audio_resample_update(hb_audio_resample_t *resample, enum AVSampleFormat new_sample_fmt, uint64_t new_channel_layout, + double new_surroundmixlev, + double new_centermixlev, int new_channels); /* Free an hb_audio_remsample_t. */ diff --git a/libhb/common.c b/libhb/common.c index 9ff9f44a3..6315498cc 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -722,43 +722,36 @@ int hb_get_best_mixdown(uint32_t codec, uint64_t layout, int mixdown) // Audio passthrough, no mixdown return HB_AMIXDOWN_NONE; } - else if ((layout & AV_CH_LAYOUT_5POINT1) == AV_CH_LAYOUT_5POINT1 || - (layout & AV_CH_LAYOUT_5POINT1_BACK) == AV_CH_LAYOUT_5POINT1_BACK) + else if ((layout & AV_CH_LAYOUT_2_1) == AV_CH_LAYOUT_2_1 || + (layout & AV_CH_LAYOUT_2_2) == AV_CH_LAYOUT_2_2 || + (layout & AV_CH_LAYOUT_QUAD) == AV_CH_LAYOUT_QUAD) { - // full 3F2R, possibly with additional channels, and an LFE - // limiting factor: liba52, libdca (can't upmix) - if (codec == HB_ACODEC_LAME || codec == HB_ACODEC_FFAAC) + // at least 2 front channels and one back or side channel + // allow downmixing or upmixing to 5.1 (yes, we can) + if (codec != HB_ACODEC_LAME && codec != HB_ACODEC_FFAAC) { - best_mixdown = HB_AMIXDOWN_DOLBYPLII; + best_mixdown = HB_AMIXDOWN_6CH; } else { - best_mixdown = HB_AMIXDOWN_6CH; + best_mixdown = HB_AMIXDOWN_DOLBYPLII; } } - else if ((layout & AV_CH_LAYOUT_5POINT0) == AV_CH_LAYOUT_5POINT0 || - (layout & AV_CH_LAYOUT_5POINT0_BACK) == AV_CH_LAYOUT_5POINT0_BACK) + else if (layout == AV_CH_LAYOUT_STEREO_DOWNMIX) { - // full 3F2R, possibly with additional channels, but no LFE - // limiting factor: liba52, libdca (can't upmix) - // limiting factor: libdca (can only do DPL2 with 3F2R sources) - best_mixdown = HB_AMIXDOWN_DOLBYPLII; + // Dolby in, allow Dolby out + best_mixdown = HB_AMIXDOWN_DOLBY; } - else if(layout == AV_CH_LAYOUT_STEREO) + else if (av_get_channel_layout_nb_channels(layout) > 1) { - // limiting factor: no Dolby Surround for Stereo sources + // more than one channel, allow Stereo downmix best_mixdown = HB_AMIXDOWN_STEREO; } - else if(av_get_channel_layout_nb_channels(layout) == 1) + else { // only one channel, not much point in upmixing best_mixdown = HB_AMIXDOWN_MONO; } - else - { - // everything else, including Dolby (AV_CH_LAYOUT_STEREO_DOWNMIX) - best_mixdown = HB_AMIXDOWN_DOLBY; - } // return the best that is not greater than the requested mixdown // HB_INVALID_AMIXDOWN means the caller requested the best available mixdown @@ -773,7 +766,7 @@ int hb_get_default_mixdown(uint32_t codec, uint64_t layout) int mixdown; switch (codec) { - // the AC3 encoder defaults to the best mixdown up to 6-channel + // the FLAC and AC3 encoders default to the best mixdown up to 6-channel case HB_ACODEC_FFFLAC: case HB_ACODEC_AC3: mixdown = HB_AMIXDOWN_6CH; diff --git a/libhb/deca52.c b/libhb/deca52.c index 0c1708de2..5f9960a91 100644 --- a/libhb/deca52.c +++ b/libhb/deca52.c @@ -9,6 +9,7 @@ #include "hb.h" #include "audio_remap.h" +#include "audio_resample.h" #include "a52dec/a52.h" #include "libavutil/crc.h" @@ -20,11 +21,9 @@ struct hb_work_private_s /* liba52 handle */ a52_state_t * state; - int flags_in; - int flags_out; + int flags; int rate; int bitrate; - int out_discrete_channels; int error; int frames; // number of good frames decoded int crc_errors; // number of frames with crc errors @@ -36,6 +35,11 @@ struct hb_work_private_s hb_list_t *list; const AVCRC *crc_table; uint8_t frame[3840]; + + int nchannels; + uint64_t channel_layout; + hb_audio_resample_t *resample; + int *remap_table; }; static int deca52Init( hb_work_object_t *, hb_job_t * ); @@ -55,6 +59,33 @@ hb_work_object_t hb_deca52 = deca52BSInfo }; +/* Translate acmod and lfeon on AV_CH_LAYOUT */ +static const uint64_t acmod2layout[] = +{ + AV_CH_LAYOUT_STEREO, // A52_CHANNEL (0) + AV_CH_LAYOUT_MONO, // A52_MONO (1) + AV_CH_LAYOUT_STEREO, // A52_STEREO (2) + AV_CH_LAYOUT_SURROUND, // A52_3F (3) + AV_CH_LAYOUT_2_1, // A52_2F1R (4) + AV_CH_LAYOUT_4POINT0, // A52_3F1R (5) + AV_CH_LAYOUT_2_2, // A52_2F2R (6) + AV_CH_LAYOUT_5POINT0, // A52_3F2R (7) + AV_CH_LAYOUT_MONO, // A52_CHANNEL1 (8) + AV_CH_LAYOUT_MONO, // A52_CHANNEL2 (9) + AV_CH_LAYOUT_STEREO_DOWNMIX, // A52_DOLBY (10) + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_STEREO, // A52_CHANNEL_MASK (15) +}; + +static const uint64_t lfeon2layout[] = +{ + 0, + AV_CH_LOW_FREQUENCY, +}; + /*********************************************************************** * Local prototypes **********************************************************************/ @@ -89,48 +120,36 @@ static sample_t dynrng_call (sample_t c, void *data) *********************************************************************** * Allocate the work object, initialize liba52 **********************************************************************/ -static int deca52Init( hb_work_object_t * w, hb_job_t * job ) +static int deca52Init(hb_work_object_t *w, hb_job_t *job) { - hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); - hb_audio_t * audio = w->audio; + hb_work_private_t *pv = calloc(1, sizeof(hb_work_private_t)); + hb_audio_t *audio = w->audio; w->private_data = pv; - pv->job = job; - - pv->crc_table = av_crc_get_table( AV_CRC_16_ANSI ); + pv->job = job; + pv->state = a52_init(0); pv->list = hb_list_init(); - pv->state = a52_init( 0 ); - pv->level = 1.0; - pv->dynamic_range_compression = audio->config.out.dynamic_range_compression; + pv->crc_table = av_crc_get_table(AV_CRC_16_ANSI); - /* Decide what format we want out of a52dec; - * work.c has already done some of this deduction for us in do_job(). */ - switch( audio->config.out.mixdown ) + /* Downmixing */ + if (audio->config.out.codec != HB_ACODEC_AC3_PASS) { - case HB_AMIXDOWN_6CH: - pv->flags_out = (A52_3F2R|A52_LFE); - break; - - case HB_AMIXDOWN_DOLBYPLII: - pv->flags_out = (A52_DOLBY|A52_USE_DPLII); - break; - - case HB_AMIXDOWN_DOLBY: - pv->flags_out = A52_DOLBY; - break; - - case HB_AMIXDOWN_MONO: - pv->flags_out = A52_MONO; - break; - - default: - pv->flags_out = A52_STEREO; - break; + /* We want AV_SAMPLE_FMT_FLT samples */ + pv->level = 1.0; + pv->dynamic_range_compression = + audio->config.out.dynamic_range_compression; + + int mode; + uint64_t layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, &mode); + pv->resample = hb_audio_resample_init(AV_SAMPLE_FMT_FLT, layout, mode, + audio->config.out.normalize_mix_level); + if (pv->resample == NULL) + { + hb_error("deca52Init: hb_audio_resample_init() failed"); + return 1; + } } - /* pass the number of channels used into the private work data */ - pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count( audio->config.out.mixdown ); - return 0; } @@ -139,19 +158,25 @@ static int deca52Init( hb_work_object_t * w, hb_job_t * job ) *********************************************************************** * Free memory **********************************************************************/ -static void deca52Close( hb_work_object_t * w ) +static void deca52Close(hb_work_object_t *w) { - hb_work_private_t * pv = w->private_data; + hb_work_private_t *pv = w->private_data; + w->private_data = NULL; - if ( pv->crc_errors ) + if (pv->crc_errors) { - hb_log( "deca52: %d frames decoded, %d crc errors, %d bytes dropped", - pv->frames, pv->crc_errors, pv->bytes_dropped ); + hb_log("deca52: %d frames decoded, %d crc errors, %d bytes dropped", + pv->frames, pv->crc_errors, pv->bytes_dropped); } - a52_free( pv->state ); - hb_list_empty( &pv->list ); - free( pv ); - w->private_data = NULL; + + if (pv->remap_table != NULL) + { + free(pv->remap_table); + } + hb_audio_resample_free(pv->resample); + hb_list_empty(&pv->list); + a52_free(pv->state); + free(pv); } /*********************************************************************** @@ -200,13 +225,12 @@ static int deca52Work( hb_work_object_t * w, hb_buffer_t ** buf_in, *********************************************************************** * **********************************************************************/ -static hb_buffer_t * Decode( hb_work_object_t * w ) +static hb_buffer_t* Decode(hb_work_object_t *w) { - hb_work_private_t * pv = w->private_data; - hb_buffer_t * buf; - hb_audio_t * audio = w->audio; - int i, j, k; - int size = 0; + hb_work_private_t *pv = w->private_data; + hb_audio_t *audio = w->audio; + hb_buffer_t *out; + int size = 0; // check that we're at the start of a valid frame and align to the // start of a valid frame if we're not. @@ -216,7 +240,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) { /* check if this is a valid header */ hb_list_seebytes( pv->list, pv->frame, 7 ); - size = a52_syncinfo( pv->frame, &pv->flags_in, &pv->rate, &pv->bitrate ); + size = a52_syncinfo(pv->frame, &pv->flags, &pv->rate, &pv->bitrate); if ( size > 0 ) { // header looks valid - check the crc1 @@ -277,65 +301,96 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) ipts = -1; } - double pts = ( ipts != -1 ) ? ipts : pv->next_expected_pts; double frame_dur = (6. * 256. * 90000.) / pv->rate; + double pts = (ipts != -1) ? (double)ipts : pv->next_expected_pts; /* AC3 passthrough: don't decode the AC3 frame */ - if( audio->config.out.codec == HB_ACODEC_AC3_PASS ) + if (audio->config.out.codec == HB_ACODEC_AC3_PASS) { - buf = hb_buffer_init( size ); - memcpy( buf->data, pv->frame, size ); - buf->s.start = pts; - buf->s.duration = frame_dur; - pts += frame_dur; - buf->s.stop = pts; - pv->next_expected_pts = pts; - return buf; + out = hb_buffer_init(size); + memcpy(out->data, pv->frame, size); } - - /* Feed liba52 */ - a52_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 ); - - /* If a user specifies strong dynamic range compression (>1), adjust it. - If a user specifies default dynamic range compression (1), leave it alone. - If a user specifies no dynamic range compression (0), call a null function. */ - if( pv->dynamic_range_compression > 1.0 ) - { - a52_dynrng( pv->state, dynrng_call, &pv->dynamic_range_compression ); - } - else if( !pv->dynamic_range_compression ) + else { - a52_dynrng( pv->state, NULL, NULL ); - } + int i, j, k; + hb_buffer_t *flt; - /* 6 blocks per frame, 256 samples per block, channelsused channels */ - buf = hb_buffer_init( 6 * 256 * pv->out_discrete_channels * sizeof( float ) ); - buf->s.start = pts; - buf->s.duration = frame_dur; - pts += frame_dur; - buf->s.stop = pts; - pv->next_expected_pts = pts; + /* Feed liba52 */ + a52_frame(pv->state, pv->frame, &pv->flags, &pv->level, 0); - for( i = 0; i < 6; i++ ) - { - sample_t * samples_in; - float * samples_out; + /* If the user requested strong DRC (>1), adjust it. + * If the user requested default DRC (1), leave it alone. + * If the user requested no DRC (0), call a null function. */ + if (pv->dynamic_range_compression > 1.0) + { + a52_dynrng(pv->state, dynrng_call, &pv->dynamic_range_compression); + } + else if (!pv->dynamic_range_compression) + { + a52_dynrng(pv->state, NULL, NULL); + } + + /* Update input channel layout and prepare remapping */ + uint64_t new_layout = (acmod2layout[(pv->flags & A52_CHANNEL_MASK)] | + lfeon2layout[(pv->flags & A52_LFE) != 0]); + if (new_layout != pv->channel_layout) + { + if (pv->remap_table != NULL) + { + free(pv->remap_table); + } + pv->remap_table = hb_audio_remap_build_table(new_layout, + &hb_libav_chan_map, + &hb_liba52_chan_map); + if (pv->remap_table == NULL) + { + hb_error("deca52: hb_audio_remap_build_table() failed"); + return NULL; + } + pv->channel_layout = new_layout; + pv->nchannels = av_get_channel_layout_nb_channels(new_layout); + } - a52_block( pv->state ); - samples_in = a52_samples( pv->state ); - samples_out = ((float *) buf->data) + 256 * pv->out_discrete_channels * i; + /* 6 blocks per frame, 256 samples per block, pv->nchannels channels */ + flt = hb_buffer_init(1536 * pv->nchannels * sizeof(float)); - /* Interleave */ - for( j = 0; j < 256; j++ ) + for (i = 0; i < 6; i++) { - for ( k = 0; k < pv->out_discrete_channels; k++ ) + sample_t *samples_in; + float *samples_out; + + a52_block(pv->state); + samples_in = a52_samples(pv->state); + samples_out = ((float*)flt->data) + 256 * pv->nchannels * i; + + /* Planar -> interleaved, remap to Libav channel order */ + for (j = 0; j < 256; j++) { - samples_out[(pv->out_discrete_channels*j)+k] = samples_in[(256*k)+j]; + for (k = 0; k < pv->nchannels; k++) + { + samples_out[(pv->nchannels*j)+k] = + samples_in[(256*pv->remap_table[k])+j]; + } } } + hb_audio_resample_update(pv->resample, AV_SAMPLE_FMT_FLT, + pv->channel_layout, (double)pv->state->slev, + (double)pv->state->clev, pv->nchannels); + out = hb_audio_resample(pv->resample, (void*)flt->data, 1536); + hb_buffer_close(&flt); + } + if (out == NULL) + { + return NULL; } - return buf; + + out->s.start = pts; + out->s.duration = frame_dur; + pts += frame_dur; + out->s.stop = pts; + pv->next_expected_pts = pts; + return out; } static int find_sync( const uint8_t *buf, int len ) @@ -439,52 +494,11 @@ static int deca52BSInfo( hb_work_object_t *w, const hb_buffer_t *b, info->mode = raw & 0x7; /* bsmod is the following 3 bits */ info->samples_per_frame = 1536; - switch( flags & A52_CHANNEL_MASK ) - { - /* mono sources */ - case A52_MONO: - case A52_CHANNEL1: - case A52_CHANNEL2: - info->channel_layout = AV_CH_LAYOUT_MONO; - break; - /* stereo input */ - case A52_CHANNEL: - case A52_STEREO: - info->channel_layout = AV_CH_LAYOUT_STEREO; - break; - /* Dolby Pro Logic (a.k.a. Dolby Surround), 4.0 channels (matrix-encoded) */ - case A52_DOLBY: - info->channel_layout = AV_CH_LAYOUT_STEREO_DOWNMIX; - break; - /* 3F/2R input */ - case A52_3F2R: - info->channel_layout = AV_CH_LAYOUT_5POINT0; - break; - /* 3F/1R input */ - case A52_3F1R: - info->channel_layout = AV_CH_LAYOUT_4POINT0; - break; - /* other inputs */ - case A52_3F: - info->channel_layout = AV_CH_LAYOUT_SURROUND; - break; - case A52_2F1R: - info->channel_layout = AV_CH_LAYOUT_2_1; - break; - case A52_2F2R: - info->channel_layout = AV_CH_LAYOUT_2_2; - break; - /* unknown */ - default: - info->channel_layout = AV_CH_LAYOUT_STEREO; - } - - if (flags & A52_LFE) - { - info->channel_layout |= AV_CH_LOW_FREQUENCY; - } + info->channel_layout = (acmod2layout[(flags & A52_CHANNEL_MASK)] | + lfeon2layout[(flags & A52_LFE) != 0]); - info->channel_map = &hb_liba52_chan_map; + // we remap to Libav order in Decode() + info->channel_map = &hb_libav_chan_map; return 1; } diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 934f7611e..5dc3b75b5 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -1454,6 +1454,7 @@ static void decodeAudio(hb_audio_t *audio, hb_work_private_t *pv, uint8_t *data, { hb_audio_resample_update(pv->resample, pv->context->sample_fmt, pv->context->channel_layout, + HB_MIXLEV_DEFAULT, HB_MIXLEV_DEFAULT, pv->context->channels); out = hb_audio_resample(pv->resample, (void*)frame.data[0], frame.nb_samples); diff --git a/libhb/declpcm.c b/libhb/declpcm.c index 0d4e449d1..1511a6abd 100644 --- a/libhb/declpcm.c +++ b/libhb/declpcm.c @@ -331,7 +331,8 @@ static hb_buffer_t *Decode( hb_work_object_t *w ) hb_buffer_t *out; hb_audio_resample_update(pv->resample, AV_SAMPLE_FMT_FLT, - hdr2layout[pv->nchannels - 1], pv->nchannels); + hdr2layout[pv->nchannels - 1], HB_MIXLEV_DEFAULT, + HB_MIXLEV_DEFAULT, pv->nchannels); out = hb_audio_resample(pv->resample, (void*)pv->data, pv->nsamples); if (out == NULL) { diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c index ef5297cca..8435b022d 100644 --- a/libhb/encavcodecaudio.c +++ b/libhb/encavcodecaudio.c @@ -121,7 +121,8 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job) context->channel_layout, AV_MATRIX_ENCODING_NONE, 0); if (hb_audio_resample_update(pv->resample, AV_SAMPLE_FMT_FLT, - context->channel_layout, context->channels)) + context->channel_layout, HB_MIXLEV_DEFAULT, + HB_MIXLEV_DEFAULT, context->channels)) { hb_error("encavcodecaInit: hb_audio_resample_update() failed"); hb_audio_resample_free(pv->resample); |