]> git.sesse.net Git - ffmpeg/commitdiff
10l trocadero: ZMBV encoder used zero score to detect whether block should be
authorKostya Shishkov <kostya.shishkov@gmail.com>
Fri, 20 Nov 2009 07:22:41 +0000 (07:22 +0000)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Fri, 20 Nov 2009 07:22:41 +0000 (07:22 +0000)
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

libavcodec/zmbvenc.c

index 0131b5d1f3f2ca1cb89af97e0b9a3f5a02ba8616..d3838904cc4d14f2b2c2eeb4dc74973f8ff07319 100644 (file)
@@ -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];