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;