--- trunk/xvidcore/src/image/image.c 2009/03/30 14:40:05 1856 +++ trunk/xvidcore/src/image/image.c 2019/01/17 14:25:05 2173 @@ -3,7 +3,7 @@ * XVID MPEG-4 VIDEO CODEC * - Image management functions - * - * Copyright(C) 2001-2004 Peter Ross + * Copyright(C) 2001-2010 Peter Ross * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: image.c,v 1.44 2009-03-30 14:40:05 Isibaar Exp $ + * $Id$ * ****************************************************************************/ @@ -127,8 +127,10 @@ memcpy(image1->v, image2->v, edged_width * height / 4); } -/* setedges bug was fixed in this BS version */ +/* setedges bug was in this BS versions */ #define SETEDGES_BUG_BEFORE 18 +#define SETEDGES_BUG_AFTER 57 +#define SETEDGES_BUG_REFIXED 63 void image_setedges(IMAGE * image, @@ -149,7 +151,9 @@ /* According to the Standard Clause 7.6.4, padding is done starting at 16 * pixel width and height multiples. This was not respected in old xvids */ - if (bs_version == 0 || bs_version >= SETEDGES_BUG_BEFORE) { + if ((bs_version >= SETEDGES_BUG_BEFORE && + bs_version < SETEDGES_BUG_AFTER) || + bs_version >= SETEDGES_BUG_REFIXED) { width = (width+15)&~15; height = (height+15)&~15; } @@ -411,10 +415,10 @@ /* packed conversions require height to be divisable by 2 (or even by 4 for interlaced conversion) */ - if (interlacing) - height_opt = height & (~3); - else - height_opt = height & (~1); + if (interlacing) + height_opt = height & (~3); + else + height_opt = height & (~1); func_opt(x_ptr, x_stride, y_ptr, u_ptr, v_ptr, y_stride, uv_stride, @@ -862,6 +866,98 @@ return (sse); } +void image_block_variance(IMAGE * orig_image, + uint16_t stride, + MACROBLOCK *mbs, + uint16_t mb_width, + uint16_t mb_height) +{ + DECLARE_ALIGNED_MATRIX(sums, 1, 4, uint16_t, CACHE_LINE); + DECLARE_ALIGNED_MATRIX(squares, 1, 4, uint32_t, CACHE_LINE); + + int x, y, i, j; + uint8_t *orig_y = orig_image->y; + uint8_t *orig_u = orig_image->u; + uint8_t *orig_v = orig_image->v; + + for (y = 0; y < mb_height; y++) { + for (x = 0; x < mb_width; x++) { + MACROBLOCK *pMB = &mbs[x + y * mb_width]; + uint32_t var4[4]; + uint32_t sum = 0, square = 0; + + /* y-blocks */ + for (j = 0; j < 2; j++) { + for (i = 0; i < 2; i++) { + int lsum = blocksum8(orig_y + ((y<<4) + (j<<3))*stride + (x<<4) + (i<<3), + stride, sums, squares); + int lsquare = (squares[0] + squares[1] + squares[2] + squares[3])<<6; + + sum += lsum; + square += lsquare; + + var4[0] = (squares[0]<<4) - sums[0]*sums[0]; + var4[1] = (squares[1]<<4) - sums[1]*sums[1]; + var4[2] = (squares[2]<<4) - sums[2]*sums[2]; + var4[3] = (squares[3]<<4) - sums[3]*sums[3]; + + pMB->rel_var8[j*2 + i] = lsquare - lsum*lsum; + if (pMB->rel_var8[j*2 + i]) + pMB->rel_var8[j*2 + i] = ((var4[0] + var4[1] + var4[2] + var4[3])<<8) / + pMB->rel_var8[j*2 + i]; /* 4*(Var(Di)/Var(D)) */ + else + pMB->rel_var8[j*2 + i] = 64; + } + } + + /* u */ + { + int lsum = blocksum8(orig_u + (y<<3)*(stride>>1) + (x<<3), + stride, sums, squares); + int lsquare = (squares[0] + squares[1] + squares[2] + squares[3])<<6; + + sum += lsum; + square += lsquare; + + var4[0] = (squares[0]<<4) - sums[0]*sums[0]; + var4[1] = (squares[1]<<4) - sums[1]*sums[1]; + var4[2] = (squares[2]<<4) - sums[2]*sums[2]; + var4[3] = (squares[3]<<4) - sums[3]*sums[3]; + + pMB->rel_var8[4] = lsquare - lsum*lsum; + if (pMB->rel_var8[4]) + pMB->rel_var8[4] = ((var4[0] + var4[1] + var4[2] + var4[3])<<8) / + pMB->rel_var8[4]; /* 4*(Var(Di)/Var(D)) */ + else + pMB->rel_var8[4] = 64; + } + + /* v */ + { + int lsum = blocksum8(orig_v + (y<<3)*(stride>>1) + (x<<3), + stride, sums, squares); + int lsquare = (squares[0] + squares[1] + squares[2] + squares[3])<<6; + + sum += lsum; + square += lsquare; + + var4[0] = (squares[0]<<4) - sums[0]*sums[0]; + var4[1] = (squares[1]<<4) - sums[1]*sums[1]; + var4[2] = (squares[2]<<4) - sums[2]*sums[2]; + var4[3] = (squares[3]<<4) - sums[3]*sums[3]; + + pMB->rel_var8[5] = lsquare - lsum*lsum; + if (pMB->rel_var8[5]) + pMB->rel_var8[5] = ((var4[0] + var4[1] + var4[2] + var4[3])<<8) / + pMB->rel_var8[5]; /* 4*(Var(Di)/Var(D)) */ + else + pMB->rel_var8[5] = 64; + } + + } + } +} + #if 0 #include