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

📄 deintl.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: deintl.cpp,v 1.7.32.1 2004/07/09 01:55:14 hubbe Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** *///////////////////////////////////////////////////////////	defines////////////////////////////////////////////////////////// Defineing TIME_DEINTERLACE will time the deinterlacer// and write a file with filename TIME_DEINTERLACE_FILENAME// with the times.//#define TIME_DEINTERLACE//#define TIME_DEINTERLACE_FILENAME "d:\\dintl.log"//////////////////////////////////////////////////////////	include files////////////////////////////////////////////////////////#include "hlxclib/stdlib.h"#include "hlxclib/string.h"#define INTL_I420_CODE#ifdef TIME_DEINTERLACE#include "hlxclib/stdio.h"#endif#include "mmx_util.h"#include "deintl.h"//////////////////////////////////////////////////////////	internal prototypes////////////////////////////////////////////////////////static voidDeinterlace_RGB24(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format);static voidDeinterlace_I420(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format);static voidDeinterlace_RGB24_Fast(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format);static voidDeinterlace_I420_Fast(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format);static voidDeinterlace_I420_Advanced(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format);static voidDeinterlace_I420_EdgeInterp(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format);static voidDeinterlace_RGB24_Field(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format, int field);static voidDeinterlace_I420_Field(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format, int field);static voidDeinterlace_I420_FlipFlop(unsigned char *frame, unsigned char *temp_frame, int pels, int lines, int pitch, int format);#ifdef _M_IX86static voidDeinterlace_I420_MMX(unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, int format);#endifintC_DetectInterlace_I420(unsigned char *frame, unsigned char *prev_frame, int first_frame, int pels, int lines, int pitch);//////////////////////////////////////////////////////////	macros////////////////////////////////////////////////////////#define MEDIAN_3(a,b,c)			\	((a > b)?					\		(						\			(b > c)?			\			(b):				\			(					\				(a > c)?		\				(c):			\				(a)				\			)					\		):						\		(						\			(a > c)?			\			(a):				\			(					\				(b > c)?		\				(c):			\				(b)				\			)					\		))						\#define MABS(v) (tmp=(v),((tmp)^(tmp>>31)))#define ABS(a)  (((a) < 0) ? (-(a)) : (a))#define DIFF_FCN(v) ((v)*(v))		// Squared differencestatic const int SQUARED_TAB[255+255+1] = {    65025,  64516,  64009,  63504,  63001,  62500,    62001,  61504,  61009,  60516,  60025,  59536,  59049,  58564,  58081,  57600,    57121,  56644,  56169,  55696,  55225,  54756,  54289,  53824,  53361,  52900,    52441,  51984,  51529,  51076,  50625,  50176,  49729,  49284,  48841,  48400,    47961,  47524,  47089,  46656,  46225,  45796,  45369,  44944,  44521,  44100,    43681,  43264,  42849,  42436,  42025,  41616,  41209,  40804,  40401,  40000,    39601,  39204,  38809,  38416,  38025,  37636,  37249,  36864,  36481,  36100,    35721,  35344,  34969,  34596,  34225,  33856,  33489,  33124,  32761,  32400,    32041,  31684,  31329,  30976,  30625,  30276,  29929,  29584,  29241,  28900,    28561,  28224,  27889,  27556,  27225,  26896,  26569,  26244,  25921,  25600,    25281,  24964,  24649,  24336,  24025,  23716,  23409,  23104,  22801,  22500,    22201,  21904,  21609,  21316,  21025,  20736,  20449,  20164,  19881,  19600,    19321,  19044,  18769,  18496,  18225,  17956,  17689,  17424,  17161,  16900,    16641,  16384,  16129,  15876,  15625,  15376,  15129,  14884,  14641,  14400,    14161,  13924,  13689,  13456,  13225,  12996,  12769,  12544,  12321,  12100,    11881,  11664,  11449,  11236,  11025,  10816,  10609,  10404,  10201,  10000,    9801,   9604,   9409,   9216,   9025,   8836,   8649,   8464,   8281,   8100,    7921,   7744,   7569,   7396,   7225,   7056,   6889,   6724,   6561,   6400,    6241,   6084,   5929,   5776,   5625,   5476,   5329,   5184,   5041,   4900,    4761,   4624,   4489,   4356,   4225,   4096,   3969,   3844,   3721,   3600,    3481,   3364,   3249,   3136,   3025,   2916,   2809,   2704,   2601,   2500,    2401,   2304,   2209,   2116,   2025,   1936,   1849,   1764,   1681,   1600,    1521,   1444,   1369,   1296,   1225,   1156,   1089,   1024,   961,    900,    841,    784,    729,    676,    625,    576,    529,    484,    441,    400,    361,    324,    289,    256,    225,    196,    169,    144,    121,    100,    81,     64,     49,     36,     25,     16,     9,      4,      1,      0,    1,      4,      9,      16,     25,     36,     49,     64,     81,     100,    121,    144,    169,    196,    225,    256,    289,    324,    361,    400,    441,    484,    529,    576,    625,    676,    729,    784,    841,    900,    961,    1024,   1089,   1156,   1225,   1296,   1369,   1444,   1521,   1600,    1681,   1764,   1849,   1936,   2025,   2116,   2209,   2304,   2401,   2500,    2601,   2704,   2809,   2916,   3025,   3136,   3249,   3364,   3481,   3600,    3721,   3844,   3969,   4096,   4225,   4356,   4489,   4624,   4761,   4900,    5041,   5184,   5329,   5476,   5625,   5776,   5929,   6084,   6241,   6400,    6561,   6724,   6889,   7056,   7225,   7396,   7569,   7744,   7921,   8100,    8281,   8464,   8649,   8836,   9025,   9216,   9409,   9604,   9801,   10000,    10201,  10404,  10609,  10816,  11025,  11236,  11449,  11664,  11881,  12100,    12321,  12544,  12769,  12996,  13225,  13456,  13689,  13924,  14161,  14400,    14641,  14884,  15129,  15376,  15625,  15876,  16129,  16384,  16641,  16900,    17161,  17424,  17689,  17956,  18225,  18496,  18769,  19044,  19321,  19600,    19881,  20164,  20449,  20736,  21025,  21316,  21609,  21904,  22201,  22500,    22801,  23104,  23409,  23716,  24025,  24336,  24649,  24964,  25281,  25600,    25921,  26244,  26569,  26896,  27225,  27556,  27889,  28224,  28561,  28900,    29241,  29584,  29929,  30276,  30625,  30976,  31329,  31684,  32041,  32400,    32761,  33124,  33489,  33856,  34225,  34596,  34969,  35344,  35721,  36100,    36481,  36864,  37249,  37636,  38025,  38416,  38809,  39204,  39601,  40000,    40401,  40804,  41209,  41616,  42025,  42436,  42849,  43264,  43681,  44100,    44521,  44944,  45369,  45796,  46225,  46656,  47089,  47524,  47961,  48400,    48841,  49284,  49729,  50176,  50625,  51076,  51529,  51984,  52441,  52900,    53361,  53824,  54289,  54756,  55225,  55696,  56169,  56644,  57121,  57600,    58081,  58564,  59049,  59536,  60025,  60516,  61009,  61504,  62001,  62500,    63001,  63504,  64009,  64516,  65025};#define MSQUARED(v) (SQUARED_TAB[(v) + 255])// Some thresholds#define INTL_DIFF_THRESH	40000#define INTL_HORIZ_THRESH	80#ifdef TIME_DEINTERLACEstatic unsigned int num_avg = 0;static unsigned int num_med = 0;#endifintInitDeinterlace (	int pels, int lines, int pitch, 	int format, 	INTL_MODE mode, 	T_DEINTL_STATE **state){	T_DEINTL_STATE *new_state = 0;	if (*state == 0)	{		new_state = (T_DEINTL_STATE *)malloc(sizeof(T_DEINTL_STATE));	}	if (new_state == 0)		return 1;	new_state->pels = pels;	new_state->lines = lines;	new_state->pitch = pitch;	new_state->format = format;	new_state->detection_measure = (lines > 242)?(16):(0);	new_state->commit_deinterlace = FALSE;	*state = new_state;	return 0;}voidFreeDeinterlace (T_DEINTL_STATE **state){	if (*state != 0)		free(*state);	*state = 0;}BOOLIsContentInterlaced (T_DEINTL_STATE *state){	if (state != 0)		return (state->commit_deinterlace == 1)?(TRUE):(FALSE);	return FALSE;}voidResetDeinterlace (T_DEINTL_STATE *state){	state->detection_measure = 0;	state->commit_deinterlace = FALSE;}////////////////////////////////////////////////////////////	Deinterlace////	Top level function to deinterlace a video frame////	Parameters://		frame:		Pointer to the frame to deinterlace//		prev_frame:	Pointer to the previous frame.//					Better results are achieved by giving//					the previous *interlaced* frame//		pels,//		lines,//		pitch:		Frame dimensions//		format:		INTL_FORMAT_RGB24 or INTL_FORMAT_I420//		mode:		Choose either using both fields or//					to remove one field entirely//					(see 'deintl.h')//////////////////////////////////////////////////////////intDeinterlace(	unsigned char *frame, 	unsigned char *prev_frame,	int pels, int lines, int pitch,	int format,	int first_frame, 	INTL_MODE mode,	T_DEINTL_STATE *state){	if (pels == 0)		pels = state->pels;	if (lines == 0)		lines = state->lines;	if (pitch == 0)		pitch = state->pitch;	if (format == 0)		format = state->format;	unsigned char *pfp = (first_frame == TRUE)?(NULL):(prev_frame);	// Unless were going to do detection first (i.e. in INTL_MODE_SMART_AUTO mode),	// don't de-interlace when there is less than 242 lines.  This is a little	// check to prevent unintentional de-interlacing of probable progressive frames.	if (lines < 242 && mode != INTL_MODE_SMART_AUTO)		return 0;	// Run detection	if (mode == INTL_MODE_SMART_AUTO)	{		unsigned char *detection_frame;		unsigned char *detection_prev_frame;		int res;		if (format == INTL_FORMAT_I420)		{			// point to the Y-Plane			detection_frame = frame;			detection_prev_frame = prev_frame;		}		if (format == INTL_FORMAT_RGB24)		{			// point to the G-Plane			detection_frame = frame + pels * lines;			detection_prev_frame = prev_frame + pels * lines;		}		// Perform detection		res = C_DetectInterlace_I420(			detection_frame, 			detection_prev_frame, 			first_frame, 			pels, lines, pitch);		// Update the "detection measure" based on result of detection		switch (res)		{		case INTL_STRONG_INTERLACE:			{				state->detection_measure = (31 * state->detection_measure + 256) >> 5;			}			break;		case INTL_WEAK_INTERLACE:			{				state->detection_measure = (31 * state->detection_measure + 256) >> 5;			}			break;		case INTL_WEAK_PROGRESSIVE:			{				state->detection_measure = (31 * state->detection_measure + 0) >> 5;			}			break;		case INTL_STRONG_PROGRESSIVE:			{				state->detection_measure = 0;			}			break;		}		// If the detection measure is above a threshold, set this flag used		// to indicate we are confident the content is interlaced.		if (state->detection_measure > 128)		{			state->commit_deinterlace = TRUE;		}		// If the detection measure is above this threshold, we should		// de-interlace this frame. Otherwise, return without de-interlacing		if (state->detection_measure > 16)		{			mode = INTL_MODE_SMART;		}		else		{			return 0;		}	}#ifdef TIME_DEINTERLACE	FILE *fp = NULL;	double proc_time;	USE_CODEC_TIMER;	num_avg = 0;	num_med = 0;	START_CODEC_TIMER;#endif	switch (format)	{#ifdef INTL_RBG24_CODE	case INTL_FORMAT_RGB24:		Deinterlace_RGB24_Fast(frame, pfp, pels, lines, pitch, format);		break;#endif#ifdef INTL_I420_CODE	case INTL_FORMAT_I420:#ifdef USE_MMX_DEINTERLACING		//_M_IX86        if (checkMmxAvailablity() & CPU_HAS_MMX)			Deinterlace_I420_MMX(frame, pfp, pels, lines, pitch, format);		else#endif		// Neelesh's new deinterlacer.		Deinterlace_I420_Advanced(frame, pfp, pels, lines, pitch, format);		break;#endif	}#ifdef TIME_DEINTERLACE	STOP_CODEC_TIMER(proc_time);		fp = fopen(TIME_DEINTERLACE_FILENAME,"a+");	if (fp != NULL)	{		fprintf(fp,"deinterlace time\t%f\t%d\t%d\n",proc_time,num_avg,num_med);		fclose(fp);	}#endif	return 1;}////////////////////////////////////////////////////////////	C_DetectInterlace_I420////	Top level function to detect the presense of //	interlaced video content////	Parameters://		frame:		Pointer to the frame to deinterlace//		prev_frame:	Pointer to the previous frame.//		pels,//		lines,//		pitch:		Frame dimensions//////////////////////////////////////////////////////////// Threshold: If 8x8 SAD is above MOVEMENT_THRESH then// we'll decide that the block is in motion#define MOVEMENT_THRESH (400)// This is the factor by which 8x8 are skipped (not checked).// SKIP_FACTOR = 1 means no skipping.#define SKIP_FACTOR 4#ifdef DEBUG// This increments with each call, // and is useful for debugging a specific frame.static unsigned int call_count = 0;#endifintC_DetectInterlace_I420(	unsigned char *frame, 	unsigned char *prev_frame, 	int first_frame, 	int pels, int lines, int pitch){	unsigned int image_size = (unsigned int)(pels * lines);		// pre-calculated image size used for determining thresholds	unsigned int interlaced_blocks = 0;					// count of the number of 8x8 blocks that look to be interlaced	unsigned int progressive_blocks = 0;		// count of the number of 8x8 blocks that look to be progressive	unsigned int step1v_tot = 0;		// running total of the 1-step squared vertical difference of pixels	unsigned int step2v_tot = 0;		// running total of the 2-step squared vertical difference of pixels	unsigned int step1h_tot = 0;		// running total of the 1-step squared horizontal difference of pixels	unsigned int step2h_tot = 0;		// running total of the 2-step squared horizontal difference of pixels	unsigned char *fp, *pp;	unsigned char *f0, *f1, *f2, *f3;		// various temporary frame pointers	int i, j, k;	// loop counter		int tmp;		// intermediate values for correlation and SAD macro	int d0, d1;		// SAD counters#ifdef DEBUG	call_count++;#endif	// We have no detection scheme for the first frame yet.	if (first_frame)	{		return INTL_NO_DETECTION;	}	// Loop through tiled 8x8 blocks of the image	for (i = 8; i < lines - 8; i += 8)	{		// Start pointer at new line		fp = frame + i * pitch + (i & (8*(SKIP_FACTOR - 1))) + 8;		pp = prev_frame + i * pitch + (i &  (8*(SKIP_FACTOR - 1))) + 8;		for (j = 8; j < pels - 8; j += 8 * SKIP_FACTOR)		{			f0 = fp;			f1 = f0 + pitch;			f2 = pp;			f3 = f2 + pitch;			d0 = d1 = 0;			// Calculate SAD for even and odd lines of 8x8 block.			// We're doing a partial SAD here for speed.			for (k = 0; k < 4; k++)			{				d0 += MABS(f0[0] - f2[0]);				d0 += MABS(f0[2] - f2[2]);				d0 += MABS(f0[4] - f2[4]);				d0 += MABS(f0[6] - f2[6]);				d1 += MABS(f1[1] - f3[1]);				d1 += MABS(f1[3] - f3[3]);				d1 += MABS(f1[5] - f3[5]);				d1 += MABS(f1[7] - f3[7]);				f0 += 2 * pitch;				f1 += 2 * pitch;				f2 += 2 * pitch;				f3 += 2 * pitch;			}			d0 <<= 1;			d1 <<= 1;						// If there is enough difference to determine movement,			// check this region for indications of interlaced artifacts			if (d0 > MOVEMENT_THRESH || d1 > MOVEMENT_THRESH)			{				int step1v_corr = 0;				int step2v_corr = 0;				int step1h_corr = 0;				int step2h_corr = 0;				f0 = fp;				f1 = f0 + pitch;				f2 = f1 + pitch;				// Determine 1 and 2 step pixel differences for 8x8 region				for (k = 0; k < 4; k++)				{					tmp = f0[1] - f1[1];					step1v_corr += MSQUARED(tmp);					tmp = f0[1] - f2[1];					step2v_corr += MSQUARED(tmp);					tmp = f1[0] - f1[1];					step1h_corr += MSQUARED(tmp);					tmp = f1[0] - f1[2];					step2h_corr += MSQUARED(tmp);					tmp = f0[3] - f1[3];					step1v_corr += MSQUARED(tmp);

⌨️ 快捷键说明

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