Mercurial > libavcodec.hg
comparison zmbvenc.c @ 10543:7ff7a34848bf libavcodec
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.
author | kostya |
---|---|
date | Fri, 20 Nov 2009 07:22:41 +0000 |
parents | d7ed9dcc78e3 |
children | b9fdb6b4c2dc |
comparison
equal
deleted
inserted
replaced
10542:5a298a61c6cc | 10543:7ff7a34848bf |
---|---|
59 | 59 |
60 /** Block comparing function | 60 /** Block comparing function |
61 * XXX should be optimized and moved to DSPContext | 61 * XXX should be optimized and moved to DSPContext |
62 * TODO handle out of edge ME | 62 * TODO handle out of edge ME |
63 */ | 63 */ |
64 static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, int bw, int bh) | 64 static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, int bw, int bh, int *xored) |
65 { | 65 { |
66 int sum = 0; | 66 int sum = 0; |
67 int i, j; | 67 int i, j; |
68 uint8_t histogram[256]={0}; | 68 uint8_t histogram[256]={0}; |
69 | 69 |
70 *xored = 0; | |
70 for(j = 0; j < bh; j++){ | 71 for(j = 0; j < bh; j++){ |
71 for(i = 0; i < bw; i++) | 72 for(i = 0; i < bw; i++){ |
72 histogram[src[i] ^ src2[i]]++; | 73 int t = src[i] ^ src2[i]; |
74 histogram[t]++; | |
75 *xored |= t; | |
76 } | |
73 src += stride; | 77 src += stride; |
74 src2 += stride2; | 78 src2 += stride2; |
75 } | 79 } |
76 | 80 |
77 for(i=1; i<256; i++) | 81 for(i=1; i<256; i++) |
82 | 86 |
83 /** Motion estimation function | 87 /** Motion estimation function |
84 * TODO make better ME decisions | 88 * TODO make better ME decisions |
85 */ | 89 */ |
86 static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, int pstride, | 90 static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, int pstride, |
87 int x, int y, int *mx, int *my) | 91 int x, int y, int *mx, int *my, int *xored) |
88 { | 92 { |
89 int dx, dy, tx, ty, tv, bv, bw, bh; | 93 int dx, dy, tx, ty, tv, bv, bw, bh; |
90 | 94 |
91 *mx = *my = 0; | 95 *mx = *my = 0; |
92 bw = FFMIN(ZMBV_BLOCK, c->avctx->width - x); | 96 bw = FFMIN(ZMBV_BLOCK, c->avctx->width - x); |
93 bh = FFMIN(ZMBV_BLOCK, c->avctx->height - y); | 97 bh = FFMIN(ZMBV_BLOCK, c->avctx->height - y); |
94 bv = block_cmp(src, sstride, prev, pstride, bw, bh); | 98 bv = block_cmp(src, sstride, prev, pstride, bw, bh, xored); |
95 if(!bv) return 0; | 99 if(!bv) return 0; |
96 for(ty = FFMAX(y - c->range, 0); ty < FFMIN(y + c->range, c->avctx->height - bh); ty++){ | 100 for(ty = FFMAX(y - c->range, 0); ty < FFMIN(y + c->range, c->avctx->height - bh); ty++){ |
97 for(tx = FFMAX(x - c->range, 0); tx < FFMIN(x + c->range, c->avctx->width - bw); tx++){ | 101 for(tx = FFMAX(x - c->range, 0); tx < FFMIN(x + c->range, c->avctx->width - bw); tx++){ |
98 if(tx == x && ty == y) continue; // we already tested this block | 102 if(tx == x && ty == y) continue; // we already tested this block |
99 dx = tx - x; | 103 dx = tx - x; |
100 dy = ty - y; | 104 dy = ty - y; |
101 tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh); | 105 tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh, xored); |
102 if(tv < bv){ | 106 if(tv < bv){ |
103 bv = tv; | 107 bv = tv; |
104 *mx = dx; | 108 *mx = dx; |
105 *my = dy; | 109 *my = dy; |
106 if(!bv) return 0; | 110 if(!bv) return 0; |
171 memcpy(c->work_buf + work_size, src, avctx->width); | 175 memcpy(c->work_buf + work_size, src, avctx->width); |
172 src += p->linesize[0]; | 176 src += p->linesize[0]; |
173 work_size += avctx->width; | 177 work_size += avctx->width; |
174 } | 178 } |
175 }else{ | 179 }else{ |
176 int x, y, bh2, bw2; | 180 int x, y, bh2, bw2, xored; |
177 uint8_t *tsrc, *tprev; | 181 uint8_t *tsrc, *tprev; |
178 uint8_t *mv; | 182 uint8_t *mv; |
179 int mx, my, bv; | 183 int mx, my, bv; |
180 | 184 |
181 bw = (avctx->width + ZMBV_BLOCK - 1) / ZMBV_BLOCK; | 185 bw = (avctx->width + ZMBV_BLOCK - 1) / ZMBV_BLOCK; |
190 bw2 = FFMIN(avctx->width - x, ZMBV_BLOCK); | 194 bw2 = FFMIN(avctx->width - x, ZMBV_BLOCK); |
191 | 195 |
192 tsrc = src + x; | 196 tsrc = src + x; |
193 tprev = prev + x; | 197 tprev = prev + x; |
194 | 198 |
195 bv = zmbv_me(c, tsrc, p->linesize[0], tprev, c->pstride, x, y, &mx, &my); | 199 bv = zmbv_me(c, tsrc, p->linesize[0], tprev, c->pstride, x, y, &mx, &my, &xored); |
196 mv[0] = (mx << 1) | !!bv; | 200 mv[0] = (mx << 1) | !!xored; |
197 mv[1] = my << 1; | 201 mv[1] = my << 1; |
198 tprev += mx + my * c->pstride; | 202 tprev += mx + my * c->pstride; |
199 if(bv){ | 203 if(xored){ |
200 for(j = 0; j < bh2; j++){ | 204 for(j = 0; j < bh2; j++){ |
201 for(i = 0; i < bw2; i++) | 205 for(i = 0; i < bw2; i++) |
202 c->work_buf[work_size++] = tsrc[i] ^ tprev[i]; | 206 c->work_buf[work_size++] = tsrc[i] ^ tprev[i]; |
203 tsrc += p->linesize[0]; | 207 tsrc += p->linesize[0]; |
204 tprev += c->pstride; | 208 tprev += c->pstride; |