summaryrefslogtreecommitdiff
path: root/libavcodec/zmbvenc.c
diff options
context:
space:
mode:
authorMatthew Fearnley <matthew.w.fearnley@gmail.com>2019-02-09 13:10:20 +0000
committerTomas Härdin <tjoppen@acc.umu.se>2019-02-19 21:25:14 +0100
commit2d80b56ce0d4bf545aeecfcc3b71f2bb2aeb3c9e (patch)
tree09429848361f0c2a01676e5aff6a593ef74208fe /libavcodec/zmbvenc.c
parentff03418348dda5b8353e5fdcf7c7ff75472b6074 (diff)
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
Diffstat (limited to 'libavcodec/zmbvenc.c')
-rw-r--r--libavcodec/zmbvenc.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index 4d9147657d..3df6e724c8 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;