diff options
author | Matthew Fearnley <matthew.w.fearnley@gmail.com> | 2019-02-09 13:10:20 +0000 |
---|---|---|
committer | Tomas Härdin <tjoppen@acc.umu.se> | 2019-02-19 21:25:14 +0100 |
commit | 2d80b56ce0d4bf545aeecfcc3b71f2bb2aeb3c9e (patch) | |
tree | 09429848361f0c2a01676e5aff6a593ef74208fe | |
parent | ff03418348dda5b8353e5fdcf7c7ff75472b6074 (diff) | |
download | ffmpeg-streaming-2d80b56ce0d4bf545aeecfcc3b71f2bb2aeb3c9e.zip ffmpeg-streaming-2d80b56ce0d4bf545aeecfcc3b71f2bb2aeb3c9e.tar.gz |
libavcodec/zmbvenc: block scoring improvements/bug fixes
- Improve block choices by counting 0-bytes in the entropy score
- Make histogram use uint16_t type, to allow byte counts from 16*16
(current block size) up to 255*255 (maximum allowed 8bpp block size)
- Make sure score table is big enough for a full block's worth of bytes
- Calculate *xored without using code in inner loop
-rw-r--r-- | libavcodec/zmbvenc.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c index 4d91476..3df6e72 100644 --- a/libavcodec/zmbvenc.c +++ b/libavcodec/zmbvenc.c @@ -55,7 +55,7 @@ typedef struct ZmbvEncContext { int keyint, curfrm; z_stream zstream; - int score_tab[256]; + int score_tab[ZMBV_BLOCK * ZMBV_BLOCK + 1]; } ZmbvEncContext; @@ -69,20 +69,26 @@ static inline int block_cmp(ZmbvEncContext *c, uint8_t *src, int stride, { int sum = 0; int i, j; - uint8_t histogram[256] = {0}; + uint16_t histogram[256] = {0}; - *xored = 0; + /* Build frequency histogram of byte values for src[] ^ src2[] */ for(j = 0; j < bh; j++){ for(i = 0; i < bw; i++){ int t = src[i] ^ src2[i]; histogram[t]++; - *xored |= t; } src += stride; src2 += stride2; } - for(i = 1; i < 256; i++) + /* If not all the xored values were 0, then the blocks are different */ + *xored = (histogram[0] < bw * bh); + + /* Exit early if blocks are equal */ + if (!*xored) return 0; + + /* Sum the entropy of all values */ + for(i = 0; i < 256; i++) sum += c->score_tab[histogram[i]]; return sum; @@ -278,7 +284,11 @@ static av_cold int encode_init(AVCodecContext *avctx) int i; int lvl = 9; - for(i=1; i<256; i++) + /* Entropy-based score tables for comparing blocks. + * Suitable for blocks up to (ZMBV_BLOCK * ZMBV_BLOCK) bytes. + * Scores are nonnegative, lower is better. + */ + for(i = 1; i <= ZMBV_BLOCK * ZMBV_BLOCK; i++) c->score_tab[i] = -i * log2(i / (double)(ZMBV_BLOCK * ZMBV_BLOCK)) * 256; c->avctx = avctx; |