Mercurial > mplayer.hg
changeset 2595:6c1d6f508466
deinterlace bugfix
author | michael |
---|---|
date | Wed, 31 Oct 2001 18:29:03 +0000 |
parents | 1486c690bece |
children | ae2026ac39d4 |
files | postproc/postprocess.c postproc/postprocess_template.c |
diffstat | 2 files changed, 226 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/postproc/postprocess.c Wed Oct 31 18:25:28 2001 +0000 +++ b/postproc/postprocess.c Wed Oct 31 18:29:03 2001 +0000 @@ -2117,11 +2117,14 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15 + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced */ static inline void deInterlaceInterpolateLinear(uint8_t src[], int stride) { #if defined (HAVE_MMX2) || defined (HAVE_3DNOW) + src+= 4*stride; asm volatile( "leal (%0, %1), %%eax \n\t" "leal (%%eax, %1, 4), %%ebx \n\t" @@ -2147,6 +2150,7 @@ ); #else int x; + src+= 4*stride; for(x=0; x<8; x++) { src[stride] = (src[0] + src[stride*2])>>1; @@ -2160,12 +2164,16 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15 + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced + * this filter will read lines 3-15 and write 7-13 * no cliping in C version */ static inline void deInterlaceInterpolateCubic(uint8_t src[], int stride) { #if defined (HAVE_MMX2) || defined (HAVE_3DNOW) + src+= stride*3; asm volatile( "leal (%0, %1), %%eax \n\t" "leal (%%eax, %1, 4), %%ebx \n\t" @@ -2207,6 +2215,7 @@ ); #else int x; + src+= stride*3; for(x=0; x<8; x++) { src[stride*3] = (-src[0] + 9*src[stride*2] + 9*src[stride*4] - src[stride*6])>>4; @@ -2220,12 +2229,16 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15 + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced * will shift the image up by 1 line (FIXME if this is a problem) + * this filter will read lines 4-13 and write 4-11 */ static inline void deInterlaceBlendLinear(uint8_t src[], int stride) { #if defined (HAVE_MMX2) || defined (HAVE_3DNOW) + src+= 4*stride; asm volatile( "leal (%0, %1), %%eax \n\t" "leal (%%eax, %1, 4), %%ebx \n\t" @@ -2273,6 +2286,7 @@ ); #else int x; + src+= 4*stride; for(x=0; x<8; x++) { src[0 ] = (src[0 ] + 2*src[stride ] + src[stride*2])>>2; @@ -2290,11 +2304,14 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, except the last row, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15, + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced */ static inline void deInterlaceMedian(uint8_t src[], int stride) { #ifdef HAVE_MMX + src+= 4*stride; #ifdef HAVE_MMX2 asm volatile( "leal (%0, %1), %%eax \n\t" @@ -2388,6 +2405,7 @@ #else //FIXME int x; + src+= 4*stride; for(x=0; x<8; x++) { src[0 ] = (src[0 ] + 2*src[stride ] + src[stride*2])>>2; @@ -2774,6 +2792,8 @@ src_stride >>= 1; dst_stride >>= 1; mode= ((mode&0xFF)>>4) | (mode&0xFFFFFF00); +// mode&= ~(LINEAR_IPOL_DEINT_FILTER | LINEAR_BLEND_DEINT_FILTER | +// MEDIAN_DEINT_FILTER | CUBIC_IPOL_DEINT_FILTER); if(1) { @@ -3088,9 +3108,82 @@ if(mode & LEVEL_FIX) QPCorrecture= packedYScale &0xFFFF; else QPCorrecture= 256; - /* copy first row of 8x8 blocks */ - for(x=0; x<width; x+=BLOCK_SIZE) - blockCopy(dst + x, dstStride, src + x, srcStride, 8, mode & LEVEL_FIX); + /* line before the first one */ + y=-BLOCK_SIZE; + { + //1% speedup if these are here instead of the inner loop + uint8_t *srcBlock= &(src[y*srcStride]); + uint8_t *dstBlock= &(dst[y*dstStride]); + + dstBlock= tempDst + dstStride; + + // From this point on it is guranteed that we can read and write 16 lines downward + // finish 1 block before the next otherwise weŽll might have a problem + // with the L1 Cache of the P4 ... or only a few blocks at a time or soemthing + for(x=0; x<width; x+=BLOCK_SIZE) + { + +#ifdef HAVE_MMX2 +/* + prefetchnta(srcBlock + (((x>>3)&3) + 5)*srcStride + 32); + prefetchnta(srcBlock + (((x>>3)&3) + 9)*srcStride + 32); + prefetcht0(dstBlock + (((x>>3)&3) + 5)*dstStride + 32); + prefetcht0(dstBlock + (((x>>3)&3) + 9)*dstStride + 32); +*/ +/* + prefetchnta(srcBlock + (((x>>2)&6) + 5)*srcStride + 32); + prefetchnta(srcBlock + (((x>>2)&6) + 6)*srcStride + 32); + prefetcht0(dstBlock + (((x>>2)&6) + 5)*dstStride + 32); + prefetcht0(dstBlock + (((x>>2)&6) + 6)*dstStride + 32); +*/ + + asm( + "movl %4, %%eax \n\t" + "shrl $2, %%eax \n\t" + "andl $6, %%eax \n\t" + "addl $8, %%eax \n\t" + "movl %%eax, %%ebx \n\t" + "imul %1, %%eax \n\t" + "imul %3, %%ebx \n\t" + "prefetchnta 32(%%eax, %0) \n\t" + "prefetcht0 32(%%ebx, %2) \n\t" + "addl %1, %%eax \n\t" + "addl %3, %%ebx \n\t" + "prefetchnta 32(%%eax, %0) \n\t" + "prefetcht0 32(%%ebx, %2) \n\t" + :: "r" (srcBlock), "r" (srcStride), "r" (dstBlock), "r" (dstStride), + "m" (x) + : "%eax", "%ebx" + ); + +#elif defined(HAVE_3DNOW) +//FIXME check if this is faster on an 3dnow chip or if its faster without the prefetch or ... +/* prefetch(srcBlock + (((x>>3)&3) + 5)*srcStride + 32); + prefetch(srcBlock + (((x>>3)&3) + 9)*srcStride + 32); + prefetchw(dstBlock + (((x>>3)&3) + 5)*dstStride + 32); + prefetchw(dstBlock + (((x>>3)&3) + 9)*dstStride + 32); +*/ +#endif + + blockCopy(dstBlock + dstStride*8, dstStride, + srcBlock + srcStride*8, srcStride, 8, mode & LEVEL_FIX); + + if(mode & LINEAR_IPOL_DEINT_FILTER) + deInterlaceInterpolateLinear(dstBlock, dstStride); + else if(mode & LINEAR_BLEND_DEINT_FILTER) + deInterlaceBlendLinear(dstBlock, dstStride); + else if(mode & MEDIAN_DEINT_FILTER) + deInterlaceMedian(dstBlock, dstStride); + else if(mode & CUBIC_IPOL_DEINT_FILTER) + deInterlaceInterpolateCubic(dstBlock, dstStride); +/* else if(mode & CUBIC_BLEND_DEINT_FILTER) + deInterlaceBlendCubic(dstBlock, dstStride); +*/ + dstBlock+=8; + srcBlock+=8; + } + memcpy(&(dst[y*dstStride]) + 8*dstStride, tempDst + 9*dstStride, 8*dstStride ); + } for(y=0; y<height; y+=BLOCK_SIZE) { @@ -3108,23 +3201,22 @@ if not than use a temporary buffer */ if(y+15 >= height) { - /* copy from line 5 to 12 of src, these will be copied with + /* copy from line 8 to 15 of src, these will be copied with blockcopy to dst later */ - memcpy(tempSrc + srcStride*5, srcBlock + srcStride*5, - srcStride*MAX(height-y-5, 0) ); - - /* duplicate last line to fill the void upto line 12 */ - if(y+12 >= height) + memcpy(tempSrc + srcStride*8, srcBlock + srcStride*8, + srcStride*MAX(height-y-8, 0) ); + + /* duplicate last line to fill the void upto line 15 */ + if(y+15 >= height) { int i; - for(i=height-y; i<=12; i++) + for(i=height-y; i<=15; i++) memcpy(tempSrc + srcStride*i, src + srcStride*(height-1), srcStride); } - - /* copy up to 6 lines of dst */ - memcpy(tempDst, dstBlock - dstStride, dstStride*MIN(height-y+1, 6) ); + /* copy up to 9 lines of dst */ + memcpy(tempDst, dstBlock - dstStride, dstStride*MIN(height-y+1, 9) ); dstBlock= tempDst + dstStride; srcBlock= tempSrc; } @@ -3190,7 +3282,7 @@ "movl %4, %%eax \n\t" "shrl $2, %%eax \n\t" "andl $6, %%eax \n\t" - "addl $5, %%eax \n\t" + "addl $8, %%eax \n\t" "movl %%eax, %%ebx \n\t" "imul %1, %%eax \n\t" "imul %3, %%ebx \n\t" @@ -3233,8 +3325,8 @@ } #endif - blockCopy(dstBlock + dstStride*5, dstStride, - srcBlock + srcStride*5, srcStride, 8, mode & LEVEL_FIX); + blockCopy(dstBlock + dstStride*8, dstStride, + srcBlock + srcStride*8, srcStride, 8, mode & LEVEL_FIX); if(mode & LINEAR_IPOL_DEINT_FILTER) deInterlaceInterpolateLinear(dstBlock, dstStride); @@ -3361,7 +3453,7 @@ #endif } - /* did we use a tmp buffer */ + /* did we use a tmp buffer for the last lines*/ if(y+15 >= height) { uint8_t *dstBlock= &(dst[y*dstStride]);
--- a/postproc/postprocess_template.c Wed Oct 31 18:25:28 2001 +0000 +++ b/postproc/postprocess_template.c Wed Oct 31 18:29:03 2001 +0000 @@ -2117,11 +2117,14 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15 + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced */ static inline void deInterlaceInterpolateLinear(uint8_t src[], int stride) { #if defined (HAVE_MMX2) || defined (HAVE_3DNOW) + src+= 4*stride; asm volatile( "leal (%0, %1), %%eax \n\t" "leal (%%eax, %1, 4), %%ebx \n\t" @@ -2147,6 +2150,7 @@ ); #else int x; + src+= 4*stride; for(x=0; x<8; x++) { src[stride] = (src[0] + src[stride*2])>>1; @@ -2160,12 +2164,16 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15 + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced + * this filter will read lines 3-15 and write 7-13 * no cliping in C version */ static inline void deInterlaceInterpolateCubic(uint8_t src[], int stride) { #if defined (HAVE_MMX2) || defined (HAVE_3DNOW) + src+= stride*3; asm volatile( "leal (%0, %1), %%eax \n\t" "leal (%%eax, %1, 4), %%ebx \n\t" @@ -2207,6 +2215,7 @@ ); #else int x; + src+= stride*3; for(x=0; x<8; x++) { src[stride*3] = (-src[0] + 9*src[stride*2] + 9*src[stride*4] - src[stride*6])>>4; @@ -2220,12 +2229,16 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15 + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced * will shift the image up by 1 line (FIXME if this is a problem) + * this filter will read lines 4-13 and write 4-11 */ static inline void deInterlaceBlendLinear(uint8_t src[], int stride) { #if defined (HAVE_MMX2) || defined (HAVE_3DNOW) + src+= 4*stride; asm volatile( "leal (%0, %1), %%eax \n\t" "leal (%%eax, %1, 4), %%ebx \n\t" @@ -2273,6 +2286,7 @@ ); #else int x; + src+= 4*stride; for(x=0; x<8; x++) { src[0 ] = (src[0 ] + 2*src[stride ] + src[stride*2])>>2; @@ -2290,11 +2304,14 @@ /** * Deinterlaces the given block - * will be called for every 8x8 block, except the last row, and can read & write into an 8x16 block + * will be called for every 8x8 block and can read & write from line 4-15, + * lines 0-3 have been passed through the deblock / dering filters allready, but can be read too + * lines 4-12 will be read into the deblocking filter and should be deinterlaced */ static inline void deInterlaceMedian(uint8_t src[], int stride) { #ifdef HAVE_MMX + src+= 4*stride; #ifdef HAVE_MMX2 asm volatile( "leal (%0, %1), %%eax \n\t" @@ -2388,6 +2405,7 @@ #else //FIXME int x; + src+= 4*stride; for(x=0; x<8; x++) { src[0 ] = (src[0 ] + 2*src[stride ] + src[stride*2])>>2; @@ -2774,6 +2792,8 @@ src_stride >>= 1; dst_stride >>= 1; mode= ((mode&0xFF)>>4) | (mode&0xFFFFFF00); +// mode&= ~(LINEAR_IPOL_DEINT_FILTER | LINEAR_BLEND_DEINT_FILTER | +// MEDIAN_DEINT_FILTER | CUBIC_IPOL_DEINT_FILTER); if(1) { @@ -3088,9 +3108,82 @@ if(mode & LEVEL_FIX) QPCorrecture= packedYScale &0xFFFF; else QPCorrecture= 256; - /* copy first row of 8x8 blocks */ - for(x=0; x<width; x+=BLOCK_SIZE) - blockCopy(dst + x, dstStride, src + x, srcStride, 8, mode & LEVEL_FIX); + /* line before the first one */ + y=-BLOCK_SIZE; + { + //1% speedup if these are here instead of the inner loop + uint8_t *srcBlock= &(src[y*srcStride]); + uint8_t *dstBlock= &(dst[y*dstStride]); + + dstBlock= tempDst + dstStride; + + // From this point on it is guranteed that we can read and write 16 lines downward + // finish 1 block before the next otherwise weŽll might have a problem + // with the L1 Cache of the P4 ... or only a few blocks at a time or soemthing + for(x=0; x<width; x+=BLOCK_SIZE) + { + +#ifdef HAVE_MMX2 +/* + prefetchnta(srcBlock + (((x>>3)&3) + 5)*srcStride + 32); + prefetchnta(srcBlock + (((x>>3)&3) + 9)*srcStride + 32); + prefetcht0(dstBlock + (((x>>3)&3) + 5)*dstStride + 32); + prefetcht0(dstBlock + (((x>>3)&3) + 9)*dstStride + 32); +*/ +/* + prefetchnta(srcBlock + (((x>>2)&6) + 5)*srcStride + 32); + prefetchnta(srcBlock + (((x>>2)&6) + 6)*srcStride + 32); + prefetcht0(dstBlock + (((x>>2)&6) + 5)*dstStride + 32); + prefetcht0(dstBlock + (((x>>2)&6) + 6)*dstStride + 32); +*/ + + asm( + "movl %4, %%eax \n\t" + "shrl $2, %%eax \n\t" + "andl $6, %%eax \n\t" + "addl $8, %%eax \n\t" + "movl %%eax, %%ebx \n\t" + "imul %1, %%eax \n\t" + "imul %3, %%ebx \n\t" + "prefetchnta 32(%%eax, %0) \n\t" + "prefetcht0 32(%%ebx, %2) \n\t" + "addl %1, %%eax \n\t" + "addl %3, %%ebx \n\t" + "prefetchnta 32(%%eax, %0) \n\t" + "prefetcht0 32(%%ebx, %2) \n\t" + :: "r" (srcBlock), "r" (srcStride), "r" (dstBlock), "r" (dstStride), + "m" (x) + : "%eax", "%ebx" + ); + +#elif defined(HAVE_3DNOW) +//FIXME check if this is faster on an 3dnow chip or if its faster without the prefetch or ... +/* prefetch(srcBlock + (((x>>3)&3) + 5)*srcStride + 32); + prefetch(srcBlock + (((x>>3)&3) + 9)*srcStride + 32); + prefetchw(dstBlock + (((x>>3)&3) + 5)*dstStride + 32); + prefetchw(dstBlock + (((x>>3)&3) + 9)*dstStride + 32); +*/ +#endif + + blockCopy(dstBlock + dstStride*8, dstStride, + srcBlock + srcStride*8, srcStride, 8, mode & LEVEL_FIX); + + if(mode & LINEAR_IPOL_DEINT_FILTER) + deInterlaceInterpolateLinear(dstBlock, dstStride); + else if(mode & LINEAR_BLEND_DEINT_FILTER) + deInterlaceBlendLinear(dstBlock, dstStride); + else if(mode & MEDIAN_DEINT_FILTER) + deInterlaceMedian(dstBlock, dstStride); + else if(mode & CUBIC_IPOL_DEINT_FILTER) + deInterlaceInterpolateCubic(dstBlock, dstStride); +/* else if(mode & CUBIC_BLEND_DEINT_FILTER) + deInterlaceBlendCubic(dstBlock, dstStride); +*/ + dstBlock+=8; + srcBlock+=8; + } + memcpy(&(dst[y*dstStride]) + 8*dstStride, tempDst + 9*dstStride, 8*dstStride ); + } for(y=0; y<height; y+=BLOCK_SIZE) { @@ -3108,23 +3201,22 @@ if not than use a temporary buffer */ if(y+15 >= height) { - /* copy from line 5 to 12 of src, these will be copied with + /* copy from line 8 to 15 of src, these will be copied with blockcopy to dst later */ - memcpy(tempSrc + srcStride*5, srcBlock + srcStride*5, - srcStride*MAX(height-y-5, 0) ); - - /* duplicate last line to fill the void upto line 12 */ - if(y+12 >= height) + memcpy(tempSrc + srcStride*8, srcBlock + srcStride*8, + srcStride*MAX(height-y-8, 0) ); + + /* duplicate last line to fill the void upto line 15 */ + if(y+15 >= height) { int i; - for(i=height-y; i<=12; i++) + for(i=height-y; i<=15; i++) memcpy(tempSrc + srcStride*i, src + srcStride*(height-1), srcStride); } - - /* copy up to 6 lines of dst */ - memcpy(tempDst, dstBlock - dstStride, dstStride*MIN(height-y+1, 6) ); + /* copy up to 9 lines of dst */ + memcpy(tempDst, dstBlock - dstStride, dstStride*MIN(height-y+1, 9) ); dstBlock= tempDst + dstStride; srcBlock= tempSrc; } @@ -3190,7 +3282,7 @@ "movl %4, %%eax \n\t" "shrl $2, %%eax \n\t" "andl $6, %%eax \n\t" - "addl $5, %%eax \n\t" + "addl $8, %%eax \n\t" "movl %%eax, %%ebx \n\t" "imul %1, %%eax \n\t" "imul %3, %%ebx \n\t" @@ -3233,8 +3325,8 @@ } #endif - blockCopy(dstBlock + dstStride*5, dstStride, - srcBlock + srcStride*5, srcStride, 8, mode & LEVEL_FIX); + blockCopy(dstBlock + dstStride*8, dstStride, + srcBlock + srcStride*8, srcStride, 8, mode & LEVEL_FIX); if(mode & LINEAR_IPOL_DEINT_FILTER) deInterlaceInterpolateLinear(dstBlock, dstStride); @@ -3361,7 +3453,7 @@ #endif } - /* did we use a tmp buffer */ + /* did we use a tmp buffer for the last lines*/ if(y+15 >= height) { uint8_t *dstBlock= &(dst[y*dstStride]);