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

📄 deintl.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					step2v_corr += MSQUARED(tmp);
					tmp = f1[4] - f1[5];
					step1h_corr += MSQUARED(tmp);
					tmp = f1[4] - f1[6];
					step2h_corr += MSQUARED(tmp);

					tmp = f0[7] - f1[7];
					step1v_corr += MSQUARED(tmp);
					tmp = f0[7] - f2[7];
					step2v_corr += MSQUARED(tmp);
					tmp = f1[6] - f1[7];
					step1h_corr += MSQUARED(tmp);
					tmp = f1[6] - f1[8];
					step2h_corr += MSQUARED(tmp);

					f0 += 2 * pitch;
					f1 += 2 * pitch;
					f2 += 2 * pitch;
				}

				// These conditions indicate the block 
				// is very likely interlaced.
				if (step1v_corr > step2v_corr && 
					step1h_corr < (40*40*4*4) &&
					step2v_corr < (40*40*4*4))
				{
					interlaced_blocks++;
				}

				// These conditions indicate the block 
				// is very likely progressive.
				if (step1v_corr < 2 * step2v_corr && 
					step1h_corr < (40*40*4*4) &&
					step1v_corr < (40*40*4*4))
				{
					progressive_blocks++;
				}

				// Maintain totals
				step1v_tot += step1v_corr;
				step2v_tot += step2v_corr;
				step1h_tot += step1h_corr;
				step2h_tot += step2h_corr;
			}

			// Jump to the next 8x8 block
			fp += 8 * SKIP_FACTOR;
			pp += 8 * SKIP_FACTOR;
		}
	}

#if (SKIP_FACTOR != 1)
	// If we're skipping some 8x8 block, 
	// acount for this by multiplying by skip factor

	interlaced_blocks *= SKIP_FACTOR;
	progressive_blocks *= SKIP_FACTOR;

	step1v_tot *= SKIP_FACTOR;
	step2v_tot *= SKIP_FACTOR;
	step1h_tot *= SKIP_FACTOR;
	step2h_tot *= SKIP_FACTOR;

#endif

	// Scale these values. 
	// (Done to prevent overflow during later multiplies)
	step1v_tot /= image_size;
	step2v_tot /= image_size;
	step1h_tot /= image_size;
	step2h_tot /= image_size;

	// Interlaced Tests
	if (interlaced_blocks > progressive_blocks &&
		interlaced_blocks > (image_size >> 12))
	{
		return INTL_WEAK_INTERLACE;
	}

	if (step1v_tot * step2h_tot > step1h_tot * step2v_tot &&
		step1v_tot > step2v_tot &&
		2 * interlaced_blocks > progressive_blocks &&
		interlaced_blocks > (image_size >> 10))
	{
		return INTL_WEAK_INTERLACE;
	}

	// Progressive Tests
	if (progressive_blocks > (image_size >> 10) &&
		progressive_blocks > (interlaced_blocks << 4))
	{
		return INTL_WEAK_PROGRESSIVE;
	}

	return INTL_NO_DETECTION;

}

////////////////////////////////////////////////////////
//
//	Deinterlace_RGB24_Fast
//
//	Fast deinterlacing of RGB24 data, using both fields
//
////////////////////////////////////////////////////////

static void
Deinterlace_RGB24_Fast(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
	int line, pel;
	unsigned char *fp1,*pfp1;
	unsigned char *fp2,*pfp2;
	unsigned char *fp3,*pfp3;

	unsigned char *fpr;
	unsigned char *fpb;

	// Only handle RGB for now...
	if (format != INTL_FORMAT_RGB24)
		return;

	for (line = 1; line < lines - 2; line += 2)
	{
		unsigned int a,b,c,d,e,f;
		int c_nw,c_ne,c_se,c_sw;
		int diff,tmp;
		int prev_mode = INTL_LINE_REMOVE_AVG;
		int mode = INTL_LINE_REMOVE_AVG;
		int next_mode = INTL_LINE_REMOVE_AVG;

		// current frame
		fpr = frame + line * pitch;
		fp2 = fpr + pels * lines;
		fp1 = fp2 - pitch;
		fp3 = fp2 + pitch;
		fpb = fp2 + pels * lines;

		// previous frame
		if (prev_frame != 0)
		{
			pfp2 = prev_frame + pels * lines + line * pitch;
			pfp1 = pfp2 - pitch;
			pfp3 = pfp2 + pitch;
		}
		else
		{
			pfp2 = fp2;
			pfp1 = fp1;
			pfp3 = fp3;
		}

		// initialize
		for (pel = 0; pel < pels - 4; pel += 4)
		{
			// Load *next* 4 pels
			a = ((unsigned int *)fp1)[1];
			b = ((unsigned int *)fp2)[1];
			c = ((unsigned int *)fp3)[1];

			// Get corners
			c_nw = (a >> 24);
			c_ne = (a & 0xff);
			c_sw = (c >> 24);
			c_se = (c & 0xff);

			// Edge detect
			tmp = c_nw + c_ne - c_sw - c_se;
			if ((tmp < 100) && (tmp > -100))
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;
			}

			tmp = c_ne + c_se - c_nw - c_sw;
			if (tmp > 100)
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;
			}
			if (tmp < -100)
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;
			}

			// Load previous pels
			d = ((unsigned int *)pfp1)[1];
			e = ((unsigned int *)pfp2)[1];
			f = ((unsigned int *)pfp3)[1];

			// Diff with previous pels
			tmp = c_nw;
			tmp -= (d >> 24);
			diff = tmp ^ (tmp >> 31);

			tmp = c_ne;
			tmp -= (d & 0xff);
			diff += tmp ^ (tmp >> 31);

			if (diff > 100)
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;
			}

			tmp = c_sw;
			tmp -= (f >> 24);
			diff += tmp ^ (tmp >> 31);

			tmp = c_se;
			tmp -= (f & 0xff);
			diff += tmp ^ (tmp >> 31);

			if (diff > 200)
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;
			}

			tmp = (b >> 24);
			tmp -= (e >> 24);
			diff += tmp ^ (tmp >> 31);
			tmp = (b & 0xff);
			tmp -= (e & 0xff);
			diff += tmp ^ (tmp >> 31);

			if (diff > 300)
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;
			}

			next_mode = INTL_LINE_REMOVE_MEDIAN;

proc:
			if (mode == INTL_LINE_REMOVE_MEDIAN || prev_mode == INTL_LINE_REMOVE_MEDIAN || next_mode == INTL_LINE_REMOVE_MEDIAN)
			{
				// median
				fp2[0] = MEDIAN_3(fp1[0],fp2[0],fp3[0]);
				fp2[1] = MEDIAN_3(fp1[1],fp2[1],fp3[1]);
				fp2[2] = MEDIAN_3(fp1[2],fp2[2],fp3[2]);
				fp2[3] = MEDIAN_3(fp1[3],fp2[3],fp3[3]);

				fpr[0] = MEDIAN_3(fpr[-pitch],fpr[0],fpr[pitch]);
				fpr[1] = MEDIAN_3(fpr[-pitch+1],fpr[1],fpr[pitch+1]);
				fpr[2] = MEDIAN_3(fpr[-pitch+2],fpr[2],fpr[pitch+2]);
				fpr[3] = MEDIAN_3(fpr[-pitch+3],fpr[3],fpr[pitch+3]);

				fpb[0] = MEDIAN_3(fpb[-pitch],fpb[0],fpb[pitch]);
				fpb[1] = MEDIAN_3(fpb[-pitch+1],fpb[1],fpb[pitch+1]);
				fpb[2] = MEDIAN_3(fpb[-pitch+2],fpb[2],fpb[pitch+2]);
				fpb[3] = MEDIAN_3(fpb[-pitch+3],fpb[3],fpb[pitch+3]);

#ifdef TIME_DEINTERLACE
				num_med++;
#endif

			}
			else
			{
				// average
				a = ((unsigned int *)fp1)[0];
				c = ((unsigned int *)fp3)[0];
				((unsigned int*)fp2)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);

				a = ((unsigned int *)(fpr - pitch))[0];
				c = ((unsigned int *)(fpr + pitch))[0];
				((unsigned int*)fpr)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);

				a = ((unsigned int *)(fpb - pitch))[0];
				c = ((unsigned int *)(fpb + pitch))[0];
				((unsigned int*)fpb)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);

#ifdef TIME_DEINTERLACE
				num_avg++;
#endif
			}

			prev_mode = mode;
			mode = next_mode;

			fp1 += 4;
			fp2 += 4;
			fp3 += 4;

			pfp1 += 4;
			pfp2 += 4;
			pfp3 += 4;

			fpr += 4;
			fpb += 4;
		}

		// last 4 pels
		if (mode == INTL_LINE_REMOVE_MEDIAN || prev_mode == INTL_LINE_REMOVE_MEDIAN)
		{
			// median
			fp2[0] = MEDIAN_3(fp1[0],fp2[0],fp3[0]);
			fp2[1] = MEDIAN_3(fp1[1],fp2[1],fp3[1]);
			fp2[2] = MEDIAN_3(fp1[2],fp2[2],fp3[2]);
			fp2[3] = MEDIAN_3(fp1[3],fp2[3],fp3[3]);

			fpr[0] = MEDIAN_3(fpr[-pitch],fpr[0],fpr[pitch]);
			fpr[1] = MEDIAN_3(fpr[-pitch+1],fpr[1],fpr[pitch+1]);
			fpr[2] = MEDIAN_3(fpr[-pitch+2],fpr[2],fpr[pitch+2]);
			fpr[3] = MEDIAN_3(fpr[-pitch+3],fpr[3],fpr[pitch+3]);

			fpb[0] = MEDIAN_3(fpb[-pitch],fpb[0],fpb[pitch]);
			fpb[1] = MEDIAN_3(fpb[-pitch+1],fpb[1],fpb[pitch+1]);
			fpb[2] = MEDIAN_3(fpb[-pitch+2],fpb[2],fpb[pitch+2]);
			fpb[3] = MEDIAN_3(fpb[-pitch+3],fpb[3],fpb[pitch+3]);

#ifdef TIME_DEINTERLACE
			num_med++;
#endif

		}
		else
		{
			// average
			a = ((unsigned int *)fp1)[0];
			c = ((unsigned int *)fp3)[0];
			((unsigned int*)fp2)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);

			a = ((unsigned int *)(fpr - pitch))[0];
			c = ((unsigned int *)(fpr + pitch))[0];
			((unsigned int*)fpr)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);

			a = ((unsigned int *)(fpb - pitch))[0];
			c = ((unsigned int *)(fpb + pitch))[0];
			((unsigned int*)fpb)[0] = (((a^c)>>1) & 0x7F7F7F7F) + (a&c);

#ifdef TIME_DEINTERLACE
			num_avg++;
#endif
		}
	}

}


////////////////////////////////////////////////////////
//
//	Deinterlace_RGB24
//
//	Slow deinterlacing of RGB24 data, using both fields
//
////////////////////////////////////////////////////////

static void
Deinterlace_RGB24(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
	int line, pel;
	unsigned char *fp1,*pfp1;
	unsigned char *fp2,*pfp2;
	unsigned char *fp3,*pfp3;
	int tmp;

	// Only handle RGB for now...
	if (format != INTL_FORMAT_RGB24)
		return;

	for (line = 1; line < lines - 2; line += 2)
	{
		int a,b,c,d,e;
		int mode = INTL_LINE_REMOVE_AVG;

		fp1 = frame + line * pitch;
		fp2 = frame + pels*lines + line * pitch;
		fp3 = frame + 2 * pels*lines + line * pitch;

		if (prev_frame != 0)
		{
			pfp1 = prev_frame + line * pitch;
			pfp2 = prev_frame + pels*lines + line * pitch;
			pfp3 = prev_frame + 2 * pels*lines + line * pitch;
		}
		else
		{
			pfp1 = fp1;
			pfp2 = fp2;
			pfp3 = fp3;
		}

		// initialize
		tmp = (int)(fp1[-pitch]) + (int)(fp2[-pitch]) + (int)(fp3[-pitch]) - (int)(pfp1[-pitch]) - (int)(pfp2[-pitch]) - (int)(pfp3[-pitch]);
		a = DIFF_FCN(tmp);
		tmp = (int)(fp1[0]) + (int)(fp2[0]) + (int)(fp3[0]) - (int)(pfp1[0]) - (int)(pfp2[0]) - (int)(pfp3[0]);
		a += DIFF_FCN(tmp);
		tmp = (int)(fp1[pitch]) + (int)(fp2[pitch]) + (int)(fp3[pitch]) - (int)(pfp1[pitch]) - (int)(pfp2[pitch]) - (int)(pfp3[pitch]);
		a += DIFF_FCN(tmp);

		fp1++;pfp1++;
		fp2++;pfp2++;
		fp3++;pfp3++;

		tmp = (int)(fp1[-pitch]) + (int)(fp2[-pitch]) + (int)(fp3[-pitch]) - (int)(pfp1[-pitch]) - (int)(pfp2[-pitch]) - (int)(pfp3[-pitch]);
		b = DIFF_FCN(tmp);
		tmp = (int)(fp1[0]) + (int)(fp2[0]) + (int)(fp3[0]) - (int)(pfp1[0]) - (int)(pfp2[0]) - (int)(pfp3[0]);
		b += DIFF_FCN(tmp);
		tmp = (int)(fp1[pitch]) + (int)(fp2[pitch]) + (int)(fp3[pitch]) - (int)(pfp1[pitch]) - (int)(pfp2[pitch]) - (int)(pfp3[pitch]);
		b += DIFF_FCN(tmp);

		fp1++;pfp1++;
		fp2++;pfp2++;
		fp3++;pfp3++;

		tmp = (int)(fp1[-pitch]) + (int)(fp2[-pitch]) + (int)(fp3[-pitch]) - (int)(pfp1[-pitch]) - (int)(pfp2[-pitch]) - (int)(pfp3[-pitch]);
		c = DIFF_FCN(tmp);
		tmp = (int)(fp1[0]) + (int)(fp2[0]) + (int)(fp3[0]) - (int)(pfp1[0]) - (int)(pfp2[0]) - (int)(pfp3[0]);
		c += DIFF_FCN(tmp);
		tmp = (int)(fp1[pitch]) + (int)(fp2[pitch]) + (int)(fp3[pitch]) - (int)(pfp1[pitch]) - (int)(pfp2[pitch]) - (int)(pfp3[pitch]);
		c += DIFF_FCN(tmp);

		tmp = (int)(fp1[-pitch+1]) + (int)(fp2[-pitch+1]) + (int)(fp3[-pitch+1]) - (int)(pfp1[-pitch+1]) - (int)(pfp2[-pitch+1]) - (int)(pfp3[-pitch+1]);
		d = DIFF_FCN(tmp);
		tmp = (int)(fp1[1]) + (int)(fp2[1]) + (int)(fp3[1]) - (int)(pfp1[1]) - (int)(pfp2[1]) - (int)(pfp3[1]);
		d += DIFF_FCN(tmp);
		tmp = (int)(fp1[pitch+1]) + (int)(fp2[pitch+1]) + (int)(fp3[pitch+1]) - (int)(pfp1[pitch+1]) - (int)(pfp2[pitch+1]) - (int)(pfp3[pitch+1]);
		d += DIFF_FCN(tmp);

		for (pel = 2; pel < pels - 2; pel++)
		{
			tmp = (int)(fp1[-pitch+2]) + (int)(fp2[-pitch+2]) + (int)(fp3[-pitch+2]) - (int)(pfp1[-pitch+2]) - (int)(pfp2[-pitch+2]) - (int)(pfp3[-pitch+2]);
			e = DIFF_FCN(tmp);
			tmp = (int)(fp1[2]) + (int)(fp2[2]) + (int)(fp3[2]) - (int)(pfp1[2]) - (int)(pfp2[2]) - (int)(pfp3[2]);
			e += DIFF_FCN(tmp);
			tmp = (int)(fp1[pitch+2]) + (int)(fp2[pitch+2]) + (int)(fp3[pitch+2]) - (int)(pfp1[pitch+2]) - (int)(pfp2[pitch+2]) - (int)(pfp3[pitch+2]);
			e += DIFF_FCN(tmp);

			if (mode == INTL_LINE_REMOVE_MEDIAN)
			{
				if (a + b + c + d + e > INTL_DIFF_THRESH)
				{
					a =  MABS(fp2[-pitch-2] - fp2[-pitch+1]);
					a += MABS(fp2[pitch-2] - fp2[pitch+1]);
					a += MABS(fp2[-pitch-1] - fp2[-pitch+2]);
					a += MABS(fp2[pitch-1] - fp2[pitch+2]);
					a <<= 1;
					a -= MABS(fp2[-pitch-2] - fp2[pitch-2]);
					a -= MABS(fp2[-pitch-1] - fp2[pitch-1]);
					a -= MABS(fp2[-pitch+1] - fp2[pitch+1]);
					a -= MABS(fp2[-pitch+2] - fp2[pitch+2]);

					if (a > 0)
					{
						mode = INTL_LINE_REMOVE_AVG;
					}
				}
			}
			else
			{
				if (a + b + c + d + e < INTL_DIFF_THRESH)
				{
					a =  MABS(fp2[-pitch-2] - fp2[-pitch+1]);
					a += MABS(fp2[pitch-2] - fp2[pitch+1]);
					a += MABS(fp2[-pitch-1] - fp2[-pitch+2]);
					a += MABS(fp2[pitch-1] - fp2[pitch+2]);
					a <<= 1;
					a -= MABS(fp2[-pitch-2] - fp2[pitch-2]);
					a -= MABS(fp2[-pitch-1] - fp2[pitch-1]);
					a -= MABS(fp2[-pitch+1] - fp2[pitch+1]);
					a -= MABS(fp2[-pitch+2] - fp2[pitch+2]);

					if (a < 0)
					{
						mode = INTL_LINE_REMOVE_MEDIAN;
					}
				}
			}
				
			if (mode == INTL_LINE_REMOVE_MEDIAN)
			{
				// median
				fp1[0] = MEDIAN_3(fp1[-pitch],fp1[0],fp1[pitch]);
				fp2[0] = MEDIAN_3(fp2[-pitch],fp2[0],fp2[pitch]);
				fp3[0] = MEDIAN_3(fp3[-pitch],fp3[0],fp3[pitch]);
			}
			else
			{
				// average
				tmp = fp1[-pitch];
				tmp += fp1[pitch];
				fp1[0] = (tmp >> 1);
				tmp = fp2[-pitch];
				tmp += fp2[pitch];
				fp2[0] = (tmp >> 1);
				tmp = fp3[-pitch];
				tmp += fp3[pitch];
				fp3[0] = (tmp >> 1);
			}
				
			a = b;
			b = c;
			c = d;
			d = e;

			fp1++;pfp1++;
			fp2++;pfp2++;
			fp3++;pfp3++;

		}
	}
}


////////////////////////////////////////////////////////
//
//	Deinterlace_I420_Fast
//
//	Fast deinterlacing of I420 data, using both fields
//
////////////////////////////////////////////////////////

static void
Deinterlace_I420_Fast(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format)
{
	int line, pel;
	unsigned char *fp1,*pfp1;
	unsigned char *fp2,*pfp2;
	unsigned char *fp3,*pfp3;

	// Only handle RGB for now...
	if (format != INTL_FORMAT_I420)
		return;

	for (line = 1; line < lines - 2; line += 2)
	{
		unsigned int a,b,c,d,e,f;
		int c_nw,c_ne,c_se,c_sw;
		int diff,tmp;
		int prev_mode = INTL_LINE_REMOVE_AVG;
		int mode = INTL_LINE_REMOVE_AVG;
		int next_mode = INTL_LINE_REMOVE_AVG;

		// current frame
		fp2 = frame + line * pitch;
		fp1 = fp2 - pitch;
		fp3 = fp2 + pitch;

		// previous frame
		if (prev_frame != 0)
		{
			pfp2 = prev_frame + line * pitch;
			pfp1 = pfp2 - pitch;
			pfp3 = pfp2 + pitch;
		}
		else
		{
			pfp2 = fp2;
			pfp1 = fp1;
			pfp3 = fp3;
		}

		// initialize
		for (pel = 0; pel < pels - 4; pel += 4)
		{
			// Load *next* 4 pels
			a = ((unsigned int *)fp1)[1];
			b = ((unsigned int *)fp2)[1];
			c = ((unsigned int *)fp3)[1];

			// Get corners
			c_nw = (a >> 24);
			c_ne = (a & 0xff);
			c_sw = (c >> 24);
			c_se = (c & 0xff);

			// Edge detect
			tmp = c_nw + c_ne - c_sw - c_se;
			if ((tmp < 100) && (tmp > -100))
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;
			}

			tmp = c_ne + c_se - c_nw - c_sw;
			if (tmp > 100)
			{
				next_mode = INTL_LINE_REMOVE_AVG;
				goto proc;

⌨️ 快捷键说明

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