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

📄 deintl.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	int lineCounter;
	
	//  reorder the frame, even field on top, Y, Cr then Cb
	for(lineCounter=0;lineCounter<lines;lineCounter+=2)
	{
		memcpy(tempFrame+((lineCounter>>1)*(pels)), /* Flawfinder: ignore */
			frame+lineCounter*pels,pels);
	}
	for(lineCounter=0;lineCounter<(lines>>1);lineCounter+=2)
	{
		memcpy(tempFrame+((lineCounter>>1)*(pels>>1)) + (pels*lines) /* Flawfinder: ignore */
			,frame+(pels*lines)+lineCounter*(pels>>1),(pels>>1));
	}
	for(lineCounter=0;lineCounter<(lines>>1);lineCounter+=2)
	{
		memcpy(tempFrame+((lineCounter>>1)*(pels>>1)) +(pels*lines*5/4) /* Flawfinder: ignore */
			,frame+(pels*lines*5/4)+lineCounter*(pels>>1),(pels>>1));
	}
	for(lineCounter=1;lineCounter<lines+1;lineCounter+=2)
	{
		memcpy(tempFrame+((lines-1)-(lineCounter>>1))*pels, /* Flawfinder: ignore */
			frame+lineCounter*pels,pels);
	}
	for(lineCounter=1;lineCounter<(lines>>1)+1;lineCounter+=2)
	{
		memcpy(tempFrame + (pels*lines) + /* Flawfinder: ignore */
			(((lines>>1)-1)-(lineCounter>>1))*(pels>>1),frame+(pels*lines)+lineCounter*(pels>>1),(pels>>1));
	}
	for(lineCounter=1;lineCounter<(lines>>1)+1;lineCounter+=2)
	{
		memcpy(tempFrame + (pels*lines*5/4) + /* Flawfinder: ignore */
			(((lines>>1)-1)-(lineCounter>>1))*(pels>>1),frame+(pels*lines*5/4)+lineCounter*(pels>>1),(pels>>1));
	}
	memcpy(frame,tempFrame,(pels*lines*3)/2); /* Flawfinder: ignore */

	return;
}


#ifdef _M_IX86

////////////////////////////////////////////////////////
//
//	Deinterlace_I420_MMX
//
//	MMX optimized deinterlacing of I420 data, using both fields
//
////////////////////////////////////////////////////////

static void
Deinterlace_I420_MMX(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
	int line_shift;
	int pels_div8;

	pels_div8 = (pels >> 3);			// round down
	line_shift = ((pitch << 1) - (pels & ~7));

	__asm {

		mov			ecx, lines			// ecx -> lines		
		shr			ecx, 1				// ecx -> lines/2

		mov			edx, pitch			// pitch
		mov			eax, edx
		neg			eax					// -pitch

		mov			esi, frame			// esi -> current frame
		add			esi, pitch;			// move esi to the next line

		pxor		mm7, mm7

ALIGN 16
line_loop:
		mov			ebx, pels_div8		// ebx -> pels/8 (rounded down)
ALIGN 16
pel_loop:
										// median = (upper & A) | (mid & B) | (lower & C)
										// e.g....
		movq		mm0,[esi+eax]		//	1	2	1	3	2	3	1	3	= mm0	= (upper)
		movq		mm1,[esi]			//	2	1	3	1	3	2	1	3	= mm1	= (mid)
		movq		mm2,[esi+edx]		//	3	3	2	2	1	1	2	3	= mm2	= (lower)

		movq		mm3,mm1				//	2	1	3	1	3	2	1	3	= mm3
		psubusb		mm3,mm0				//	1	0	2	0	1	0	0	0	= mm3	
		pcmpeqb		mm3,mm7				//	0	1	0	1	0	1	1	1	= mm3	= (upper > mid)

		movq		mm4,mm2				//	3	3	2	2	1	1	2	3	= mm4	
		psubusb		mm4,mm1				//	1	2	0	1	0	0	1	0	= mm4
		pcmpeqb		mm4,mm7				//	0	0	1	0	1	1	0	1	= mm4	= (mid > lower)

		movq		mm6,mm3				//	0	1	0	1	0	1	1	1	= mm6
		pxor		mm6,mm4				//	0	1	1	1	1	0	1	0	= mm6	= ~(B)
		pandn		mm6,mm1				//	2	0	0	0	0	2	1	0	= mm6	= (mid & B)

		movq		mm5,mm2				//	3	3	2	2	1	1	2	3	= mm5	
		psubusb		mm5,mm0				//	2	1	1	0	0	0	1	0	= mm5
		pcmpeqb		mm5,mm7				//	0	0	0	1	1	1	0	1	= mm5	= (upper > lower)

		movq		mm1,mm5				//	0	0	0	1	1	1	0	1	= mm1
		pxor		mm1,mm3				//	0	1	0	0	1	0	1	0	= mm1	= (A)
		pand		mm1,mm0				//	0	2	0	0	2	0	1	0	= mm1	= (upper & A)

		por  		mm6,mm1				//	2	2	0	0	2	2	1	0	= mm6	= (upper & A) | (mid & B)

		pxor		mm4,mm5				//	0	0	1	1	0	0	0	1	= mm4	= (C)
		pand		mm4,mm2				//	0	0	2	2	0	0	0	3	= mm4	= (lower & C)

		por  		mm6,mm4				//	2	2	2	2	2	2	1	3	= mm6	= (upper & A) | (mid & B) | (lower & C)

		movq		[esi],mm6			

		lea			esi,[esi+8]		

		dec			ebx
		jnz			pel_loop

		// any pels left???
		mov			ebx, pels
		and			ebx, 0x07
		jnz			last_pels

		add			esi, line_shift;	// move esi to the next line

		dec			ecx
		jnz			line_loop
		jmp			done

last_pels:
		// take care of last four pels
		movd		mm0,[esi+eax]
		movd		mm1,[esi]
		movd		mm2,[esi+edx]

		movq		mm3,mm1				//	2	1	3	1	3	2	1	3	= mm3
		psubusb		mm3,mm0				//	1	0	2	0	1	0	0	0	= mm3	
		pcmpeqb		mm3,mm7				//	0	1	0	1	0	1	1	1	= mm3	= (upper > mid)

		movq		mm4,mm2				//	3	3	2	2	1	1	2	3	= mm4	
		psubusb		mm4,mm1				//	1	2	0	1	0	0	1	0	= mm4
		pcmpeqb		mm4,mm7				//	0	0	1	0	1	1	0	1	= mm4	= (mid > lower)

		movq		mm6,mm3				//	0	1	0	1	0	1	1	1	= mm6
		pxor		mm6,mm4				//	0	1	1	1	1	0	1	0	= mm6	= ~(B)
		pandn		mm6,mm1				//	2	0	0	0	0	2	1	0	= mm6	= (mid & B)

		movq		mm5,mm2				//	3	3	2	2	1	1	2	3	= mm5	
		psubusb		mm5,mm0				//	2	1	1	0	0	0	1	0	= mm5
		pcmpeqb		mm5,mm7				//	0	0	0	1	1	1	0	1	= mm5	= (upper > lower)

		movq		mm1,mm5				//	0	0	0	1	1	1	0	1	= mm1
		pxor		mm1,mm3				//	0	1	0	0	1	0	1	0	= mm1	= (A)
		pand		mm1,mm0				//	0	2	0	0	2	0	1	0	= mm1	= (upper & A)

		por  		mm6,mm1				//	2	2	0	0	2	2	1	0	= mm6	= (upper & A) | (mid & B)

		pxor		mm4,mm5				//	0	0	1	1	0	0	0	1	= mm4	= (C)
		pand		mm4,mm2				//	0	0	2	2	0	0	0	3	= mm4	= (lower & C)

		por  		mm6,mm4				//	2	2	2	2	2	2	1	3	= mm6	= (upper & A) | (mid & B) | (lower & C)

		movd		[esi],mm6			

		add			esi, line_shift;	// move esi to the next line

		dec			ecx
		jnz			line_loop

done:
		emms
	}
}


////////////////////////////////////////////////////////
//
//	Deinterlace_I420_Slow
//
//	Slow deinterlacing of I420 data, 
//  with Rigorous Edge Interpolation using 
//  Optical Flow
//
////////////////////////////////////////////////////////
static void
Deinterlace_I420_EdgeInterp(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
	int line, pel, mcountfr=1, mcountfi=1, D1=0;
	unsigned char *fpr, *fpg, *pfpg, *pfpr;
	unsigned char *fp1, *pfp1;
	unsigned char *fp2, *pfp2;
	unsigned char *fp3, *pfp3;
	# define IFrMThresh 10
	# define IFsMThresh 20
	# define FlowThresh 1200
	# define StrictFlowThresh 5	
	# define adj 10
	int frm =1;
	int diff1;
	
	int tmp;
	int *tempLine, *ptempLine;
	tempLine = (int*)malloc(pels*sizeof(int));		

	for (line = 1; line < lines - 2; line += 2)
	{
	
		int a,b,c,d,e,f;
		int D1 =0;		
		unsigned char *tfp3;
		memset(tempLine, -1, pels*sizeof(int));

		fpr = frame + line*pitch;
		
		fpg = fpr;

		
		fp2 = fpg + adj;
		
		ptempLine = &tempLine[0] + adj;


		// prev line
		fp1 = fp2 - pitch;
		
		// next line
		fp3 = fp2 + pitch;
		
		// previous frame
		if (prev_frame != 0)
		{
			pfpr = prev_frame + line * pitch;
			pfpg = pfpr;
			pfp2 = pfpg + adj;
			pfp1 = pfp2 - pitch;
			pfp3 = pfp2 + pitch;
		}
		else
		{
			Deinterlace_RGB24_Fast(frame, prev_frame, pels, lines, pitch, format);
			free(tempLine);
			return;
		}

		
		// initialize
		for (pel = adj; pel < (pels - adj); pel += 1)
		{
			
			int moving = 0;
			int fi, fD;
			int minf;
			int pix;
			int error2, error21, error22, error3, d2=0, j;

			// Load *next* pels
			a = (int)(*fp1);
			b = (int)(*fp2);
			c = (int)(*fp3);

			// intra frame
			D1 = *(fp1+1) - *(fp1-1);
			D1 = ABS(D1);
			if( D1 > 20) { 
					d = *(fp1+1);
					e = *(fp1-1);
					tfp3 = fp3;
					tmp = (a - *(tfp3));					
					minf = DIFF_FCN(tmp);
					tmp = (d - *(tfp3+1));
					minf += DIFF_FCN(tmp);
					tmp = (e - *(tfp3-1));
					minf += DIFF_FCN(tmp);

					fi = 0;
					tfp3--;					
					for (j=-1; j>=-adj; j--) {	
						tmp = (a - *(tfp3));
						fD = DIFF_FCN(tmp);
						if (fD > minf)
							goto gskip;
						tmp = (d - *(tfp3+1));
						fD= fD + DIFF_FCN(tmp);
						if (fD > minf)
							goto gskip;
						tmp = (e - *(tfp3-1));
						fD= fD + DIFF_FCN(tmp);
						if(fD<minf) {
							minf = fD;
							fi = j;
						}
gskip:
						tfp3--;						
					}

					tfp3 = fp3 + 1;
					for (j=1; j<=adj; j++) {	
						tmp = (a - *(tfp3));
						fD = DIFF_FCN(tmp);
						if (fD > minf)
							goto gskip2;
						tmp = (d - *(tfp3+1));
						fD += DIFF_FCN(tmp);
						if (fD > minf)
							goto gskip2;
						tmp = (e - *(tfp3-1));
						fD += DIFF_FCN(tmp);
						if(fD<minf) {
							minf = fD;
							fi = j;
						}
gskip2:
						tfp3++;						
					}

					#ifdef TIME_DEINTERLACE
					//num_flow++;
					#endif
					
					if (minf < FlowThresh)  {
						
						if ((fi == 1) || (fi == -1) || (fi == 0)) {							
							tempLine[pel] = (*fp1 + *fp3)/2;
						} else {
							
							f = *(fp3+ fi);
							pix = (a + f) / 2;
							d2 = (int)(fi)/2;
						
							f = *(fp1 + d2);
							tmp = (pix - f);
							error2 = ABS(tmp);
							
							f = *(fp1 + d2 + 1);
							pix = (d + *(fp3 + fi + 1))/2;
							tmp = (pix - f);
							error21 = ABS(tmp);

							f = *(fp1 + d2 -1);
							pix = (e + *(fp3 + fi - 1))/2;
							tmp = (pix - f);
							error22 = ABS(tmp);
														

							if(error2 < 15 && ( ((error21 < 15) && (error22 > 25)) || ((error21 > 25) && (error22 < 15)) ) ) {
								
								pix = (a + *(fp3+fi)) / 2;
								tempLine[pel + d2] = pix;
							
								pix = (d + *(fp3 + fi + 1))/2;
								tempLine[pel + d2 + 1] = pix;

								pix = (e + *(fp3 + fi - 1))/2;
								tempLine[pel + d2 - 1] = pix;								

								goto gadvance;
							}
							
							pix = (a + *(fp3 + fi))/2;
							f = *(fp3 + d2);
							tmp = (pix - f);
							error3 = ABS(tmp);
							
							f = *(fp3 + d2 + 1);
							pix = (d + *(fp3 + fi + 1))/2;
							tmp = (pix - f);
							error21 = ABS(tmp);
							
							f = *(fp3 + d2 -1);
							pix = (e + *(fp3 + fi - 1))/2;
							tmp = (pix - f);
							error22 = ABS(tmp);	
							
							pix = (a + *(fp3 + fi))/2;

							if( error3 < 15 && ( ((error21 < 15) && (error22 > 25)) || ((error21 > 25) && (error22 < 15))) ) {
							
								tempLine[pel + d2] = pix;
							
								pix = (d + *(fp3 + fi + 1))/2;
								tempLine[pel + d2 + 1] = pix;

								pix = (e + *(fp3 + fi - 1))/2;
								tempLine[pel + d2 - 1] = pix;
													
							
								goto gadvance;
							} else {
								/*
								*fp2 = 0;
								*fpr2 = 0;
								*fpb2 = 255;
								tempLine[pel] = 0;
								*/
								
							}
							
						}
					} else {
						/*
						*fp2 = 0;
						*fpr2 = 255;
						*fpb2 = 0;
						tempLine[pel] = 0;
						*/
						
					}

			}
gadvance:
			fp1++;
			fp2++;
			fp3++;
			pfp1++;
			pfp2++;
			pfp3++;
			ptempLine++;
		}

		// current frame
		// current line
		fp2 = fpg;
		// prev line
		fp1 = fp2 - pitch;
		// next line
		fp3 = fp2 + pitch;
		// current frame
		
		//prev frame
		// current line
		pfp2 = pfpg;
		// prev line
		pfp1 = pfp2 - pitch;
		// next line
		pfp3 = pfp2 + pitch;

		ptempLine = &tempLine[0];		

		for (pel = 0; pel < pels-1; pel += 1)		
		{			
			// change
					
				tmp = (*fp1 - *(fp3));
				diff1 = DIFF_FCN(tmp);
				tmp = (*(fp1-1) - *(fp3-1));
				diff1 += DIFF_FCN(tmp);
				tmp = (*(fp3+1) - *(pfp3+1));
				diff1 += DIFF_FCN(tmp);				

				if( ABS(diff1) > 4800 ) {
					// horiz
					tmp = (*fp1 - *(pfp1));
					diff1 = DIFF_FCN(tmp);
					tmp = (*(fp1-1) - *(pfp1-1));
					diff1 += DIFF_FCN(tmp);
					tmp = (*(fp1+1) - *(pfp1+1));
					diff1 += DIFF_FCN(tmp);
					tmp = (*fp3 - *(pfp3));
					diff1 += DIFF_FCN(tmp);
					tmp = (*(fp3-1) - *(pfp3-1));
					diff1 += DIFF_FCN(tmp);
					tmp = (*(fp3+1) - *(pfp3+1));
					diff1 += DIFF_FCN(tmp);
					
				
					if (diff1 < 2400) {
						// not moving						
					
						*fp2 = MEDIAN_3(*fp1,*fp2,*fp3);											
					
					} else {

						if (*ptempLine != -1) {
							*fp2 = (unsigned char) *ptempLine;
						} else {
							tmp = (*fp1 + *fp3)/2;
							*fp2 = 	(unsigned char) tmp;	
						}						

						#ifdef TIME_DEINTERLACE
							num_avg++;
						#endif				
			
					}
				} else {
				// not horiz
				// avg
					if (*ptempLine != -1) {
						D1 = *(fp1+1) - *(fp1-1);
						D1 = ABS(D1);
						if( D1 > 20) { 
							*fp2 = (unsigned char) *ptempLine;
						} else {
							tmp = (*fp1 + *fp3)/2;
							*fp2 = 	(unsigned char) tmp;															
								// not vertical								
						}
					} else {
						tmp = (*fp1 + *fp3)/2;
						*fp2 = 	(unsigned char) tmp;							
					}					
			
					#ifdef TIME_DEINTERLACE
						num_avg++;
					#endif	
											
				}

			
			fp1++;
			fp2++;
			fp3++;
			pfp1++;
			pfp2++;
			pfp3++;
			ptempLine++;
		}
	}
	
	free(tempLine);	

	return;

}	


#endif





















































⌨️ 快捷键说明

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