summaryrefslogtreecommitdiff
path: root/libavcodec/ac3dec_fixed.c
diff options
context:
space:
mode:
authorJean-Francois Thibert <jfthibert@google.com>2014-08-26 19:16:06 -0400
committerMichael Niedermayer <michaelni@gmx.at>2014-08-27 14:31:39 +0200
commit12df9b9a151026c4b382df8852fad38165b49f95 (patch)
tree5b2f03eae9dc3e3eb44cdb0b1cd930a5d0e03012 /libavcodec/ac3dec_fixed.c
parent7a67ab5cba8ed5509be5d058fe9e5612ef39d3b0 (diff)
Improved AC3 decoder level support (heavy drc, dialnorm)
Added support for AC3 heavy dynamic range compression used to restrict the output range and added a setting to specify the output target level and use the dialog normalization field to apply it in the digital domain. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/ac3dec_fixed.c')
-rw-r--r--libavcodec/ac3dec_fixed.c99
1 files changed, 65 insertions, 34 deletions
diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c
index c6cbeb9b28..f36e7b0849 100644
--- a/libavcodec/ac3dec_fixed.c
+++ b/libavcodec/ac3dec_fixed.c
@@ -81,40 +81,69 @@ static void scale_coefs (
int temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
mul = (dynrng & 0x1f) + 0x20;
- shift = 4 - ((dynrng << 24) >> 29);
- round = 1 << (shift-1);
- for (i=0; i<len; i+=8) {
-
- temp = src[i] * mul;
- temp1 = src[i+1] * mul;
- temp = temp + round;
- temp2 = src[i+2] * mul;
-
- temp1 = temp1 + round;
- dst[i] = temp >> shift;
- temp3 = src[i+3] * mul;
- temp2 = temp2 + round;
-
- dst[i+1] = temp1 >> shift;
- temp4 = src[i + 4] * mul;
- temp3 = temp3 + round;
- dst[i+2] = temp2 >> shift;
-
- temp5 = src[i+5] * mul;
- temp4 = temp4 + round;
- dst[i+3] = temp3 >> shift;
- temp6 = src[i+6] * mul;
-
- dst[i+4] = temp4 >> shift;
- temp5 = temp5 + round;
- temp7 = src[i+7] * mul;
- temp6 = temp6 + round;
-
- dst[i+5] = temp5 >> shift;
- temp7 = temp7 + round;
- dst[i+6] = temp6 >> shift;
- dst[i+7] = temp7 >> shift;
-
+ shift = 4 - ((dynrng << 23) >> 28);
+ if (shift > 0 ) {
+ round = 1 << (shift-1);
+ for (i=0; i<len; i+=8) {
+
+ temp = src[i] * mul;
+ temp1 = src[i+1] * mul;
+ temp = temp + round;
+ temp2 = src[i+2] * mul;
+
+ temp1 = temp1 + round;
+ dst[i] = temp >> shift;
+ temp3 = src[i+3] * mul;
+ temp2 = temp2 + round;
+
+ dst[i+1] = temp1 >> shift;
+ temp4 = src[i + 4] * mul;
+ temp3 = temp3 + round;
+ dst[i+2] = temp2 >> shift;
+
+ temp5 = src[i+5] * mul;
+ temp4 = temp4 + round;
+ dst[i+3] = temp3 >> shift;
+ temp6 = src[i+6] * mul;
+
+ dst[i+4] = temp4 >> shift;
+ temp5 = temp5 + round;
+ temp7 = src[i+7] * mul;
+ temp6 = temp6 + round;
+
+ dst[i+5] = temp5 >> shift;
+ temp7 = temp7 + round;
+ dst[i+6] = temp6 >> shift;
+ dst[i+7] = temp7 >> shift;
+
+ }
+ } else {
+ shift = -shift;
+ for (i=0; i<len; i+=8) {
+
+ temp = src[i] * mul;
+ temp1 = src[i+1] * mul;
+ temp2 = src[i+2] * mul;
+
+ dst[i] = temp << shift;
+ temp3 = src[i+3] * mul;
+
+ dst[i+1] = temp1 << shift;
+ temp4 = src[i + 4] * mul;
+ dst[i+2] = temp2 << shift;
+
+ temp5 = src[i+5] * mul;
+ dst[i+3] = temp3 << shift;
+ temp6 = src[i+6] * mul;
+
+ dst[i+4] = temp4 << shift;
+ temp7 = src[i+7] * mul;
+
+ dst[i+5] = temp5 << shift;
+ dst[i+6] = temp6 << shift;
+ dst[i+7] = temp7 << shift;
+
+ }
}
}
@@ -150,6 +179,8 @@ static void ac3_downmix_c_fixed16(int16_t **samples, int16_t (*matrix)[2],
#include "ac3dec.c"
static const AVOption options[] = {
+ { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR },
+ { "heavy_compr", "heavy dynamic range compression enabled", OFFSET(heavy_compression), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, PAR },
{ NULL},
};