[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