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

📄 tdeinterlaceyuy2.cpp

📁 the De-interlace video processing developed with C++ enviroment in Motion adaptive in 3D and Bi-indi
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
**                TDeinterlace v1.0b4 for AviSynth 2.5.x
**
**   TDeinterlace is a bi-directionally motion adaptive deinterlacer.
**   It also uses a couple modified forms of ela interpolation which 
**   help to reduce "jaggy" edges in places where interpolation must 
**   be used. TDeinterlace currently supports YV12 and YUY2 colorspaces.
**   
**   Copyright (C) 2004-2005 Kevin Stone
**
**   This program is free software; you can redistribute it and/or modify
**   it under the terms of the GNU General Public License as published by
**   the Free Software Foundation; either version 2 of the License, or
**   (at your option) any later version.
**
**   This program is distributed in the hope that it will be useful,
**   but WITHOUT ANY WARRANTY; without even the implied warranty of
**   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**   GNU General Public License for more details.
**
**   You should have received a copy of the GNU General Public License
**   along with this program; if not, write to the Free Software
**   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "TDeinterlace.h"

PVideoFrame TDeinterlace::GetFrameYUY2(int n, IScriptEnvironment* env)
{
	if (mode < 0)
	{
		PVideoFrame src2up = child->GetFrame(n, env);
		PVideoFrame dst2up = env->NewVideoFrame(vi);
		PVideoFrame msk2up = env->NewVideoFrame(vi);
		copyForUpsize(dst2up, src2up, 1, env);
		setMaskForUpsize(msk2up, 1);
		if (mode == -2) smartELADeintYUY2(dst2up, msk2up, dst2up, dst2up, dst2up);
		else if (mode == -1) ELADeintYUY2(dst2up, msk2up, dst2up, dst2up, dst2up);
		return dst2up;
	}
	if (mode == 1)
	{
		if (autoFO) order = child->GetParity(n>>1) ? 1 : 0;
		if (n&1) field = order == 1 ? 0 : 1;
		else field = order;
		n >>= 1;
	}
	else if (autoFO) order = child->GetParity(n) ? 1 : 0;
	PVideoFrame prv2, prv, nxt, nxt2, dst, mask;
	PVideoFrame src = child->GetFrame(n, env);
	bool found = false, fieldOVR = false;
	int x, hintField = -1;
	passHint = 0xFFFFFFFF;
	if (input != NULL && *ovr)
	{
		if (mode != 1) 
		{
			field = fieldS; 
			if (!autoFO) order = orderS;
		}
		mthreshL = mthreshLS; 
		mthreshC = mthreshCS;
		type = typeS;
		for (x=0; x<countOvr; x+=4)
		{
			if (n >= input[x+1] && n <= input[x+2])
			{
				if (input[x] == 45 && mode != 1) // -
				{
					if (debug)
					{
						sprintf(buf,"TDeint:  frame %d:  not deinterlacing\n", n);
						OutputDebugString(buf);
					}
					return src;
				}
				else if (input[x] == 43 && mode != 1) found = true;  // +
				else if (input[x] == 102 && mode != 1) { field = input[x+3]; fieldOVR = true; }// f
				else if (input[x] == 111 && mode != 1) order = input[x+3]; // o
				else if (input[x] == 108) mthreshL = input[x+3]; // l
				else if (input[x] == 99) mthreshC = input[x+3]; // c
				else if (input[x] == 116) type = input[x+3]; // t
			}
		}
		if (!found && ovrDefault == 1 && mode != 1) 
		{
			if (debug)
			{
				sprintf(buf,"TDeint:  frame %d:  not deinterlacing\n", n);
				OutputDebugString(buf);
			}
			return src;
		}
	}
	if (mode == 0 && hints && TDeinterlace::getHint(src, passHint, hintField) == 0 && !found) 
	{
		if (debug)
		{
			sprintf(buf,"TDeint:  frame %d:  not deinterlacing (HINTS)\n", n);
			OutputDebugString(buf);
		}
		return src;
	}
	if (mode == 0 && !full && !found)
	{
		if (!checkCombedYUY2(src, env))
		{
			if (debug)
			{
				sprintf(buf,"TDeint:  frame %d:  not deinterlacing (full = false)\n", n);
				OutputDebugString(buf);
			}
			return src;
		}
	}
	if (!fieldOVR && hintField >= 0)
	{
		int tempf = field;
		field = hintField;
		hintField = tempf;
	}
	if (!useClip2)
	{
		prv2 = child->GetFrame(n>1 ? n-2 : n>0 ? n-1 : 0, env);
		prv = child->GetFrame(n>0 ? n-1 : 0, env);
		nxt = child->GetFrame(n<nfrms ? n+1 : nfrms, env);
		nxt2 = child->GetFrame(n<nfrms-1 ? n+2 : n<nfrms ? n+1 : nfrms, env);
	}
	else
	{
		prv2 = clip2->GetFrame(n>1 ? n-2 : n>0 ? n-1 : 0, env);
		prv = clip2->GetFrame(n>0 ? n-1 : 0, env);
		src = clip2->GetFrame(n, env);
		nxt = clip2->GetFrame(n<nfrms ? n+1 : nfrms, env);
		nxt2 = clip2->GetFrame(n<nfrms-1 ? n+2 : n<nfrms ? n+1 : nfrms, env);
	}
	dst = env->NewVideoFrame(vi);
	if (type == 2 || mtnmode > 1 || tryWeave) 
	{
		subtractFieldsYUY2(prv, src, nxt);
		if (debug)
		{
			sprintf(buf, "TDeint:  frame %d:  accumP = %u  accumN = %u\n", n, accumP, accumN);
			OutputDebugString(buf);
		}
	}
	if (tryWeave && (mode != 0 || full || found || (field^order && accumP > accumN) || 
			(!(field^order) && accumN > accumP)))
	{
		createWeaveFrameYUY2(dst, prv, src, nxt, env);
		if (!checkCombedYUY2(dst, env))
		{
			if (debug)
			{
				sprintf(buf,"TDeint:  frame %d:  weaved with %s (tryWeave)\n", n, 
					field^order ? (accumP <= accumN ? "CURR" : "NEXT") : 
					(accumN <= accumP ? "CURR" : "PREV"));
				OutputDebugString(buf);
			}
			if (hintField >= 0 && !fieldOVR) field = hintField;
			return dst;
		}
	}
	mask = env->NewVideoFrame(vi);
	if (mthreshL <= 0 && mthreshC <= 0) setMaskForUpsize(mask, 1);
	else if (mtnmode == 0 || mtnmode == 2) createMotionMapYUY2(prv2, prv, src, nxt, nxt2, mask, n);
	else if (mtnmode == 1 || mtnmode == 3) createMotionMap2YUY2(prv2, prv, src, nxt, nxt2, mask, n);
	else env->ThrowError("TDeint:  an unknown error occured!");
	if (denoise) denoiseYUY2(mask);
	if (link == 1) linkFULL_YUY2(mask);
	else if (link == 2) linkYtoUV_YUY2(mask);
	else if (link == 3) linkUVtoY_YUY2(mask);
	else if (link != 0) env->ThrowError("TDeint:  an unknown error occured (link)!");
	if (map == 1) mapColorsYUY2(dst, mask);
	else if (map == 2) mapMergeYUY2(dst, mask, prv, src, nxt);
	else if (type == 0) cubicDeintYUY2(dst, mask, prv, src, nxt);
	else if (type == 1) smartELADeintYUY2(dst, mask, prv, src, nxt);
	else if (type == 2) kernelDeintYUY2(dst, mask, prv, src, nxt);
	else if (type == 3) ELADeintYUY2(dst, mask, prv, src, nxt);
	else env->ThrowError("TDeint:  an unknown error occured!");
	if (AP >= 0 && AP < 255 && map == 0) apPostCheck(dst, mask, env);
	if (!(passHint&0xFFFFFF00)) TDeinterlace::putHint(dst, passHint, field);
	if (debug)
	{
		sprintf(buf,"TDeint:  frame %d:  field = %s  order = %s\n", n, 
			field == 1 ? "bottom" : "top", order == 1 ? "tff" : "bff");
		OutputDebugString(buf);
		sprintf(buf,"TDeint:  frame %d:  mthreshL = %d  mthreshC = %d  type = %d\n", n, 
			mthreshL, mthreshC, type);
		OutputDebugString(buf);
	}
	if (hintField >= 0 && !fieldOVR) field = hintField;
	return dst;
}

void TDeinterlace::createMotionMapYUY2(PVideoFrame &prv2, PVideoFrame &prv, 
	PVideoFrame &src, PVideoFrame &nxt, PVideoFrame &nxt2, PVideoFrame &mask, int n)
{
	const unsigned char *prv2p = prv2->GetReadPtr();
	int prv2_pitch = prv2->GetPitch();
	prv2p += prv2_pitch*(2-field);
	prv2_pitch *= 2;
	const unsigned char *prvp = prv->GetReadPtr();
	int prv_pitch = prv->GetPitch();
	prvp += prv_pitch*(2-field);
	const unsigned char *prvpp = prvp - prv_pitch;
	const unsigned char *prvpn = prvp + prv_pitch;
	prv_pitch *= 2;
	const unsigned char *srcp = src->GetReadPtr();
	int src_pitch = src->GetPitch();
	int Width = src->GetRowSize();
	int Height = src->GetHeight();
	srcp += src_pitch*(2-field);
	const unsigned char *srcpp = srcp - src_pitch;
	const unsigned char *srcpn = srcp + src_pitch;
	src_pitch *= 2;
	const unsigned char *nxtp = nxt->GetReadPtr();
	int nxt_pitch = nxt->GetPitch();
	nxtp += nxt_pitch*(2-field);
	const unsigned char *nxtpp = nxtp - nxt_pitch;
	const unsigned char *nxtpn = nxtp + nxt_pitch;
	nxt_pitch *= 2;
	const unsigned char *nxt2p = nxt2->GetReadPtr();
	int nxt2_pitch = nxt2->GetPitch();
	nxt2p += nxt2_pitch*(2-field);
	nxt2_pitch *= 2;
	unsigned char *maskw = mask->GetWritePtr();
	int mask_pitch = mask->GetPitch();
	memset(maskw,10,mask_pitch*Height);
	maskw += mask_pitch*(2-field);
	mask_pitch *= 2;
	int x, y;
	unsigned char val1;
	bool t1, t2, t3, t4, t5, t6, t7;
	if (field^order)
	{
		val1 = mtnmode > 1 ? (accumP <= accumN ? 10 : 30) : 40;
		if (n <= 1 || n >= nfrms-1)
		{
			for (y=1; y<Height-1; y+=2)
			{
				for (x=0; x<Width; ++x)
				{
					t1 = n == 0 ? false : (abs(srcpp[x] - prvpp[x]) < mthreshL);
					t2 = n == 0 ? false : (abs(srcpn[x] - prvpn[x]) < mthreshL);
					t3 = n == nfrms ? false : (abs(srcpp[x] - nxtpp[x]) < mthreshL);
					t4 = n == nfrms ? false : (abs(srcpn[x] - nxtpn[x]) < mthreshL);
					t5 = n == 0 ? false : (abs(srcp[x] - prvp[x]) < mthreshL);
					t6 = n == nfrms ? false : (abs(srcp[x] - nxtp[x]) < mthreshL);
					t7 = n >= nfrms-1 ? false : (abs(nxtp[x] - nxt2p[x]) < mthreshL);
					if (t6 && ((t1 && t2) || (t3 && t4) || (t2 && t4 && (t5 || t7)) || (t1 && t3 && (t5 || t7))))
						maskw[x] = val1;
					else if (t1 && t2 && t3 && t4 && t5 && t7) maskw[x] = val1;
					else if (t1 && t5 && t2) maskw[x] = 10;
					else if (t3 && t7 && t4) maskw[x] = 30;
					else if (abs(srcp[x]-srcpp[x])<4 && abs(srcp[x]-srcpn[x])<4) maskw[x] = 110;
					else if (abs(nxtp[x]-srcpp[x])<4 && abs(nxtp[x]-srcpn[x])<4) maskw[x] = 130;
					else maskw[x] = 60;
					++x;
					t1 = n == 0 ? false : (abs(srcpp[x] - prvpp[x]) < mthreshC);
					t2 = n == 0 ? false : (abs(srcpn[x] - prvpn[x]) < mthreshC);
					t3 = n == nfrms ? false : (abs(srcpp[x] - nxtpp[x]) < mthreshC);
					t4 = n == nfrms ? false : (abs(srcpn[x] - nxtpn[x]) < mthreshC);
					t5 = n == 0 ? false : (abs(srcp[x] - prvp[x]) < mthreshC);
					t6 = n == nfrms ? false : (abs(srcp[x] - nxtp[x]) < mthreshC);
					t7 = n >= nfrms-1 ? false : (abs(nxtp[x] - nxt2p[x]) < mthreshC);
					if (t6 && ((t1 && t2) || (t3 && t4) || (t2 && t4 && (t5 || t7)) || (t1 && t3 && (t5 || t7))))
						maskw[x] = val1;
					else if (t1 && t2 && t3 && t4 && t5 && t7) maskw[x] = val1;
					else if (t1 && t5 && t2) maskw[x] = 10;
					else if (t3 && t7 && t4) maskw[x] = 30;
					else if (abs(srcp[x]-srcpp[x])<4 && abs(srcp[x]-srcpn[x])<4) maskw[x] = 110;
					else if (abs(nxtp[x]-srcpp[x])<4 && abs(nxtp[x]-srcpn[x])<4) maskw[x] = 130;
					else maskw[x] = 60;
				}
				prvpp += prv_pitch;
				prvp += prv_pitch;
				prvpn += prv_pitch;
				srcpp += src_pitch;
				srcp += src_pitch;
				srcpn += src_pitch;
				nxtpp += nxt_pitch;
				nxtp += nxt_pitch;
				nxtpn += nxt_pitch;
				nxt2p += nxt2_pitch;
				maskw += mask_pitch;
			}
		}
		else
		{
			for (y=1; y<Height-1; y+=2)
			{
				for (x=0; x<Width; ++x)
				{
					t1 = (abs(srcpp[x] - prvpp[x]) < mthreshL);
					t2 = (abs(srcpn[x] - prvpn[x]) < mthreshL);
					t3 = (abs(srcpp[x] - nxtpp[x]) < mthreshL);
					t4 = (abs(srcpn[x] - nxtpn[x]) < mthreshL);
					t5 = (abs(srcp[x] - prvp[x]) < mthreshL);
					t6 = (abs(srcp[x] - nxtp[x]) < mthreshL);
					t7 = (abs(nxtp[x] - nxt2p[x]) < mthreshL);
					if (t6 && ((t1 && t2) || (t3 && t4) || (t2 && t4 && (t5 || t7)) || (t1 && t3 && (t5 || t7))))
						maskw[x] = val1;
					else if (t1 && t2 && t3 && t4 && t5 && t7) maskw[x] = val1;
					else if (t1 && t5 && t2) maskw[x] = 10;
					else if (t3 && t7 && t4) maskw[x] = 30;
					else if (abs(srcp[x]-srcpp[x])<4 && abs(srcp[x]-srcpn[x])<4) maskw[x] = 110;
					else if (abs(nxtp[x]-srcpp[x])<4 && abs(nxtp[x]-srcpn[x])<4) maskw[x] = 130;
					else maskw[x] = 60;
					++x;
					t1 = (abs(srcpp[x] - prvpp[x]) < mthreshC);
					t2 = (abs(srcpn[x] - prvpn[x]) < mthreshC);
					t3 = (abs(srcpp[x] - nxtpp[x]) < mthreshC);
					t4 = (abs(srcpn[x] - nxtpn[x]) < mthreshC);
					t5 = (abs(srcp[x] - prvp[x]) < mthreshC);
					t6 = (abs(srcp[x] - nxtp[x]) < mthreshC);
					t7 = (abs(nxtp[x] - nxt2p[x]) < mthreshC);
					if (t6 && ((t1 && t2) || (t3 && t4) || (t2 && t4 && (t5 || t7)) || (t1 && t3 && (t5 || t7))))
						maskw[x] = val1;
					else if (t1 && t2 && t3 && t4 && t5 && t7) maskw[x] = val1;
					else if (t1 && t5 && t2) maskw[x] = 10;
					else if (t3 && t7 && t4) maskw[x] = 30;
					else if (abs(srcp[x]-srcpp[x])<4 && abs(srcp[x]-srcpn[x])<4) maskw[x] = 110;
					else if (abs(nxtp[x]-srcpp[x])<4 && abs(nxtp[x]-srcpn[x])<4) maskw[x] = 130;
					else maskw[x] = 60;
				}
				prvpp += prv_pitch;
				prvp += prv_pitch;
				prvpn += prv_pitch;
				srcpp += src_pitch;
				srcp += src_pitch;
				srcpn += src_pitch;
				nxtpp += nxt_pitch;
				nxtp += nxt_pitch;
				nxtpn += nxt_pitch;
				nxt2p += nxt2_pitch;
				maskw += mask_pitch;
			}
		}
	}
	else
	{
		val1 = mtnmode > 1 ? (accumP < accumN ? 20 : 10) : 50;
		if (n <= 1 || n >= nfrms-1)
		{
			for (y=1; y<Height-1; y+=2)
			{
				for (x=0; x<Width; ++x)
				{
					t1 = n == 0 ? false : (abs(srcpp[x] - prvpp[x]) < mthreshL);
					t2 = n == 0 ? false : (abs(srcpn[x] - prvpn[x]) < mthreshL);
					t3 = n == nfrms ? false : (abs(srcpp[x] - nxtpp[x]) < mthreshL);
					t4 = n == nfrms ? false : (abs(srcpn[x] - nxtpn[x]) < mthreshL);
					t5 = n <= 1 ? false : (abs(prvp[x] - prv2p[x]) < mthreshL);
					t6 = n == 0 ? false : (abs(srcp[x] - prvp[x]) < mthreshL);
					t7 = n == nfrms ? false : (abs(srcp[x] - nxtp[x]) < mthreshL);
					if (t6 && ((t1 && t2) || (t3 && t4) || (t2 && t4 && (t5 || t7)) || (t1 && t3 && (t5 || t7))))
						maskw[x] = val1;
					else if (t1 && t2 && t3 && t4 && t5 && t7) maskw[x] = val1;
					else if (t1 && t5 && t2) maskw[x] = 20;
					else if (t3 && t7 && t4) maskw[x] = 10;
					else if (abs(prvp[x]-srcpp[x])<4 && abs(prvp[x]-srcpn[x])<4) maskw[x] = 120;

⌨️ 快捷键说明

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