On 09/03/2016 01:32 PM, Rostislav Pehlivanov wrote:
> On 2 September 2016 at 02:59, Jonathan Campbell <
> jonat...@impactstudiopro.com> wrote:
> 
>> I finished the consistent noise generation patch for AC-3 decoding.
>>
>> Set AVOption "cons_noisegen" to 1 (true) to enable it.
>>
>> Git repository:
>> https://github.com/joncampbell123/FFmpeg.git
>>
>> commit dbd086586f0ad1591ea2013293bbb6e4dbfd0455
>> Author: Jonathan Campbell <jonat...@castus.tv>
>> Date:   Thu Sep 1 18:46:16 2016 -0700
>>
>>     AC-3 consistent noise generation: avopt -cons_noisegen <number>
>>
>>     When -cons_noisegen 1, the linear feedback generator used for AC-3
>>     dithering is seeded with the contents of the AC-3 frame. Seeding from
>>     the AC-3 frame ensures the dithering noise comes out exactly the same
>>     when given the same AC-3 frame data, which can then be used by
>>     non-linear editing software to reliably decode discontinuous segments
>> of
>>     an AC-3 bitstream without gaps or discontinuities.
>>
>> Jonathan Campbell
>>
>> Patch follows, hope Thunderbird doesn't garble it:
>>
>> diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
>> index fac189b..28048d7 100644
>> --- a/libavcodec/ac3dec.c
>> +++ b/libavcodec/ac3dec.c
>> @@ -1419,6 +1419,19 @@ 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) {
>> +        const AVCRC *avcrc = av_crc_get_table(AV_CRC_32_IEEE);
>> +
>> +        if (avcrc != NULL)
>> +            av_lfg_init(&s->dith_state, av_crc(avcrc, 0, s->input_buffer,
>> FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)));
>> +        else
>> +            av_log(avctx, AV_LOG_ERROR, "CNG unable to seed from frame");
>> +    }
>> +
>>      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 },
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
> 
> Any random noise, hardcoded constant or not sill sounds like white noise.
Yes.

> What is the point of this patch?
To make the random noise consistent with the AC-3 frame data given to the 
decoder, so that decoding the same data gives the exact same audio samples. It 
doesn't matter to normal file playback but it does matter to non-linear editing 
software that would want the decoded audio to be consistent for editing 
purposes no matter where or how much it decodes.

Without CNG, the dithering would change the audio slightly every time the same 
audio is decoded and that can cause audible discontinuities between cuts on the 
NLE's timeline even if the audio across the cuts is continuous from one to the 
other. The discontinuities are most noticeable if the AC-3 audio is slowed down 
or encoded at a lower sample rate like 16KHz.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
Jonathan Campbell
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to