|
|
@@ -61,15 +61,19 @@ static int score_tab[256]; |
|
|
|
* XXX should be optimized and moved to DSPContext |
|
|
|
* TODO handle out of edge ME |
|
|
|
*/ |
|
|
|
static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, int bw, int bh) |
|
|
|
static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, int bw, int bh, int *xored) |
|
|
|
{ |
|
|
|
int sum = 0; |
|
|
|
int i, j; |
|
|
|
uint8_t histogram[256]={0}; |
|
|
|
|
|
|
|
*xored = 0; |
|
|
|
for(j = 0; j < bh; j++){ |
|
|
|
for(i = 0; i < bw; i++) |
|
|
|
histogram[src[i] ^ src2[i]]++; |
|
|
|
for(i = 0; i < bw; i++){ |
|
|
|
int t = src[i] ^ src2[i]; |
|
|
|
histogram[t]++; |
|
|
|
*xored |= t; |
|
|
|
} |
|
|
|
src += stride; |
|
|
|
src2 += stride2; |
|
|
|
} |
|
|
@@ -84,21 +88,21 @@ static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2 |
|
|
|
* TODO make better ME decisions |
|
|
|
*/ |
|
|
|
static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, int pstride, |
|
|
|
int x, int y, int *mx, int *my) |
|
|
|
int x, int y, int *mx, int *my, int *xored) |
|
|
|
{ |
|
|
|
int dx, dy, tx, ty, tv, bv, bw, bh; |
|
|
|
|
|
|
|
*mx = *my = 0; |
|
|
|
bw = FFMIN(ZMBV_BLOCK, c->avctx->width - x); |
|
|
|
bh = FFMIN(ZMBV_BLOCK, c->avctx->height - y); |
|
|
|
bv = block_cmp(src, sstride, prev, pstride, bw, bh); |
|
|
|
bv = block_cmp(src, sstride, prev, pstride, bw, bh, xored); |
|
|
|
if(!bv) return 0; |
|
|
|
for(ty = FFMAX(y - c->range, 0); ty < FFMIN(y + c->range, c->avctx->height - bh); ty++){ |
|
|
|
for(tx = FFMAX(x - c->range, 0); tx < FFMIN(x + c->range, c->avctx->width - bw); tx++){ |
|
|
|
if(tx == x && ty == y) continue; // we already tested this block |
|
|
|
dx = tx - x; |
|
|
|
dy = ty - y; |
|
|
|
tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh); |
|
|
|
tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh, xored); |
|
|
|
if(tv < bv){ |
|
|
|
bv = tv; |
|
|
|
*mx = dx; |
|
|
@@ -173,7 +177,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void |
|
|
|
work_size += avctx->width; |
|
|
|
} |
|
|
|
}else{ |
|
|
|
int x, y, bh2, bw2; |
|
|
|
int x, y, bh2, bw2, xored; |
|
|
|
uint8_t *tsrc, *tprev; |
|
|
|
uint8_t *mv; |
|
|
|
int mx, my, bv; |
|
|
@@ -192,11 +196,11 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void |
|
|
|
tsrc = src + x; |
|
|
|
tprev = prev + x; |
|
|
|
|
|
|
|
bv = zmbv_me(c, tsrc, p->linesize[0], tprev, c->pstride, x, y, &mx, &my); |
|
|
|
mv[0] = (mx << 1) | !!bv; |
|
|
|
bv = zmbv_me(c, tsrc, p->linesize[0], tprev, c->pstride, x, y, &mx, &my, &xored); |
|
|
|
mv[0] = (mx << 1) | !!xored; |
|
|
|
mv[1] = my << 1; |
|
|
|
tprev += mx + my * c->pstride; |
|
|
|
if(bv){ |
|
|
|
if(xored){ |
|
|
|
for(j = 0; j < bh2; j++){ |
|
|
|
for(i = 0; i < bw2; i++) |
|
|
|
c->work_buf[work_size++] = tsrc[i] ^ tprev[i]; |
|
|
|