summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/a52dec/A00-a52-state-t-public.patch152
-rw-r--r--contrib/a52dec/A00-dpl2.patch114
-rw-r--r--contrib/a52dec/A01-thread-safe.patch41
-rw-r--r--contrib/a52dec/A02-imdct-shutup.patch4
-rw-r--r--libhb/audio_resample.c19
-rw-r--r--libhb/audio_resample.h10
-rw-r--r--libhb/common.c37
-rw-r--r--libhb/deca52.c296
-rw-r--r--libhb/decavcodec.c1
-rw-r--r--libhb/declpcm.c3
-rw-r--r--libhb/encavcodecaudio.c3
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);