summaryrefslogtreecommitdiff
path: root/libavcodec/zmbvenc.c
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2009-11-20 07:22:41 +0000
committerKostya Shishkov <kostya.shishkov@gmail.com>2009-11-20 07:22:41 +0000
commitdd562761d95148c52e4be6d6b516407abf1815ee (patch)
tree938fe071000655923ec3b98e074ca97e2286027e /libavcodec/zmbvenc.c
parentcb893cf38662d9c532de41e0fd03d0fdd992a557 (diff)
10l trocadero: ZMBV encoder used zero score to detect whether block should be
XORed with source one or not, which went wrong with new block comparing code. So track this condition explicitly. Originally committed as revision 20558 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/zmbvenc.c')
-rw-r--r--libavcodec/zmbvenc.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index 0131b5d1f3..d3838904cc 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -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];