Message ID | 57C8DD12.7030104@impactstudiopro.com |
---|---|
State | Superseded |
Headers | show |
On Thu, Sep 01, 2016 at 06:59:46PM -0700, Jonathan Campbell 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 <jonathan@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)); patch looks newline garbled [...]
On 09/01/2016 07:13 PM, Michael Niedermayer wrote: > On Thu, Sep 01, 2016 at 06:59:46PM -0700, Jonathan Campbell 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 <jonathan@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)); > patch looks newline garbled > > [...] > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Yeah, figured that would happen. Can you accept patches directly from Github? https://github.com/joncampbell123/FFmpeg/commit/dbd086586f0ad1591ea2013293bbb6e4dbfd0455.patch Jonathan Campbell
On 09/01/2016 07:13 PM, Michael Niedermayer wrote: > On Thu, Sep 01, 2016 at 06:59:46PM -0700, Jonathan Campbell 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 <jonathan@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)); > patch looks newline garbled > > [...] > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Figured that would happen. Can you accept patches directly from Github? https://github.com/joncampbell123/FFmpeg/commit/dbd086586f0ad1591ea2013293bbb6e4dbfd0455.patch Jonathan Campbell
On Thu, Sep 01, 2016 at 06:59:46PM -0700, Jonathan Campbell 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 <jonathan@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))); av_lfg_init involves md5 which is slow and not apropriate to be executed per frame, this would double the time to decode a frame 965641 decicycles in rndint, 64 runs, 0 skips 2375023 decicycles in FRAME, 64 runs, 0 skips write/use a faster way to init the LFG please [...]
CRC computation isn't fast enough? What should I use then? A sum of byte values? Jonathan Campbell CASTUS On 09/02/2016 04:50 AM, Michael Niedermayer wrote: > On Thu, Sep 01, 2016 at 06:59:46PM -0700, Jonathan Campbell 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 <jonathan@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))); > av_lfg_init involves md5 which is slow and not apropriate to be > executed per frame, this would double the time to decode a frame > > 965641 decicycles in rndint, 64 runs, 0 skips > 2375023 decicycles in FRAME, 64 runs, 0 skips > > > write/use a faster way to init the LFG please > > > [...] > > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
On 09/02/2016 04:50 AM, Michael Niedermayer wrote: > On Thu, Sep 01, 2016 at 06:59:46PM -0700, Jonathan Campbell 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 <jonathan@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))); > av_lfg_init involves md5 which is slow and not apropriate to be > executed per frame, this would double the time to decode a frame > > 965641 decicycles in rndint, 64 runs, 0 skips > 2375023 decicycles in FRAME, 64 runs, 0 skips > > > write/use a faster way to init the LFG please > > > [...] > > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel (sorry..) CRC computation isn't fast enough? What should I use then? A sum of byte values? Jonathan Campbell CASTUS
On Fri, Sep 02, 2016 at 10:19:23AM -0700, Jonathan Campbell wrote: [...] > CRC computation isn't fast enough? What should I use then? A sum of > byte values? av_lfg_init() calls av_md5_sum() av_md5_sum() is too slow to be called per ac3 frame [...]
On 09/02/2016 01:01 PM, Michael Niedermayer wrote: > On Fri, Sep 02, 2016 at 10:19:23AM -0700, Jonathan Campbell wrote: > [...] >> CRC computation isn't fast enough? What should I use then? A sum of >> byte values? > av_lfg_init() calls av_md5_sum() > av_md5_sum() is too slow to be called per ac3 frame > > [...] > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Then for this to work at better performance, I'm going to have to either directly modify the AVLFG struct state (probably not a good idea), or add a function to libavutil/lfg.c that allows "fast seeding" without the use of MD5 which could probably be something as simple as copy the 32-bit seed 16 times through c->state[] with or without modification during the loop. Sound good? Jonathan Campbell CASTUS
On Fri, Sep 02, 2016 at 01:13:33PM -0700, Jonathan Campbell wrote: > > On 09/02/2016 01:01 PM, Michael Niedermayer wrote: > >On Fri, Sep 02, 2016 at 10:19:23AM -0700, Jonathan Campbell wrote: > >[...] > >>CRC computation isn't fast enough? What should I use then? A sum of > >>byte values? > >av_lfg_init() calls av_md5_sum() > >av_md5_sum() is too slow to be called per ac3 frame > > > >[...] > > > > > >_______________________________________________ > >ffmpeg-devel mailing list > >ffmpeg-devel@ffmpeg.org > >http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > Then for this to work at better performance, I'm going to have to > either directly modify the AVLFG struct state (probably not a good > idea), or add a function to libavutil/lfg.c that allows "fast > seeding" without the use of MD5 which could probably be something as > simple as copy the 32-bit seed 16 times through c->state[] with or > without modification during the loop. Sound good? yes, something like this probably spliting the input into 16 parts get 16 CRCs and use them instead of replication is probably better [...]
On 09/02/2016 01:56 PM, Michael Niedermayer wrote: > On Fri, Sep 02, 2016 at 01:13:33PM -0700, Jonathan Campbell wrote: >> On 09/02/2016 01:01 PM, Michael Niedermayer wrote: >>> On Fri, Sep 02, 2016 at 10:19:23AM -0700, Jonathan Campbell wrote: >>> [...] >>>> CRC computation isn't fast enough? What should I use then? A sum of >>>> byte values? >>> av_lfg_init() calls av_md5_sum() >>> av_md5_sum() is too slow to be called per ac3 frame >>> >>> [...] >>> >>> >>> _______________________________________________ >>> ffmpeg-devel mailing list >>> ffmpeg-devel@ffmpeg.org >>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> Then for this to work at better performance, I'm going to have to >> either directly modify the AVLFG struct state (probably not a good >> idea), or add a function to libavutil/lfg.c that allows "fast >> seeding" without the use of MD5 which could probably be something as >> simple as copy the 32-bit seed 16 times through c->state[] with or >> without modification during the loop. Sound good? > yes, something like this > probably spliting the input into 16 parts get 16 CRCs and use them > instead of replication is probably better > > > [...] > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel How's this: void av_lfg_init_from_data(AVLFG *c, const unsigned char *data, unsigned int length) { unsigned int beg, end, segm; const AVCRC *avcrc; uint32_t crc = 0; avcrc = av_crc_get_table(AV_CRC_32_IEEE); if (avcrc == NULL) return; /* try to avoid integer overflow during the segmented crc loop below. * the code below would break if "end" went backwards before "beg". */ if (length > (UINT_MAX / 128U)) return; /* across 64 pieces 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 piece 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; } } I also realize that c->state[] is an array of 64 unsigned ints, not 64 bytes. A running CRC over the data is used to fill in all 64 slots of the LFG. This code should work correctly even if any one of the 64 "slots" is computed from 0 bytes of the source (when length < 64). Jonathan Campbell
On Fri, Sep 02, 2016 at 04:05:44PM -0700, Jonathan Campbell wrote: > > On 09/02/2016 01:56 PM, Michael Niedermayer wrote: > >On Fri, Sep 02, 2016 at 01:13:33PM -0700, Jonathan Campbell wrote: > >>On 09/02/2016 01:01 PM, Michael Niedermayer wrote: > >>>On Fri, Sep 02, 2016 at 10:19:23AM -0700, Jonathan Campbell wrote: > >>>[...] > >>>>CRC computation isn't fast enough? What should I use then? A sum of > >>>>byte values? > >>>av_lfg_init() calls av_md5_sum() > >>>av_md5_sum() is too slow to be called per ac3 frame > >>> > >>>[...] > >>> > >>> > >>>_______________________________________________ > >>>ffmpeg-devel mailing list > >>>ffmpeg-devel@ffmpeg.org > >>>http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > >>Then for this to work at better performance, I'm going to have to > >>either directly modify the AVLFG struct state (probably not a good > >>idea), or add a function to libavutil/lfg.c that allows "fast > >>seeding" without the use of MD5 which could probably be something as > >>simple as copy the 32-bit seed 16 times through c->state[] with or > >>without modification during the loop. Sound good? > >yes, something like this > >probably spliting the input into 16 parts get 16 CRCs and use them > >instead of replication is probably better > > > > > >[...] > > > > > >_______________________________________________ > >ffmpeg-devel mailing list > >ffmpeg-devel@ffmpeg.org > >http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > How's this: > > void av_lfg_init_from_data(AVLFG *c, const unsigned char *data, > unsigned int length) { > unsigned int beg, end, segm; > const AVCRC *avcrc; > uint32_t crc = 0; 1 might be better should be ok otherwise didnt review it deeply though [...]
On 2 September 2016 at 02:59, Jonathan Campbell < jonathan@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 <jonathan@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. What is the point of this patch?
On 09/03/2016 01:32 PM, Rostislav Pehlivanov wrote: > On 2 September 2016 at 02:59, Jonathan Campbell < > jonathan@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 <jonathan@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
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",