[FFmpeg-devel] CNG (consistent noise generation) patch for AC-3 decoder
Jonathan Campbell
jonathan at impactstudiopro.com
Sat Sep 3 13:50:33 EEST 2016
On 09/02/2016 05:35 PM, Michael Niedermayer wrote:
> On Fri, Sep 02, 2016 at 05:31:35PM -0700, Jonathan Campbell wrote:
>>> should be in a different patch
>>> also needs minor version bump and APIChanges update
>>>
>>> also please generate patches with git format-patch or git send-email
>>> see the respective man pages
>>> (otherwise they woul be lacking commit messages)
>>>
>>> thx
>>>
>>> [...]
>>>
>>>
>>>
>>> _______________________________________________
>>> ffmpeg-devel mailing list
>>> ffmpeg-devel at ffmpeg.org
>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>> One patch for the new function in lfg.c, and another patch to use
>> the addition in the ac3 decoder, right? I can do that.
>
> yes
>
>
>>
>> The version minor bump would bring libavutil 55.30.100 (or should it
>> be 55.30.0?). I'll format the patch correctly.
>
> 55.30.100
>
> thx
>
> [...]
>
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Here you go (as attachments).
Jonathan Campbell
-------------- next part --------------
From 5de30d309fb48b26acd8d95f14ef4d4064450ddc Mon Sep 17 00:00:00 2001
From: Jonathan Campbell <jonathan at castus.tv>
Date: Sat, 3 Sep 2016 03:20:41 -0700
Subject: [PATCH 1/3] libavutil version bump, av_lfg_init_from_data() incoming
---
libavutil/version.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavutil/version.h b/libavutil/version.h
index 7d32c7b..60b58eb 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 55
-#define LIBAVUTIL_VERSION_MINOR 29
+#define LIBAVUTIL_VERSION_MINOR 30
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
--
2.2.2
-------------- next part --------------
From 3cc9a0e4a8bae127ca9254f31cd8b7f00d107395 Mon Sep 17 00:00:00 2001
From: Jonathan Campbell <jonathan at castus.tv>
Date: Sat, 3 Sep 2016 03:29:29 -0700
Subject: [PATCH 2/3] libavutil av_lfg_init_from_data() function
seeds an AVLFG from binary data.
---
libavutil/lfg.c | 27 +++++++++++++++++++++++++++
libavutil/lfg.h | 9 +++++++++
2 files changed, 36 insertions(+)
diff --git a/libavutil/lfg.c b/libavutil/lfg.c
index 08a4f67..0ef456a 100644
--- a/libavutil/lfg.c
+++ b/libavutil/lfg.c
@@ -23,7 +23,9 @@
#include <limits.h>
#include <math.h>
#include "lfg.h"
+#include "crc.h"
#include "md5.h"
+#include "error.h"
#include "intreadwrite.h"
#include "attributes.h"
@@ -58,3 +60,28 @@ void av_bmg_get(AVLFG *lfg, double out[2])
out[0] = x1 * w;
out[1] = x2 * w;
}
+
+int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length) {
+ unsigned int beg, end, segm;
+ const AVCRC *avcrc;
+ uint32_t crc = 1;
+
+ c->index = 0;
+ avcrc = av_crc_get_table(AV_CRC_32_IEEE); /* This can't fail. It's a well-defined table in crc.c */
+
+ /* avoid integer overflow in the loop below. */
+ if (length > (UINT_MAX / 128U)) return AVERROR(EINVAL);
+
+ /* across 64 segments of the incoming data,
+ * do a running crc of each segment and store the crc as the state for that slot.
+ * this works even if the length of the segment is 0 bytes. */
+ beg = 0;
+ for (segm = 0;segm < 64;segm++) {
+ end = (((segm + 1) * length) / 64);
+ crc = av_crc(avcrc, crc, data + beg, end - beg);
+ c->state[segm] = (unsigned int)crc;
+ beg = end;
+ }
+
+ return 0;
+}
diff --git a/libavutil/lfg.h b/libavutil/lfg.h
index ec90562..72eb673 100644
--- a/libavutil/lfg.h
+++ b/libavutil/lfg.h
@@ -22,6 +22,8 @@
#ifndef AVUTIL_LFG_H
#define AVUTIL_LFG_H
+#include <stdint.h> /* uint8_t type */
+
typedef struct AVLFG {
unsigned int state[64];
int index;
@@ -29,6 +31,13 @@ typedef struct AVLFG {
void av_lfg_init(AVLFG *c, unsigned int seed);
+/*
+ * Seed the state of the ALFG using binary data.
+ *
+ * Return value: 0 on success, negative value (AVERROR) on failure.
+ */
+int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length);
+
/**
* Get the next random unsigned 32-bit number using an ALFG.
*
--
2.2.2
-------------- next part --------------
From eb8b354c5edf9c876f3e4a209ec617500776fcf2 Mon Sep 17 00:00:00 2001
From: Jonathan Campbell <jonathan at castus.tv>
Date: Sat, 3 Sep 2016 03:34:01 -0700
Subject: [PATCH 3/3] ac3dec consistent noise generation option.
use av_lfg_init_from_data() to seed AC-3 dithering from the AC-3 frame
data to make it consistent given the same AC-3 frame, if option is set.
---
libavcodec/ac3dec.c | 7 +++++++
libavcodec/ac3dec.h | 4 ++++
libavcodec/ac3dec_fixed.c | 1 +
libavcodec/ac3dec_float.c | 1 +
4 files changed, 13 insertions(+)
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index fac189b..18a674b 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -1419,6 +1419,13 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
(const uint16_t *) buf, cnt);
} else
memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));
+
+ /* if consistent noise generation is enabled, seed the linear feedback generator
+ * with the contents of the AC-3 frame so that the noise is identical across
+ * decodes given the same AC-3 frame data, for use with non-linear edititing software. */
+ if (s->consistent_noise_generation)
+ av_lfg_init_from_data(&s->dith_state, s->input_buffer, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));
+
buf = s->input_buffer;
/* initialize the GetBitContext with the start of valid AC-3 Frame */
if ((ret = init_get_bits8(&s->gbc, buf, buf_size)) < 0)
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index c2b867e..98184e9 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -177,6 +177,10 @@ typedef struct AC3DecodeContext {
int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant)
///@}
+///@name Consistent noise generation
+ int consistent_noise_generation; ///< seed noise generation with AC-3 frame on decode
+///@}
+
///@name Rematrixing
int num_rematrixing_bands; ///< number of rematrixing bands (nrematbnd)
int rematrixing_flags[4]; ///< rematrixing flags (rematflg)
diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c
index 6416da4..1f79ade 100644
--- a/libavcodec/ac3dec_fixed.c
+++ b/libavcodec/ac3dec_fixed.c
@@ -168,6 +168,7 @@ static void ac3_downmix_c_fixed16(int16_t **samples, int16_t (*matrix)[2],
#include "ac3dec.c"
static const AVOption options[] = {
+ { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
{ "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", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
{ NULL},
diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c
index 0a5319a..b85a4ce 100644
--- a/libavcodec/ac3dec_float.c
+++ b/libavcodec/ac3dec_float.c
@@ -32,6 +32,7 @@
#include "ac3dec.c"
static const AVOption options[] = {
+ { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
{ "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", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
{ "target_level", "target level in -dBFS (0 not applied)", OFFSET(target_level), AV_OPT_TYPE_INT, {.i64 = 0 }, -31, 0, PAR },
--
2.2.2
More information about the ffmpeg-devel
mailing list