summary refs log tree commit diff
diff options
context:
space:
mode:
authorWout Mertens <Wout.Mertens@gmail.com>2014-05-04 01:15:16 +0200
committerWout Mertens <Wout.Mertens@gmail.com>2014-05-04 01:56:48 +0200
commitac80d4541997132d55b5af3707257f605dd897fd (patch)
tree4e511a10366886a6116d047a21d3ced88ee28493
parentead35d9d042db1cc85394a69039238453708600e (diff)
downloadnixpkgs-ac80d4541997132d55b5af3707257f605dd897fd.tar
nixpkgs-ac80d4541997132d55b5af3707257f605dd897fd.tar.gz
nixpkgs-ac80d4541997132d55b5af3707257f605dd897fd.tar.bz2
nixpkgs-ac80d4541997132d55b5af3707257f605dd897fd.tar.lz
nixpkgs-ac80d4541997132d55b5af3707257f605dd897fd.tar.xz
nixpkgs-ac80d4541997132d55b5af3707257f605dd897fd.tar.zst
nixpkgs-ac80d4541997132d55b5af3707257f605dd897fd.zip
a52dec: Add patches from Handbrake project
this project hasn't been updated in 10 years, so adding patches that
don't break the API should be ok.

Patches:
- A00: Make a52-state-t public
- A01: Make it thread-safe (changing internal API by adding state
objects)
- A02: Quell common error
- A03: Fix for automake vs autoconf
-rw-r--r--pkgs/development/libraries/a52dec/A00-a52-state-t-public.patch152
-rw-r--r--pkgs/development/libraries/a52dec/A01-thread-safe.patch462
-rw-r--r--pkgs/development/libraries/a52dec/A02-imdct-shutup.patch11
-rw-r--r--pkgs/development/libraries/a52dec/A03-automake.patch12
-rw-r--r--pkgs/development/libraries/a52dec/default.nix10
5 files changed, 646 insertions, 1 deletions
diff --git a/pkgs/development/libraries/a52dec/A00-a52-state-t-public.patch b/pkgs/development/libraries/a52dec/A00-a52-state-t-public.patch
new file mode 100644
index 00000000000..5e0af3577d6
--- /dev/null
+++ b/pkgs/development/libraries/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/pkgs/development/libraries/a52dec/A01-thread-safe.patch b/pkgs/development/libraries/a52dec/A01-thread-safe.patch
new file mode 100644
index 00000000000..4ca2d1a0873
--- /dev/null
+++ b/pkgs/development/libraries/a52dec/A01-thread-safe.patch
@@ -0,0 +1,462 @@
+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 {
++    sample_t real;
++    sample_t imag;
++} complex_t;
++
++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;
++
++    /* Root values for IFFT */
++    sample_t * roots16;           // size 3
++    sample_t * roots32;           // size 7
++    sample_t * roots64;           // size 15
++    sample_t * roots128;          // size 31
++
++    /* Twiddle factors for IMDCT */
++    complex_t * pre1;             // size 128
++    complex_t * post1;            // size 64
++    complex_t * pre2;             // size 64
++    complex_t * post2;            // size 32
++
++    sample_t * a52_imdct_window;  // size 256
+ } a52_state_t;
+ 
+ #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);
+ 
+-void a52_imdct_init (uint32_t mm_accel);
+-void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias);
+-void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias);
++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 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"
+ 
+-typedef struct complex_s {
+-    sample_t real;
+-    sample_t imag;
+-} complex_t;
+-
+ static uint8_t fftorder[] = {
+       0,128, 64,192, 32,160,224, 96, 16,144, 80,208,240,112, 48,176,
+       8,136, 72,200, 40,168,232,104,248,120, 56,184, 24,152,216, 88,
+@@ -56,22 +51,8 @@
+       6,134, 70,198, 38,166,230,102,246,118, 54,182, 22,150,214, 86
+ };
+ 
+-/* Root values for IFFT */
+-static sample_t roots16[3];
+-static sample_t roots32[7];
+-static sample_t roots64[15];
+-static sample_t roots128[31];
+-
+-/* Twiddle factors for IMDCT */
+-static complex_t pre1[128];
+-static complex_t post1[64];
+-static complex_t pre2[64];
+-static complex_t post2[32];
+-
+-static sample_t a52_imdct_window[256];
+-
+-static void (* ifft128) (complex_t * buf);
+-static void (* ifft64) (complex_t * buf);
++static void (* ifft128) (a52_state_t * state, complex_t * buf);
++static void (* ifft64) (a52_state_t * state, complex_t * buf);
+ 
+ static inline void ifft2 (complex_t * buf)
+ {
+@@ -167,7 +148,7 @@
+     a1.imag += tmp4;				\
+ } while (0)
+ 
+-static inline void ifft8 (complex_t * buf)
++static inline void ifft8 (a52_state_t * state, complex_t * buf)
+ {
+     double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+ 
+@@ -175,7 +156,7 @@
+     ifft2 (buf + 4);
+     ifft2 (buf + 6);
+     BUTTERFLY_ZERO (buf[0], buf[2], buf[4], buf[6]);
+-    BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], roots16[1]);
++    BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], state->roots16[1]);
+ }
+ 
+ static void ifft_pass (complex_t * buf, sample_t * weight, int n)
+@@ -205,66 +186,66 @@
+     } while (--i);
+ }
+ 
+-static void ifft16 (complex_t * buf)
++static void ifft16 (a52_state_t * state, complex_t * buf)
+ {
+-    ifft8 (buf);
++    ifft8 (state, buf);
+     ifft4 (buf + 8);
+     ifft4 (buf + 12);
+-    ifft_pass (buf, roots16 - 4, 4);
++    ifft_pass (buf, state->roots16 - 4, 4);
+ }
+ 
+-static void ifft32 (complex_t * buf)
++static void ifft32 (a52_state_t * state, complex_t * buf)
+ {
+-    ifft16 (buf);
+-    ifft8 (buf + 16);
+-    ifft8 (buf + 24);
+-    ifft_pass (buf, roots32 - 8, 8);
++    ifft16 (state, buf);
++    ifft8 (state, buf + 16);
++    ifft8 (state, buf + 24);
++    ifft_pass (buf, state->roots32 - 8, 8);
+ }
+ 
+-static void ifft64_c (complex_t * buf)
++static void ifft64_c (a52_state_t * state, complex_t * buf)
+ {
+-    ifft32 (buf);
+-    ifft16 (buf + 32);
+-    ifft16 (buf + 48);
+-    ifft_pass (buf, roots64 - 16, 16);
++    ifft32 (state, buf);
++    ifft16 (state, buf + 32);
++    ifft16 (state, buf + 48);
++    ifft_pass (buf, state->roots64 - 16, 16);
+ }
+ 
+-static void ifft128_c (complex_t * buf)
++static void ifft128_c (a52_state_t * state, complex_t * buf)
+ {
+-    ifft32 (buf);
+-    ifft16 (buf + 32);
+-    ifft16 (buf + 48);
+-    ifft_pass (buf, roots64 - 16, 16);
++    ifft32 (state, buf);
++    ifft16 (state, buf + 32);
++    ifft16 (state, buf + 48);
++    ifft_pass (buf, state->roots64 - 16, 16);
+ 
+-    ifft32 (buf + 64);
+-    ifft32 (buf + 96);
+-    ifft_pass (buf, roots128 - 32, 32);
++    ifft32 (state, buf + 64);
++    ifft32 (state, buf + 96);
++    ifft_pass (buf, state->roots128 - 32, 32);
+ }
+ 
+-void a52_imdct_512 (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)
+ {
+     int i, k;
+     sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2;
+-    const sample_t * window = a52_imdct_window;
++    const sample_t * window = state->a52_imdct_window;
+     complex_t buf[128];
+ 	
+     for (i = 0; i < 128; i++) {
+ 	k = fftorder[i];
+-	t_r = pre1[i].real;
+-	t_i = pre1[i].imag;
++	t_r = state->pre1[i].real;
++	t_i = state->pre1[i].imag;
+ 
+ 	buf[i].real = t_i * data[255-k] + t_r * data[k];
+ 	buf[i].imag = t_r * data[255-k] - t_i * data[k];
+     }
+ 
+-    ifft128 (buf);
++    ifft128 (state, buf);
+ 
+     /* Post IFFT complex multiply plus IFFT complex conjugate*/
+     /* Window and convert to real valued signal */
+     for (i = 0; i < 64; i++) {
+ 	/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
+-	t_r = post1[i].real;
+-	t_i = post1[i].imag;
++	t_r = state->post1[i].real;
++	t_i = state->post1[i].imag;
+ 
+ 	a_r = t_r * buf[i].real     + t_i * buf[i].imag;
+ 	a_i = t_i * buf[i].real     - t_r * buf[i].imag;
+@@ -285,18 +266,18 @@
+     }
+ }
+ 
+-void a52_imdct_256(sample_t * data, sample_t * delay, sample_t bias)
++void a52_imdct_256(a52_state_t * state, sample_t * data, sample_t * delay, sample_t bias)
+ {
+     int i, k;
+     sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2;
+-    const sample_t * window = a52_imdct_window;
++    const sample_t * window = state->a52_imdct_window;
+     complex_t buf1[64], buf2[64];
+ 
+     /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
+     for (i = 0; i < 64; i++) {
+ 	k = fftorder[i];
+-	t_r = pre2[i].real;
+-	t_i = pre2[i].imag;
++	t_r = state->pre2[i].real;
++	t_i = state->pre2[i].imag;
+ 
+ 	buf1[i].real = t_i * data[254-k] + t_r * data[k];
+ 	buf1[i].imag = t_r * data[254-k] - t_i * data[k];
+@@ -305,15 +286,15 @@
+ 	buf2[i].imag = t_r * data[255-k] - t_i * data[k+1];
+     }
+ 
+-    ifft64 (buf1);
+-    ifft64 (buf2);
++    ifft64 (state, buf1);
++    ifft64 (state, buf2);
+ 
+     /* Post IFFT complex multiply */
+     /* Window and convert to real valued signal */
+     for (i = 0; i < 32; i++) {
+ 	/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ 
+-	t_r = post2[i].real;
+-	t_i = post2[i].imag;
++	t_r = state->post2[i].real;
++	t_i = state->post2[i].imag;
+ 
+ 	a_r = t_r * buf1[i].real    + t_i * buf1[i].imag;
+ 	a_i = t_i * buf1[i].real    - t_r * buf1[i].imag;
+@@ -362,7 +343,7 @@
+     return bessel;
+ }
+ 
+-void a52_imdct_init (uint32_t mm_accel)
++void a52_imdct_init (a52_state_t * state, uint32_t mm_accel)
+ {
+     int i, k;
+     double sum;
+@@ -371,50 +352,50 @@
+     sum = 0;
+     for (i = 0; i < 256; i++) {
+ 	sum += besselI0 (i * (256 - i) * (5 * M_PI / 256) * (5 * M_PI / 256));
+-	a52_imdct_window[i] = sum;
++	state->a52_imdct_window[i] = sum;
+     }
+     sum++;
+     for (i = 0; i < 256; i++)
+-	a52_imdct_window[i] = sqrt (a52_imdct_window[i] / sum);
++	state->a52_imdct_window[i] = sqrt (state->a52_imdct_window[i] / sum);
+ 
+     for (i = 0; i < 3; i++)
+-	roots16[i] = cos ((M_PI / 8) * (i + 1));
++	state->roots16[i] = cos ((M_PI / 8) * (i + 1));
+ 
+     for (i = 0; i < 7; i++)
+-	roots32[i] = cos ((M_PI / 16) * (i + 1));
++	state->roots32[i] = cos ((M_PI / 16) * (i + 1));
+ 
+     for (i = 0; i < 15; i++)
+-	roots64[i] = cos ((M_PI / 32) * (i + 1));
++	state->roots64[i] = cos ((M_PI / 32) * (i + 1));
+ 
+     for (i = 0; i < 31; i++)
+-	roots128[i] = cos ((M_PI / 64) * (i + 1));
++	state->roots128[i] = cos ((M_PI / 64) * (i + 1));
+ 
+     for (i = 0; i < 64; i++) {
+ 	k = fftorder[i] / 2 + 64;
+-	pre1[i].real = cos ((M_PI / 256) * (k - 0.25));
+-	pre1[i].imag = sin ((M_PI / 256) * (k - 0.25));
++	state->pre1[i].real = cos ((M_PI / 256) * (k - 0.25));
++	state->pre1[i].imag = sin ((M_PI / 256) * (k - 0.25));
+     }
+ 
+     for (i = 64; i < 128; i++) {
+ 	k = fftorder[i] / 2 + 64;
+-	pre1[i].real = -cos ((M_PI / 256) * (k - 0.25));
+-	pre1[i].imag = -sin ((M_PI / 256) * (k - 0.25));
++	state->pre1[i].real = -cos ((M_PI / 256) * (k - 0.25));
++	state->pre1[i].imag = -sin ((M_PI / 256) * (k - 0.25));
+     }
+ 
+     for (i = 0; i < 64; i++) {
+-	post1[i].real = cos ((M_PI / 256) * (i + 0.5));
+-	post1[i].imag = sin ((M_PI / 256) * (i + 0.5));
++	state->post1[i].real = cos ((M_PI / 256) * (i + 0.5));
++	state->post1[i].imag = sin ((M_PI / 256) * (i + 0.5));
+     }
+ 
+     for (i = 0; i < 64; i++) {
+ 	k = fftorder[i] / 4;
+-	pre2[i].real = cos ((M_PI / 128) * (k - 0.25));
+-	pre2[i].imag = sin ((M_PI / 128) * (k - 0.25));
++	state->pre2[i].real = cos ((M_PI / 128) * (k - 0.25));
++	state->pre2[i].imag = sin ((M_PI / 128) * (k - 0.25));
+     }
+ 
+     for (i = 0; i < 32; i++) {
+-	post2[i].real = cos ((M_PI / 128) * (i + 0.5));
+-	post2[i].imag = sin ((M_PI / 128) * (i + 0.5));
++	state->post2[i].real = cos ((M_PI / 128) * (i + 0.5));
++	state->post2[i].imag = sin ((M_PI / 128) * (i + 0.5));
+     }
+ 
+ #ifdef LIBA52_DJBFFT
+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;
+ 
+-    state = malloc (sizeof (a52_state_t));
++    state = calloc (1, sizeof (a52_state_t));
+     if (state == NULL)
+ 	return NULL;
+ 
+     state->samples = memalign (16, 256 * 12 * sizeof (sample_t));
+     if (state->samples == NULL) {
+-	free (state);
+-	return NULL;
++        goto fail;
+     }
+ 
++    /* Root values for IFFT */
++    state->roots16 = memalign (16, 3 * sizeof (sample_t));
++    if (state->roots16 == NULL)
++        goto fail;
++
++    state->roots32 = memalign (16, 7 * sizeof (sample_t));
++    if (state->roots32 == NULL)
++        goto fail;
++
++    state->roots64 = memalign (16, 15 * sizeof (sample_t));
++    if (state->roots64 == NULL)
++        goto fail;
++
++    state->roots128 = memalign (16, 31 * sizeof (sample_t));
++    if (state->roots128 == NULL)
++        goto fail;
++
++    /* Twiddle factors for IMDCT */
++    state->pre1 = memalign (16, 128 * sizeof (complex_t));
++    if (state->pre1 == NULL)
++        goto fail;
++
++    state->post1 = memalign (16, 64 * sizeof (complex_t));
++    if (state->post1 == NULL)
++        goto fail;
++
++    state->pre2 = memalign (16, 64 * sizeof (complex_t));
++    if (state->pre2 == NULL)
++        goto fail;
++
++    state->post2 = memalign (16, 32 * sizeof (complex_t));
++    if (state->post2 == NULL)
++        goto fail;
++
++    state->a52_imdct_window = memalign (16, 256 * sizeof (sample_t));
++    if (state->a52_imdct_window == NULL)
++        goto fail;
++
+     for (i = 0; i < 256 * 12; i++)
+ 	state->samples[i] = 0;
+ 
+@@ -73,9 +110,27 @@
+ 
+     state->lfsr_state = 1;
+ 
+-    a52_imdct_init (mm_accel);
++    a52_imdct_init (state, mm_accel);
+ 
+     return state;
++
++fail:
++    if ( state )
++    {
++        free (state->a52_imdct_window);
++        free (state->post2);
++        free (state->pre2);
++        free (state->post1);
++        free (state->pre1);
++        free (state->roots128);
++        free (state->roots64);
++        free (state->roots32);
++        free (state->roots16);
++        free (state->samples);
++        free (state);
++    }
++    return NULL;
++
+ }
+ 
+ sample_t * a52_samples (a52_state_t * state)
+@@ -825,7 +880,7 @@
+ 		       state->dynrng, 0, 7);
+ 	    for (i = 7; i < 256; i++)
+ 		(samples-256)[i] = 0;
+-	    a52_imdct_512 (samples - 256, samples + 1536 - 256, state->bias);
++	    a52_imdct_512 (state, samples - 256, samples + 1536 - 256, state->bias);
+ 	} else {
+ 	    /* just skip the LFE coefficients */
+ 	    coeff_get (state, samples + 1280, &state->lfe_expbap, &quantizer,
+@@ -854,10 +909,10 @@
+ 
+ 	    if (coeff[i]) {
+ 		if (blksw[i])
+-		    a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
++		    a52_imdct_256 (state, samples + 256 * i, samples + 1536 + 256 * i,
+ 				   bias);
+ 		else 
+-		    a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
++		    a52_imdct_512 (state, samples + 256 * i, samples + 1536 + 256 * i,
+ 				   bias);
+ 	    } else {
+ 		int j;
+@@ -883,11 +938,11 @@
+ 
+ 	if (blksw[0])
+ 	    for (i = 0; i < nfchans; i++)
+-		a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
++		a52_imdct_256 (state, samples + 256 * i, samples + 1536 + 256 * i,
+ 			       state->bias);
+ 	else 
+ 	    for (i = 0; i < nfchans; i++)
+-		a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
++		a52_imdct_512 (state, samples + 256 * i, samples + 1536 + 256 * i,
+ 			       state->bias);
+     }
+ 
+@@ -896,6 +951,15 @@
+ 
+ void a52_free (a52_state_t * state)
+ {
++    free (state->a52_imdct_window);
++    free (state->post2);
++    free (state->pre2);
++    free (state->post1);
++    free (state->pre1);
++    free (state->roots128);
++    free (state->roots64);
++    free (state->roots32);
++    free (state->roots16);
+     free (state->samples);
+     free (state);
+ }
diff --git a/pkgs/development/libraries/a52dec/A02-imdct-shutup.patch b/pkgs/development/libraries/a52dec/A02-imdct-shutup.patch
new file mode 100644
index 00000000000..a22e5979e66
--- /dev/null
+++ b/pkgs/development/libraries/a52dec/A02-imdct-shutup.patch
@@ -0,0 +1,11 @@
+diff -Naur a52dec_original/liba52/imdct.c a52dec_patched/liba52/imdct.c
+--- 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
+     {
+-	fprintf (stderr, "No accelerated IMDCT transform found\n");
+ 	ifft128 = ifft128_c;
+ 	ifft64 = ifft64_c;
+     }
diff --git a/pkgs/development/libraries/a52dec/A03-automake.patch b/pkgs/development/libraries/a52dec/A03-automake.patch
new file mode 100644
index 00000000000..142091dc695
--- /dev/null
+++ b/pkgs/development/libraries/a52dec/A03-automake.patch
@@ -0,0 +1,12 @@
+diff -Naur a52dec.orig/configure.in a52dec/configure.in
+--- a52dec.orig/configure.in	2002-07-27 23:50:20.000000000 -0400
++++ a52dec/configure.in	2013-01-28 21:06:27.000000000 -0500
+@@ -6,7 +6,7 @@
+ AC_CONFIG_FILES([Makefile autotools/Makefile include/Makefile test/Makefile
+     doc/Makefile src/Makefile liba52/Makefile libao/Makefile vc++/Makefile])
+ AM_INIT_AUTOMAKE([a52dec],[0.7.4])
+-AM_CONFIG_HEADER(include/config.h)
++AC_CONFIG_HEADER(include/config.h)
+ AM_MAINTAINER_MODE
+ AC_CANONICAL_HOST
+ 
diff --git a/pkgs/development/libraries/a52dec/default.nix b/pkgs/development/libraries/a52dec/default.nix
index 84a87df03e4..7d5c5fab393 100644
--- a/pkgs/development/libraries/a52dec/default.nix
+++ b/pkgs/development/libraries/a52dec/default.nix
@@ -1,7 +1,7 @@
 {stdenv, fetchurl}:
 
 stdenv.mkDerivation rec {
-  name = "a52dec-0.7.4";
+  name = "a52dec-0.7.4p4";
   
   src = fetchurl {
     url = "${meta.homepage}/files/a52dec-0.7.4.tar.gz";
@@ -10,6 +10,14 @@ stdenv.mkDerivation rec {
 
   NIX_CFLAGS_COMPILE = "-fpic";
 
+  # From Handbrake
+  patches = [
+    ./A00-a52-state-t-public.patch
+    ./A01-thread-safe.patch
+    ./A02-imdct-shutup.patch
+    ./A03-automake.patch
+  ];
+
   meta = {
     description = "ATSC A/52 stream decoder";
     homepage = http://liba52.sourceforge.net/;