[FFmpeg-devel] CNG (consistent noise generation) patch for AC-3 decoder

Jonathan Campbell jonathan at impactstudiopro.com
Sat Sep 3 02:05:44 EEST 2016


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 at 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 at 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



More information about the ffmpeg-devel mailing list