Commit 2d80b56c authored by Matthew Fearnley's avatar Matthew Fearnley Committed by Tomas Härdin

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
parent ff034183
...@@ -55,7 +55,7 @@ typedef struct ZmbvEncContext { ...@@ -55,7 +55,7 @@ typedef struct ZmbvEncContext {
int keyint, curfrm; int keyint, curfrm;
z_stream zstream; z_stream zstream;
int score_tab[256]; int score_tab[ZMBV_BLOCK * ZMBV_BLOCK + 1];
} ZmbvEncContext; } ZmbvEncContext;
...@@ -69,20 +69,26 @@ static inline int block_cmp(ZmbvEncContext *c, uint8_t *src, int stride, ...@@ -69,20 +69,26 @@ static inline int block_cmp(ZmbvEncContext *c, uint8_t *src, int stride,
{ {
int sum = 0; int sum = 0;
int i, j; 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(j = 0; j < bh; j++){
for(i = 0; i < bw; i++){ for(i = 0; i < bw; i++){
int t = src[i] ^ src2[i]; int t = src[i] ^ src2[i];
histogram[t]++; histogram[t]++;
*xored |= t;
} }
src += stride; src += stride;
src2 += stride2; 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]]; sum += c->score_tab[histogram[i]];
return sum; return sum;
...@@ -278,7 +284,11 @@ static av_cold int encode_init(AVCodecContext *avctx) ...@@ -278,7 +284,11 @@ static av_cold int encode_init(AVCodecContext *avctx)
int i; int i;
int lvl = 9; 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->score_tab[i] = -i * log2(i / (double)(ZMBV_BLOCK * ZMBV_BLOCK)) * 256;
c->avctx = avctx; c->avctx = avctx;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment