[FFmpeg-devel] [PATCH 1/2] aacenc: use the decoder's lcg PRNG

Rostislav Pehlivanov atomnuker at gmail.com
Sat Oct 8 18:20:30 EEST 2016


Using lfg was an overkill in this case where the random numbers
were only used for encoder descisions. Should increase result
uniformity between different FPUs and gives a slight speedup.

Signed-off-by: Rostislav Pehlivanov <atomnuker at gmail.com>
---
 libavcodec/aaccoder.c     |  8 +++-----
 libavcodec/aacenc.c       |  2 +-
 libavcodec/aacenc.h       |  2 --
 libavcodec/aacenc_utils.h | 13 +++++++++++++
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index 284b401..35787e8 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -643,11 +643,9 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne
                 float band_energy, scale, pns_senergy;
                 const int start_c = (w+w2)*128+sce->ics.swb_offset[g];
                 band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
-                for (i = 0; i < sce->ics.swb_sizes[g]; i+=2) {
-                    double rnd[2];
-                    av_bmg_get(&s->lfg, rnd);
-                    PNS[i+0] = (float)rnd[0];
-                    PNS[i+1] = (float)rnd[1];
+                for (i = 0; i < sce->ics.swb_sizes[g]; i++) {
+                    s->random_state  = lcg_random(s->random_state);
+                    PNS[i] = s->random_state;
                 }
                 band_energy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]);
                 scale = noise_amp/sqrtf(band_energy);
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 9e421a9..ee3cbf8 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -1031,7 +1031,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
         goto fail;
     s->psypp = ff_psy_preprocess_init(avctx);
     ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON);
-    av_lfg_init(&s->lfg, 0x72adca55);
+    s->random_state = 0x1f2e3d4c;
 
     if (HAVE_MIPSDSP)
         ff_aac_coder_init_mips(s);
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 63e7893..1ace00d 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -23,7 +23,6 @@
 #define AVCODEC_AACENC_H
 
 #include "libavutil/float_dsp.h"
-#include "libavutil/lfg.h"
 #include "avcodec.h"
 #include "put_bits.h"
 
@@ -100,7 +99,6 @@ typedef struct AACEncContext {
     FFTContext mdct1024;                         ///< long (1024 samples) frame transform context
     FFTContext mdct128;                          ///< short (128 samples) frame transform context
     AVFloatDSPContext *fdsp;
-    AVLFG lfg;                                   ///< PRNG needed for PNS
     float *planar_samples[8];                    ///< saved preprocessed input
 
     int profile;                                 ///< copied from avctx
diff --git a/libavcodec/aacenc_utils.h b/libavcodec/aacenc_utils.h
index bb1dcb4..ff9188a 100644
--- a/libavcodec/aacenc_utils.h
+++ b/libavcodec/aacenc_utils.h
@@ -252,6 +252,19 @@ static inline int ff_sfdelta_can_replace(const SingleChannelElement *sce,
         && sce->sf_idx[nextband[band]] <= (new_sf + SCALE_MAX_DIFF);
 }
 
+/**
+ * linear congruential pseudorandom number generator
+ *
+ * @param   previous_val    pointer to the current state of the generator
+ *
+ * @return  Returns a 32-bit pseudorandom integer
+ */
+static av_always_inline int lcg_random(unsigned previous_val)
+{
+    union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
+    return v.s;
+}
+
 #define ERROR_IF(cond, ...) \
     if (cond) { \
         av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \
-- 
2.9.3



More information about the ffmpeg-devel mailing list