⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postprocess.c

📁 MPEG4编解码的C语言源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	#endif
	
	/* simple C implementation of vertical default filter */
	for (x=0; x<8; x++) { /* loop left->right */
		vv = &(v[x]);
		p1 = (ABS(vv[0*stride]-vv[1*stride]) < QP ) ?  vv[0*stride] : vv[1*stride];
		p2 = (ABS(vv[8*stride]-vv[9*stride]) < QP ) ?  vv[9*stride] : vv[8*stride];
		/* the above may well be endian-fussy */
		psum = p1 + p1 + p1 + vv[l1] + vv[l2] + vv[l3] + vv[l4] + 4; 
		vnew[1] = (((psum + vv[l1]) << 1) - (vv[l4] - vv[l5])) >> 4; 
		psum += vv[l5] - p1; 
		vnew[2] = (((psum + vv[l2]) << 1) - (vv[l5] - vv[l6])) >> 4; 
		psum += vv[l6] - p1; 
		vnew[3] = (((psum + vv[l3]) << 1) - (vv[l6] - vv[l7])) >> 4; 
		psum += vv[l7] - p1; 
		vnew[4] = (((psum + vv[l4]) << 1) + p1 - vv[l1] - (vv[l7] - vv[l8])) >> 4; 
		psum += vv[l8] - vv[l1];  
		vnew[5] = (((psum + vv[l5]) << 1) + (vv[l1] - vv[l2]) - vv[l8] + p2) >> 4; 
		psum += p2 - vv[l2];  
		vnew[6] = (((psum + vv[l6]) << 1) + (vv[l2] - vv[l3])) >> 4; 
		psum += p2 - vv[l3]; 
		vnew[7] = (((psum + vv[l7]) << 1) + (vv[l3] - vv[l4])) >> 4; 
		psum += p2 - vv[l4]; 
		vnew[8] = (((psum + vv[l8]) << 1) + (vv[l4] - vv[l5])) >> 4;
		for (y=1; y<=8; y++) {
			vv[y*stride] = vnew[y];
		}  
	}
	
	#ifdef PP_SELF_CHECK
	/* use the self-check version of the filter result in selfcheck[64] to verify the filter output */
	for (k=0; k<8; k++) { /* loop top->bottom */
		for (j=0; j<8; j++) { /* loop left->right */
			if (v[(k+1)*stride + j] != selfcheck[j+8*k]) printf("ERROR: problem with C filter in row %d\n", k+1);
		}
	}
	#endif

}




/* Vertical deblocking filter for use in non-flat picture regions */
static void deblock_vert_default_filter(uint8_t *v, int stride, int QP) {
	int x, a3_0, a3_1, a3_2, d, q;
	/* define semi-constants to enable us to move up and down the picture easily... */
	int l1 = 1 * stride;
	int l2 = 2 * stride;
	int l3 = 3 * stride;
	int l4 = 4 * stride;
	int l5 = 5 * stride;
	int l6 = 6 * stride;
	int l7 = 7 * stride;
	int l8 = 8 * stride;
	
	#ifdef PP_SELF_CHECK
	int j, k, a3_0_SC, a3_1_SC, a3_2_SC, d_SC, q_SC;
	uint8_t selfcheck[8][2];
	#endif

	#ifdef PP_SELF_CHECK
	/* compute selfcheck matrix for later comparison */
	for (j=0; j<8; j++) {
		a3_0_SC = 2*v[l3+j] - 5*v[l4+j] + 5*v[l5+j] - 2*v[l6+j];	
		a3_1_SC = 2*v[l1+j] - 5*v[l2+j] + 5*v[l3+j] - 2*v[l4+j];	
		a3_2_SC = 2*v[l5+j] - 5*v[l6+j] + 5*v[l7+j] - 2*v[l8+j];	
		q_SC    = (v[l4+j] - v[l5+j]) / 2;

		if (ABS(a3_0_SC) < 8*QP) {

			d_SC = ABS(a3_0_SC) - MIN(ABS(a3_1_SC), ABS(a3_2_SC));
			if (d_SC < 0) d_SC=0;
				
			d_SC = (5*d_SC + 32) >> 6; 
			d_SC *= SIGN(-a3_0_SC);
							
			//printf("d_SC[%d] preclip=%d\n", j, d_SC);
			/* clip d in the range 0 ... q */
			if (q_SC > 0) {
				d_SC = d_SC<0    ? 0    : d_SC;
				d_SC = d_SC>q_SC ? q_SC : d_SC;
			} else {
				d_SC = d_SC>0    ? 0    : d_SC;
				d_SC = d_SC<q_SC ? q_SC : d_SC;
			}
						
		} else {
			d_SC = 0;		
		}
		selfcheck[j][0] = v[l4+j] - d_SC;
		selfcheck[j][1] = v[l5+j] + d_SC;
	}
	#endif

	/* simple C implementation of vertical default filter */
	for (x=0; x<8; x++) {
		a3_0 = 2*v[l3+x] - 5*v[l4+x] + 5*v[l5+x] - 2*v[l6+x];	
		a3_1 = 2*v[l1+x] - 5*v[l2+x] + 5*v[l3+x] - 2*v[l4+x];	
		a3_2 = 2*v[l5+x] - 5*v[l6+x] + 5*v[l7+x] - 2*v[l8+x];	
		q    = (v[l4+x] - v[l5+x]) / 2;

		if (ABS(a3_0) < 8*QP) {

			d = ABS(a3_0) - MIN(ABS(a3_1), ABS(a3_2));
			if (d < 0) d=0;
				
			d = (5*d + 32) >> 6; 
			d *= SIGN(-a3_0);
							
			//printf("d[%d] preclip=%d\n", x, d);
			/* clip d in the range 0 ... q */
			if (q > 0) {
				d = d<0    ? 0    : d;
				d = d>q ? q : d;
			} else {
				d = d>0    ? 0    : d;
				d = d<q ? q : d;
			}
						
		} else {
			d = 0;		
		}
		v[l4+x] -= d;
		v[l5+x] += d;
	}
	
	
	


	#ifdef PP_SELF_CHECK
	/* do selfcheck */
	for (j=0; j<8; j++) {
		for (k=0; k<2; k++) {
			if (selfcheck[j][k] != v[l4+j+k*stride]) {
				printf("ERROR: problem with vertical default filter in col %d, row %d\n", j, k);	
				printf("%d should be %d\n", v[l4+j+k*stride], selfcheck[j][k]);	
				
			}
		}
	}
	#endif

	


}










/* this is a vertical deblocking filter - i.e. it will smooth _horizontal_ block edges */
void deblock_vert( uint8_t *image, int width, int height, int stride, QP_STORE_T *QP_store, int QP_stride, int chroma) {
	uint64_t v_local[20];
	uint64_t p1p2[4];
	int Bx, y;
	int QP, QPx16;
	uint8_t *v;
	int useDC, DC_on;

	/* loop over image's block boundary rows */
	for (y=8; y<height; y+=8) {	
		
		/* loop over all blocks, left to right */
		for (Bx=0; Bx<width; Bx+=8) {

			QP = chroma ? QP_store[y/8*QP_stride+Bx/8]
			            : QP_store[y/16*QP_stride+Bx/16];	
			QPx16 = 16 * QP;
			v = &(image[y*stride + Bx]) - 5*stride;

			/* decide whether to use DC mode on a block-by-block basis */
			useDC = deblock_vert_useDC(v, stride);
						
			if (useDC) {
 				/* we are in DC mode for this block.  But we only want to filter low-energy areas */
				
				/* decide whether the filter should be on or off for this block */
				DC_on = deblock_vert_DC_on(v, stride, QP);
				
				if (DC_on) { /* use DC offset mode */
				
						v = &(image[y*stride + Bx])- 5*stride;
						
						/* copy the block we're working on and unpack to 16-bit values */
						/* not needed for plain C version */
						//deblock_vert_copy_and_unpack(stride, &(v[stride]), &(v_local[2]), 8);
						//deblock_vert_choose_p1p2(v, stride, p1p2, QP);
					
						deblock_vert_lpf9(v_local, p1p2, v, stride, QP); 

						#ifdef SHOWDECISIONS_V
						if (!chromaFlag) {
							v[4*stride  ] = 
							v[4*stride+1] = 
							v[4*stride+2] = 
							v[4*stride+3] = 
							v[4*stride+4] = 
							v[4*stride+5] = 
							v[4*stride+6] = 
							v[4*stride+7] = 255;
						}  
						#endif
					}
			}

			if (!useDC) { /* use the default filter */

				v = &(image[y*stride + Bx])- 5*stride;
			
				deblock_vert_default_filter(v, stride, QP);

				#ifdef SHOWDECISIONS_V
				if (!chromaFlag) {
					v[4*stride  ] = 
					v[4*stride+1] = 
					v[4*stride+2] = 
					v[4*stride+3] = 
					v[4*stride+4] = 
					v[4*stride+5] = 
					v[4*stride+6] = 
					v[4*stride+7] = 0;
				}  
				#endif
			}
		} 
	}
}







/* this is the deringing filter */
void dering( uint8_t *image, int width, int height, int stride, QP_STORE_T *QP_store, int QP_stride, int chroma) {
	int x, y, h, v, i, j;
	uint8_t *b8x8, *b10x10;
	uint8_t b8x8filtered[64];
	int QP, max_diff;
	uint8_t min, max, thr, range;
	uint16_t indicesP[10];  /* bitwise array of binary indices above threshold */
	uint16_t indicesN[10];  /* bitwise array of binary indices below threshold */
	uint16_t indices3x3[8]; /* bitwise array of pixels where we should filter */
	uint16_t sr;
	
	/* loop over all the 8x8 blocks in the image... */
	/* don't process outer row of blocks for the time being. */
	for (y=8; y<height-8; y+=8) {
		for (x=8; x< width-8; x+=8) {
		
			/* QP for this block.. */
			QP = chroma ? QP_store[y/8*QP_stride+x/8]
			            : QP_store[y/16*QP_stride+x/16];	
	
			/* pointer to the top left pixel in 8x8   block */
			b8x8   = &(image[stride*y + x]);
			/* pointer to the top left pixel in 10x10 block */
			b10x10 = &(image[stride*(y-1) + (x-1)]);
			
			/* Threshold detirmination - find min and max grey levels in the block */
			min = 255; max = 0;
			for (v=0; v<8; v++) {
				for (h=0; h<8; h++) {
					min = b8x8[stride*v + h] < min ? b8x8[stride*v + h] : min;				
					max = b8x8[stride*v + h] > max ? b8x8[stride*v + h] : max;				
				}
			} 
			/* Threshold detirmination - compute threshold and dynamic range */
			thr = (max + min + 1) / 2;
			range = max - min;
			
			/* Threshold rearrangement not implemented yet */
			
			/* Index aquisition */
			for (j=0; j<10; j++) {
				indicesP[j] = 0;
				for (i=0; i<10; i++) {
					if (b10x10[j*stride+i] >= thr) indicesP[j] |= (2 << i);
				}
				indicesN[j] = ~indicesP[j];			
			}
			
			/* Adaptive filtering */
			/* need to identify 3x3 blocks of '1's in indicesP and indicesN */
			for (j=0; j<10; j++) {
				indicesP[j] = (indicesP[j]<<1) & indicesP[j] & (indicesP[j]>>1);				
				indicesN[j] = (indicesN[j]<<1) & indicesN[j] & (indicesN[j]>>1);				
			}			
			for (j=1; j<9; j++) {
				indices3x3[j-1]  = indicesP[j-1] & indicesP[j] & indicesP[j+1];				
				indices3x3[j-1] |= indicesN[j-1] & indicesN[j] & indicesN[j+1];				
			}			

			for (v=0; v<8; v++) {
				sr = 4;
				for (h=0; h<8; h++) {
					if (indices3x3[v] & sr) {
						b8x8filtered[8*v + h] = ( 8
						 + 1 * b10x10[stride*(v+0) + (h+0)] + 2 * b10x10[stride*(v+0) + (h+1)] + 1 * b10x10[stride*(v+0) + (h+2)]
						 + 2 * b10x10[stride*(v+1) + (h+0)] + 4 * b10x10[stride*(v+1) + (h+1)] + 2 * b10x10[stride*(v+1) + (h+2)]
						 + 1 * b10x10[stride*(v+2) + (h+0)] + 2 * b10x10[stride*(v+2) + (h+1)] + 1 * b10x10[stride*(v+2) + (h+2)]
						) / 16;
					}
					sr <<= 1;
				}
			}
			
			/* Clipping */
			max_diff = QP/2;
			for (v=0; v<8; v++) {
				sr = 4;
				for (h=0; h<8; h++) {
					if (indices3x3[v] & sr) {
						if        (b8x8filtered[8*v + h] - b8x8[stride*v + h] >  max_diff) {
							b8x8[stride*v + h] = b8x8[stride*v + h] + max_diff;
						} else if (b8x8filtered[8*v + h] - b8x8[stride*v + h] < -max_diff) {
							b8x8[stride*v + h] = b8x8[stride*v + h] - max_diff;	
						} else {
							b8x8[stride*v + h] = b8x8filtered[8*v + h];
						}  								
					}
					sr <<= 1;
				}
			}

		}
	}


}





/* This function is more or less what Andrea wanted: */
void postprocess(unsigned char * src[], int src_stride,
                 unsigned char * dst[], int dst_stride, 
                 int horizontal_size,   int vertical_size, 
                 QP_STORE_T *QP_store,  int QP_stride,
					  int mode) {
					  
	uint8_t *Y, *U, *V;
	int x, y;

	if (!(mode & PP_DONT_COPY)) {
		/* First copy source to destination... */
		/* luma */
		for (y=0; y<vertical_size; y++) {
			for (x=0; x<horizontal_size; x++) {
				(dst[0])[y*dst_stride + x] = (src[0])[y*src_stride + x];
			}
		}
		/* chroma */
		for (y=0; y<vertical_size/2; y++) {
			for (x=0; x<horizontal_size/2; x++) {
				(dst[1])[y*dst_stride/2 + x] = (src[1])[y*src_stride/2 + x];
				(dst[2])[y*dst_stride/2 + x] = (src[2])[y*src_stride/2 + x];
			}
		}
	}
					  
	Y = dst[0];
	U = dst[1];
	V = dst[2];
	
	if (mode & PP_DEBLOCK_Y_H) {
		deblock_horiz(Y, horizontal_size,   vertical_size,   dst_stride, QP_store, QP_stride, 0);
	}
	if (mode & PP_DEBLOCK_Y_V) {
		deblock_vert( Y, horizontal_size,   vertical_size,   dst_stride, QP_store, QP_stride, 0);
	}
	if (mode & PP_DEBLOCK_C_H) {
		deblock_horiz(U, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
		deblock_horiz(V, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
	}
	if (mode & PP_DEBLOCK_C_V) {
		deblock_vert( U, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
		deblock_vert( V, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
	}
	if (mode & PP_DERING_Y) {
		dering(       Y, horizontal_size,   vertical_size,   dst_stride, QP_store, QP_stride, 0);
	}
	if (mode & PP_DERING_C) {
		dering(       U, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
		dering(       V, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
	}

}








⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -