diff options
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/random_seed.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c index 4680081..26884cb 100644 --- a/libavutil/random_seed.c +++ b/libavutil/random_seed.c @@ -31,8 +31,11 @@ #include <math.h> #include <time.h> #include "internal.h" +#include "intreadwrite.h" +#include "mem.h" #include "timer.h" #include "random_seed.h" +#include "sha.h" static int read_random(uint32_t *dst, const char *file) { @@ -53,34 +56,40 @@ static int read_random(uint32_t *dst, const char *file) static uint32_t get_generic_seed(void) { + struct AVSHA *sha = av_sha_alloc(); clock_t last_t = 0; - int bits = 0; - uint64_t random = 0; - unsigned i; - float s = 0.000000000001; + static uint64_t i = 0; + static uint32_t buffer[512] = { 0 }; + unsigned char digest[20]; + uint64_t last_i = i; - for (i = 0; bits < 64; i++) { + for (;;) { clock_t t = clock(); - if (last_t && fabs(t - last_t) > s || t == (clock_t) -1) { - if (i < 10000 && s < (1 << 24)) { - s += s; - i = t = 0; - } else { - random = 2 * random + (i & 1); - bits++; - } + + if (last_t == t) { + buffer[i & 511]++; + } else { + buffer[++i & 511] += (t - last_t) % 3294638521U; + if (last_i && i - last_i > 4 || i - last_i > 64) + break; } last_t = t; } -#ifdef AV_READ_TIME - random ^= AV_READ_TIME(); -#else - random ^= clock(); -#endif - random += random >> 32; - - return random; + if (!sha) { + uint32_t seed = 0; + int j; + // Unable to allocate an sha context, just xor the buffer together + // to create something hopefully unique. + for (j = 0; j < 512; j++) + seed ^= buffer[j]; + return seed; + } + av_sha_init(sha, 160); + av_sha_update(sha, (const uint8_t *) buffer, sizeof(buffer)); + av_sha_final(sha, digest); + av_free(sha); + return AV_RB32(digest) + AV_RB32(digest + 16); } uint32_t av_get_random_seed(void) |