Skip to content
Snippets Groups Projects
postprocess.c 105 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	}
    	else
    	{
    #ifdef HAVE_MMX
    					asm volatile(
    						"pushl %0 \n\t"
    						"pushl %1 \n\t"
    						"leal (%2,%2), %%eax	\n\t"
    						"leal (%3,%3), %%ebx	\n\t"
    
    #define SIMPLE_CPY					\
    						"movq (%0), %%mm0	\n\t"\
    						"movq (%0,%2), %%mm1	\n\t"\
    						"movq %%mm0, (%1)	\n\t"\
    						"movq %%mm1, (%1, %3)	\n\t"\
    
    SIMPLE_CPY
    						"addl %%eax, %0		\n\t"
    						"addl %%ebx, %1		\n\t"
    SIMPLE_CPY
    
    						"addl %%eax, %0		\n\t"
    						"addl %%ebx, %1		\n\t"
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    SIMPLE_CPY
    						"addl %%eax, %0		\n\t"
    						"addl %%ebx, %1		\n\t"
    SIMPLE_CPY
    
    						"popl %1 \n\t"
    						"popl %0 \n\t"
    						: : "r" (src),
    						"r" (dst),
    						"r" (srcStride),
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    						"r" (dstStride)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				for(i=0; i<8; i++)
    
    					memcpy(	&(dst[dstStride*i]),
    						&(src[srcStride*i]), BLOCK_SIZE);
    #endif
    
    }
    
    
    /**
     * Filters array of bytes (Y or U or V values)
     */
    
    static void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
    
    	QP_STORE_T QPs[], int QPStride, int isColor, struct PPMode *ppMode)
    
    	const int mode= isColor ? ppMode->chromMode : ppMode->lumMode;
    
    
    	/* we need 64bit here otherwise well going to have a problem
    	   after watching a black picture for 5 hours*/
    	static uint64_t *yHistogram= NULL;
    	int black=0, white=255; // blackest black and whitest white in the picture
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    	int QPCorrecture= 256;
    
    	/* Temporary buffers for handling the last row(s) */
    	static uint8_t *tempDst= NULL;
    	static uint8_t *tempSrc= NULL;
    
    
    	/* Temporary buffers for handling the last block */
    	static uint8_t *tempDstBlock= NULL;
    	static uint8_t *tempSrcBlock= NULL;
    
    
    	/* Temporal noise reducing buffers */
    	static uint8_t *tempBlured[3]= {NULL,NULL,NULL};
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    	static uint32_t *tempBluredPast[3]= {NULL,NULL,NULL};
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    	int copyAhead;
    
    
    	uint8_t *dstBlockPtrBackup;
    	uint8_t *srcBlockPtrBackup;
    
    #ifdef MORE_TIMING
    	long long T0, T1, diffTime=0;
    #endif
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef TIMING
    
    	long long memcpyTime=0, vertTime=0, horizTime=0, sumTime;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    //mode= 0x7F;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef HAVE_MMX
    	maxTmpNoise[0]= ppMode->maxTmpNoise[0];
    	maxTmpNoise[1]= ppMode->maxTmpNoise[1];
    	maxTmpNoise[2]= ppMode->maxTmpNoise[2];
    #endif
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    	if(mode & CUBIC_IPOL_DEINT_FILTER) copyAhead=16;
    	else if(mode & LINEAR_BLEND_DEINT_FILTER) copyAhead=14;
    	else if(   (mode & V_DEBLOCK)
    		|| (mode & LINEAR_IPOL_DEINT_FILTER)
    		|| (mode & MEDIAN_DEINT_FILTER)) copyAhead=13;
    	else if(mode & V_X1_FILTER) copyAhead=11;
    	else if(mode & V_RK1_FILTER) copyAhead=10;
    	else if(mode & DERING) copyAhead=9;
    	else copyAhead=8;
    
    	copyAhead-= 8;
    
    
    	if(tempDst==NULL)
    	{
    		tempDst= (uint8_t*)memalign(8, 1024*24);
    		tempSrc= (uint8_t*)memalign(8, 1024*24);
    
    		tempDstBlock= (uint8_t*)memalign(8, 1024*24);
    		tempSrcBlock= (uint8_t*)memalign(8, 1024*24);
    
    	if(tempBlured[isColor]==NULL && (mode & TEMP_NOISE_FILTER))
    	{
    //		printf("%d %d %d\n", isColor, dstStride, height);
    		//FIXME works only as long as the size doesnt increase
    		//Note:the +17*1024 is just there so i dont have to worry about r/w over te end
    		tempBlured[isColor]= (uint8_t*)memalign(8, dstStride*((height+7)&(~7)) + 17*1024);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    		tempBluredPast[isColor]= (uint32_t*)memalign(8, 256*((height+7)&(~7))/2 + 17*1024);
    
    
    		memset(tempBlured[isColor], 0, dstStride*((height+7)&(~7)) + 17*1024);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    		memset(tempBluredPast[isColor], 0, 256*((height+7)&(~7))/2 + 17*1024);
    
    		int i;
    		yHistogram= (uint64_t*)malloc(8*256);
    		for(i=0; i<256; i++) yHistogram[i]= width*height/64*15/256;
    
    
    		if(mode & FULL_Y_RANGE)
    		{
    			maxAllowedY=255;
    			minAllowedY=0;
    		}
    
    		int i;
    		static int framenum= -1;
    		uint64_t maxClipped;
    		uint64_t clipped;
    		double scale;
    
    		framenum++;
    		if(framenum == 1) yHistogram[0]= width*height/64*15/256;
    
    		for(i=0; i<256; i++)
    		{
    
    //			printf("%d ", yHistogram[i]);
    		}
    //		printf("\n\n");
    
    		/* we allways get a completly black picture first */
    		maxClipped= (uint64_t)(sum * maxClippedThreshold);
    
    		for(black=255; black>0; black--)
    		{
    			if(clipped < maxClipped) break;
    			clipped-= yHistogram[black];
    		}
    
    		clipped= sum;
    		for(white=0; white<256; white++)
    		{
    			if(clipped < maxClipped) break;
    			clipped-= yHistogram[white];
    		}
    
    
    		packedYOffset= (black - minAllowedY) & 0xFFFF;
    
    		packedYOffset|= packedYOffset<<32;
    		packedYOffset|= packedYOffset<<16;
    
    
    		scale= (double)(maxAllowedY - minAllowedY) / (double)(white-black);
    
    		packedYScale= (uint16_t)(scale*1024.0 + 0.5);
    
    		packedYScale|= packedYScale<<32;
    		packedYScale|= packedYScale<<16;
    	}
    	else
    	{
    		packedYScale= 0x0100010001000100LL;
    		packedYOffset= 0;
    	}
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    	if(mode & LEVEL_FIX)	QPCorrecture= packedYScale &0xFFFF;
    	else			QPCorrecture= 256;
    
    
    	/* copy & deinterlace first row of blocks */
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    	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 well 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>>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"
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				"addl %5, %%eax			\n\t"
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				"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),
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			"m" (x), "m" (copyAhead)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			: "%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
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			blockCopy(dstBlock + dstStride*copyAhead, dstStride,
    				srcBlock + srcStride*copyAhead, srcStride, mode & LEVEL_FIX);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
    			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;
    		}
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    		memcpy(&(dst[y*dstStride]) + 8*dstStride, tempDst + 9*dstStride, copyAhead*dstStride );
    
    	for(y=0; y<height; 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]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef ARCH_X86
    		int *QPptr= isColor ? &QPs[(y>>3)*QPStride] :&QPs[(y>>4)*QPStride];
    		int QPDelta= isColor ? 1<<(32-3) : 1<<(32-4);
    		int QPFrac= QPDelta;
    
    		uint8_t *tempBlock1= tempBlocks;
    		uint8_t *tempBlock2= tempBlocks + 8;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #endif
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    		/* can we mess with a 8x16 block from srcBlock/dstBlock downwards and 1 line upwards
    		   if not than use a temporary buffer */
    
    		if(y+15 >= height)
    		{
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			/* copy from line (copyAhead) to (copyAhead+7) of src, these will be copied with
    
    			   blockcopy to dst later */
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			memcpy(tempSrc + srcStride*copyAhead, srcBlock + srcStride*copyAhead,
    				srcStride*MAX(height-y-copyAhead, 0) );
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			/* duplicate last line of src to fill the void upto line (copyAhead+7) */
    			for(i=MAX(height-y, 8); i<copyAhead+8; i++)
    
    				memcpy(tempSrc + srcStride*i, src + srcStride*(height-1), srcStride);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			/* copy up to (copyAhead+1) lines of dst (line -1 to (copyAhead-1))*/
    			memcpy(tempDst, dstBlock - dstStride, dstStride*MIN(height-y+1, copyAhead+1) );
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			/* duplicate last line of dst to fill the void upto line (copyAhead) */
    			for(i=height-y+1; i<=copyAhead; i++)
    
    				memcpy(tempDst + dstStride*i, dst + dstStride*(height-1), dstStride);
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			dstBlock= tempDst + dstStride;
    
    			srcBlock= tempSrc;
    		}
    
    		// From this point on it is guranteed that we can read and write 16 lines downward
    
    		// finish 1 block before the next otherwise well 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)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef ARCH_X86
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			asm volatile(
    				"addl %2, %1		\n\t"
    				"sbbl %%eax, %%eax	\n\t"
    				"shll $2, %%eax		\n\t"
    				"subl %%eax, %0		\n\t"
    				: "+r" (QPptr), "+m" (QPFrac)
    				: "r" (QPDelta)
    				: "%eax"
    			);
    #else
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                                    QPs[(y>>3)*QPStride + (x>>3)]:
                                    QPs[(y>>4)*QPStride + (x>>4)];
    #endif
    			if(!isColor)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			{
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				QP= (QP* QPCorrecture)>>8;
    
    				yHistogram[ srcBlock[srcStride*12 + 4] ]++;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			}
    
    			asm volatile(
    				"movd %0, %%mm7					\n\t"
    				"packuswb %%mm7, %%mm7				\n\t" // 0, 0, 0, QP, 0, 0, 0, QP
    				"packuswb %%mm7, %%mm7				\n\t" // 0,QP, 0, QP, 0,QP, 0, QP
    				"packuswb %%mm7, %%mm7				\n\t" // QP,..., QP
    				"movq %%mm7, pQPb				\n\t"
    				: : "r" (QP)
    			);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef MORE_TIMING
    
    			T0= rdtsc();
    
    #ifdef HAVE_MMX2
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    /*
    			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"
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				"addl %5, %%eax			\n\t"
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				"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),
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			"m" (x), "m" (copyAhead)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			: "%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);
    
    #ifdef PP_FUNNY_STRIDE
    
    			//can we mess with a 8x16 block, if not use a temp buffer, yes again
    			if(x+7 >= width)
    			{
    				int i;
    				dstBlockPtrBackup= dstBlock;
    				srcBlockPtrBackup= srcBlock;
    
    				for(i=0;i<BLOCK_SIZE*2; i++)
    				{
    					memcpy(tempSrcBlock+i*srcStride, srcBlock+i*srcStride, width-x);
    					memcpy(tempDstBlock+i*dstStride, dstBlock+i*dstStride, width-x);
    				}
    
    				dstBlock= tempDstBlock;
    				srcBlock= tempSrcBlock;
    			}
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			blockCopy(dstBlock + dstStride*copyAhead, dstStride,
    				srcBlock + srcStride*copyAhead, srcStride, 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);
    
    			/* only deblock if we have 2 blocks */
    			if(y + 8 < height)
    			{
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef MORE_TIMING
    
    				T1= rdtsc();
    				memcpyTime+= T1-T0;
    				T0=T1;
    #endif
    
    				if(mode & V_RK1_FILTER)
    					vertRK1Filter(dstBlock, stride, QP);
    				else if(mode & V_X1_FILTER)
    					vertX1Filter(dstBlock, stride, QP);
    				else if(mode & V_DEBLOCK)
    
    						if(isVertMinMaxOk(dstBlock, stride, QP))
    							doVertLowPass(dstBlock, stride, QP);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef MORE_TIMING
    
    				T1= rdtsc();
    				vertTime+= T1-T0;
    				T0=T1;
    #endif
    			}
    
    #ifdef HAVE_MMX
    			transpose1(tempBlock1, tempBlock2, dstBlock, dstStride);
    #endif
    
    			/* check if we have a previous block to deblock it with dstBlock */
    
    			if(x - 8 >= 0)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef MORE_TIMING
    
    #ifdef HAVE_MMX
    				if(mode & H_RK1_FILTER)
    					vertRK1Filter(tempBlock1, 16, QP);
    				else if(mode & H_X1_FILTER)
    					vertX1Filter(tempBlock1, 16, QP);
    				else if(mode & H_DEBLOCK)
    				{
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    					if( isVertDC(tempBlock1, 16) )
    
    					{
    						if(isVertMinMaxOk(tempBlock1, 16, QP))
    							doVertLowPass(tempBlock1, 16, QP);
    					}
    					else
    						doVertDefFilter(tempBlock1, 16, QP);
    				}
    
    				transpose2(dstBlock-4, dstStride, tempBlock1 + 4*16);
    
    #else
    
    				if(mode & H_X1_FILTER)
    					horizX1Filter(dstBlock-4, stride, QP);
    				else if(mode & H_DEBLOCK)
    
    						if(isHorizMinMaxOk(dstBlock-4, stride, QP))
    							doHorizLowPass(dstBlock-4, stride, QP);
    
    						doHorizDefFilter(dstBlock-4, stride, QP);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef MORE_TIMING
    
    				T1= rdtsc();
    				horizTime+= T1-T0;
    				T0=T1;
    #endif
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				if(mode & DERING)
    				{
    				//FIXME filter first line
    					if(y>0) dering(dstBlock - stride - 8, stride, QP);
    				}
    
    
    				if(mode & TEMP_NOISE_FILTER)
    				{
    					tempNoiseReducer(dstBlock-8, stride,
    						tempBlured[isColor] + y*dstStride + x,
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    						tempBluredPast[isColor] + (y>>3)*256 + (x>>3),
    
    #ifdef PP_FUNNY_STRIDE
    
    			/* did we use a tmp-block buffer */
    			if(x+7 >= width)
    			{
    				int i;
    				dstBlock= dstBlockPtrBackup;
    				srcBlock= srcBlockPtrBackup;
    
    				for(i=0;i<BLOCK_SIZE*2; i++)
    				{
    					memcpy(dstBlock+i*dstStride, tempDstBlock+i*dstStride, width-x);
    				}
    			}
    
    			tmpXchg= tempBlock1;
    			tempBlock1= tempBlock2;
    			tempBlock2 = tmpXchg;
    
    		if(mode & DERING)
    		{
    				if(y > 0) dering(dstBlock - dstStride - 8, dstStride, QP);
    		}
    
    		if((mode & TEMP_NOISE_FILTER))
    		{
    			tempNoiseReducer(dstBlock-8, dstStride,
    				tempBlured[isColor] + y*dstStride + x,
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				tempBluredPast[isColor] + (y>>3)*256 + (x>>3),
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    		/* did we use a tmp buffer for the last lines*/
    
    		if(y+15 >= height)
    
    		{
    			uint8_t *dstBlock= &(dst[y*dstStride]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			memcpy(dstBlock, tempDst + dstStride, dstStride*(height-y) );
    
    /*
    		for(x=0; x<width; x+=32)
    		{
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    			volatile int i;
    
    			i+=	+ dstBlock[x + 7*dstStride] + dstBlock[x + 8*dstStride]
    				+ dstBlock[x + 9*dstStride] + dstBlock[x +10*dstStride]
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    				+ dstBlock[x +11*dstStride] + dstBlock[x +12*dstStride];
    //				+ dstBlock[x +13*dstStride]
    //				+ dstBlock[x +14*dstStride] + dstBlock[x +15*dstStride];
    		}*/
    	}
    
    #ifdef HAVE_3DNOW
    	asm volatile("femms");
    #elif defined (HAVE_MMX)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #ifdef TIMING
    
    	// FIXME diff is mostly the time spent for rdtsc (should subtract that but ...)
    	sumTime= rdtsc() - sumTime;
    	if(!isColor)
    		printf("cpy:%4dk, vert:%4dk, horiz:%4dk, sum:%4dk, diff:%4dk, color: %d/%d    \r",
    
    			(int)(memcpyTime/1000), (int)(vertTime/1000), (int)(horizTime/1000),
    			(int)(sumTime/1000), (int)((sumTime-memcpyTime-vertTime-horizTime)/1000)
    
    #ifdef DEBUG_BRIGHTNESS
    	if(!isColor)
    	{
    		int max=1;
    		int i;
    		for(i=0; i<256; i++)
    			if(yHistogram[i] > max) max=yHistogram[i];
    
    		for(i=1; i<256; i++)
    		{
    			int x;
    			int start=yHistogram[i-1]/(max/256+1);
    			int end=yHistogram[i]/(max/256+1);
    			int inc= end > start ? 1 : -1;
    			for(x=start; x!=end+inc; x+=inc)
    				dst[ i*dstStride + x]+=128;
    		}
    
    		for(i=0; i<100; i+=2)
    		{
    			dst[ (white)*dstStride + i]+=128;
    			dst[ (black)*dstStride + i]+=128;
    		}
    
    	}
    #endif