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

📄 pred.cpp

📁 avs decoder sources, added a command line sample
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/** * Copyright (c) 2006 *	OpenAVS Developers. All Rights Reserved. * * Copyright (c) 2005-2006 *	NSCC. All Rights Reserved. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *//**      * ! \file "pred.c" *   \brief Motion vector prediction. */#include "pred.h"#include "define.h"#include "global.h"#include "block.h"static AVS_HRESULT InterPredChromaB8x8(		MBINFO* pMbInfo, 		AVS_INT dwMbIndex, 		const VIDEODATA ** ppRefFrame, 		AVS_DWORD dwRefNum, 		AVS_INT dwMbWidth, AVS_INT dwMbHeight, 		AVS_INT dwSubMb, 		AVS_INT dwUV, AVS_BYTE * pPred);AVS_HRESULT IntraPredLuma(		MBINFO * pMbInfo, 		const AVS_BYTE * pbCurrY, 		AVS_DWORD dwMbIndex, 		AVS_DWORD dwImgWidth, 		AVS_DWORD dwImgHeight, 		AVS_DWORD dwBlockNo, 		AVS_BYTE* pPred, 		AVS_DWORD dwImgX, 		AVS_DWORD dwImgY){	AVS_BOOL LeftBlockAvailable = FALSE;	AVS_BOOL UpBlockAvailable = FALSE;	AVS_BOOL LeftDownBlockAvailable = FALSE;	AVS_BOOL UpRightBlockAvailable = FALSE;	AVS_INT  intraPredModeA = -1, intraPredModeB = -1;	AVS_INT  predIntraPredMode = -1;	AVS_INT  IntraLumaPredMode = -1;	AVS_INT  mostpredIntraPredMode = -1;	AVS_INT BlockX = dwImgX >> 3;	AVS_INT BlockY = dwImgY >> 3;	AVS_INT dwMb8Width = dwImgWidth>>3;	AVS_INT dwMb8Height = dwImgHeight>>3;	AVS_DWORD dwMbWidth = dwImgWidth >> 4;	dwImgWidth = dwImgWidth;	//判断相邻块是否已“可用”	if(BlockY > 0)		UpBlockAvailable = TRUE;	if(BlockY>0 && BlockX<dwMb8Width-1)		UpRightBlockAvailable = TRUE;	if(BlockX > 0)		LeftBlockAvailable = TRUE;	if(BlockX>0 && BlockY<dwMb8Height-1 )		LeftDownBlockAvailable = TRUE;	if(dwBlockNo == 3)		UpRightBlockAvailable = FALSE; 	if(dwBlockNo != 0)		LeftDownBlockAvailable = FALSE;	//求预测模式	if(LeftBlockAvailable)	{		if(dwBlockNo == 0 || dwBlockNo == 2)		{			if(pMbInfo[dwMbIndex-1].dwMbType == I_8x8)				intraPredModeA = pMbInfo[dwMbIndex-1].iIntraLumaPredModeNew[dwBlockNo+1];			else 				intraPredModeA = 2;		}		else			intraPredModeA = pMbInfo[dwMbIndex].iIntraLumaPredModeNew[dwBlockNo-1];	}	if(UpBlockAvailable)	{		if(dwBlockNo == 0 || dwBlockNo == 1)		{			if(pMbInfo[dwMbIndex-dwMbWidth].dwMbType == I_8x8)				intraPredModeB = pMbInfo[dwMbIndex-dwMbWidth].iIntraLumaPredModeNew[dwBlockNo+2];			else				intraPredModeB = 2;		}		else			intraPredModeB = pMbInfo[dwMbIndex].iIntraLumaPredModeNew[dwBlockNo-2];	}	if (intraPredModeA == -1 || intraPredModeB == -1) 	{		predIntraPredMode = 2;	}	else	{		predIntraPredMode = min(intraPredModeA, intraPredModeB);	}	if(pMbInfo[dwMbIndex].bPredModeFlag[dwBlockNo])	{		IntraLumaPredMode = predIntraPredMode;	}	else	{		if(pMbInfo[dwMbIndex].iIntraLumaPredMode[dwBlockNo] < predIntraPredMode)			IntraLumaPredMode = pMbInfo[dwMbIndex].iIntraLumaPredMode[dwBlockNo];		else			IntraLumaPredMode = pMbInfo[dwMbIndex].iIntraLumaPredMode[dwBlockNo]+1;	}	pMbInfo[dwMbIndex].iIntraLumaPredModeNew[dwBlockNo] = IntraLumaPredMode; 	AVS_BYTE c[18], r[18];	AVS_INT i, j;	if(LeftBlockAvailable)	{		for(i=0; i<8; i++)			c[i+1] = *(pbCurrY + (dwImgY+i)*dwImgWidth + dwImgX-1);		c[0] = c[1];		for(i=0; i<9; i++)		{			c[i+9] = c[8];		}	}	if(UpBlockAvailable)	{		for(i=0; i<8; i++)			r[i+1] = *(pbCurrY+(dwImgY-1)*dwImgWidth + dwImgX+i);		r[0] = r[1];		for(i=0; i<9; i++)		{			r[i+9] = r[8];		}	}	if(LeftDownBlockAvailable)	{		for(i=0; i<8; i++)			c[i+9] = *(pbCurrY+(dwImgY+8+i)*dwImgWidth + dwImgX-1);		c[17] = c[16];	}	if(UpRightBlockAvailable)	{		for(i=0; i<8; i++)			r[i+9] = *(pbCurrY+(dwImgY-1)*dwImgWidth + dwImgX+8+i);		r[17] =r[16];	}	if(UpBlockAvailable && LeftBlockAvailable)	{		r[0] = c[0] = *(pbCurrY+(dwImgY-1)*dwImgWidth + dwImgX-1);	}	switch(IntraLumaPredMode) 	{		case Intra_8x8_Vertical:			for(i=0; i<8; i++)				for(j=0; j<8; j++)					pPred[i*8+j]=r[j+1];			break;		case Intra_8x8_Horizontal:			for(i=0; i<8; i++)				for(j=0; j<8; j++)					pPred[i*8+j]=c[i+1];			break;		case Intra_8x8_DC:			if(!UpBlockAvailable && !LeftBlockAvailable)			{       				for(i=0;i<8;i++)					for(j=0;j<8;j++)						pPred[i*8+j] = 128;			}			else if(UpBlockAvailable && !LeftBlockAvailable)			{				for(i=0;i<8;i++)					for(j=0;j<8;j++)						//pPred[j*8+i] = (r[i]+2*r[i+1]+r[i+2]+2)>>2;  						pPred[i*8+j] = (r[j]+2*r[j+1]+r[j+2]+2)>>2;  			}			else if(!UpBlockAvailable && LeftBlockAvailable)			{				for(i=0; i<8; i++)					for(j=0; j<8; j++)						//pPred[j*8+i] = (c[j]+2*c[j+1]+c[j+2]+2)>>2;  						pPred[i*8+j] = (c[i]+2*c[i+1]+c[i+2]+2)>>2;  			}			else if(UpBlockAvailable && LeftBlockAvailable)			{				for(i=0; i<8; i++)					for(j=0; j<8; j++)						//pPred[j*8+i] = (((r[i]+2*r[i+1]+r[i+2]+2)>>2)+((c[j]+2*c[j+1]+c[j+2]+2)>>2))>>1;						pPred[i*8+j] = (((r[j]+2*r[j+1]+r[j+2]+2)>>2)+((c[i]+2*c[i+1]+c[i+2]+2)>>2))>>1;			}			break;		case Intra_8x8_Down_Left:			for(i=0; i<8; i++)			{				for(j=0; j<8; j++)					//pPred[j*8+i] = (((r[i+j+1]+2*r[i+j+2]+r[i+j+3]+2)>>2)+((c[i+j+1]+2*c[i+j+2]+c[i+j+3]+2)>>2))>>1;					pPred[i*8+j] = (((r[i+j+1]+2*r[i+j+2]+r[i+j+3]+2)>>2)+((c[i+j+1]+2*c[i+j+2]+c[i+j+3]+2)>>2))>>1;			}			break;		case Intra_8x8_Down_Right:			for(i=0; i<8; i++)			{				for(j=0; j<8; j++)				{					if(i==j)						pPred[i*8+j] = (c[1]+2*r[0]+r[1]+2)>>2;					if(j>i)						pPred[i*8+j] = (r[j-i+1]+2*r[j-i]+r[j-i-1]+2)>>2;					if(j<i)						pPred[i*8+j] = (c[i-j+1]+2*c[i-j]+c[i-j-1]+2)>>2;				}			}   			break;		default:			break;			//erro!	}	return AVS_NOERROR;}AVS_HRESULT IntraPredChroma(MBINFO* pMbInfo, const AVS_BYTE* pbCurrUV, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_DWORD dwMbHeight, AVS_BYTE* pPred, AVS_DWORD dwUVX, AVS_DWORD dwUVY){	AVS_INT i, j;	AVS_BOOL UpBlockAvailable = FALSE;	AVS_BOOL LeftBlockAvailable = FALSE;	AVS_INT BlockX = dwMbIndex%dwMbWidth;	AVS_INT BlockY = dwMbIndex/dwMbWidth;	AVS_INT dwUVWidth = dwMbWidth*8;	if(BlockX > 0)		LeftBlockAvailable = TRUE;	if(BlockY > 0)		UpBlockAvailable = TRUE;	AVS_INT r[10], c[10];	if(LeftBlockAvailable)	{		for(i=0; i<8; i++)			c[i+1] = *(pbCurrUV+(dwUVY+i)*dwUVWidth+dwUVX-1);		c[0] = c[1];		c[9] = c[8];	}	if(UpBlockAvailable)	{		for(i=0; i<8; i++)			r[i+1] = *(pbCurrUV+(dwUVY-1)*dwUVWidth+dwUVX+i);		r[0] = r[1];		r[9] = r[8];	}	if(LeftBlockAvailable && UpBlockAvailable)	{		c[0] = r[0] = *(pbCurrUV+(dwUVY-1)*dwUVWidth+dwUVX-1);	}	AVS_INT intraChromaPreMode = pMbInfo[dwMbIndex].dwintraChromaPredMode;	AVS_INT ih=0, iv=0, ia=0, ib=0, ic=0;	switch(intraChromaPreMode) 	{		case Intra_Chroma_DC:			if(LeftBlockAvailable && UpBlockAvailable)			{				for(i=0; i<8; i++)					for(j=0; j<8; j++)						pPred[j*8+i] = (((r[i]+2*r[i+1]+r[i+2]+2)>>2)+((c[j]+2*c[j+1]+c[j+2]+2)>>2))>>1;			}			if(!LeftBlockAvailable && UpBlockAvailable)			{				for(i=0; i<8; i++)					for(j=0; j<8; j++)						pPred[j*8+i] = (r[i]+2*r[i+1]+r[i+2]+2)>>2; 			}			if(LeftBlockAvailable && !UpBlockAvailable)			{				for(i=0; i<8; i++)					for(j=0; j<8; j++)						pPred[j*8+i] = (c[j]+2*c[j+1]+c[j+2]+2)>>2;			}			if(!LeftBlockAvailable && !UpBlockAvailable)			{				for(i=0; i<8; i++)					for(j=0; j<8; j++)						pPred[j*8+i] = 128;			}			break;		case Intra_Chroma_Horizontal:			for(i=0; i<8; i++)				for(j=0; j<8; j++)					pPred[j*8+i] = c[j+1];			break;		case Intra_Chroma_Vertical:			for(i=0; i<8; i++)				for(j=0; j<8; j++)					pPred[j*8+i] = r[i+1];			break;		case Intra_Chroma_Plane:			for(i=0; i<=3; i++)			{				ih += (i+1)*(r[5+i]-r[3-i]);				iv += (i+1)*(c[5+i]-c[3-i]);			}			ia = (r[8]+c[8])<<4; 			ib = (17*ih+16)>>5;			ic = (17*iv+16)>>5;			for(i=0; i<8; i++)				for(j=0; j<8; j++)					pPred[i*8+j] = Clip((ia+(j-3)*ib+(i-3)*ic+16)>>5); 			break;		default:			// error!			break;	}	return AVS_NOERROR;}MOTIONVECTOR ScaleMv(MOTIONVECTOR* pMv, AVS_INT iDistance1, AVS_INT iDistance2){	MOTIONVECTOR mv={0,0};	if(pMv->x != 0)		mv.x = sign1(pMv->x)*((abs(pMv->x)*iDistance1*(512/iDistance2)+256) >>9);	if(pMv->y != 0)		mv.y = sign1(pMv->y)*((abs(pMv->y)*iDistance1*(512/iDistance2)+256) >>9);	return mv;}MOTIONVECTOR ScalePredMv(MOTIONVECTOR* pMvA, MOTIONVECTOR* pMvB, MOTIONVECTOR* pMvC, AVS_INT iDistance1, AVS_INT iDistanceA, AVS_INT iDistanceB, AVS_INT iDistanceC){	MOTIONVECTOR MVA, MVB, MVC;	MVA = ScaleMv(pMvA, iDistance1, iDistanceA);	MVB = ScaleMv(pMvB, iDistance1, iDistanceB);	MVC = ScaleMv(pMvC, iDistance1, iDistanceC);	AVS_INT VAB = abs(MVA.x - MVB.x) + abs(MVA.y - MVB.y);	AVS_INT VBC = abs(MVB.x - MVC.x) + abs(MVB.y - MVC.y);	AVS_INT VCA = abs(MVC.x - MVA.x) + abs(MVC.y - MVA.y);	AVS_INT FMV = Median(VAB, VBC, VCA);	if(FMV == VAB)		return MVC;	else if(FMV == VBC)		return MVA;	else		return MVB;}static AVS_HRESULT InterPredLuma16x16(		MBINFO* pMbInfo, AVS_INT dwMbIndex, 		const AVS_BYTE* pbRefY, 		AVS_INT dwMbWidth, AVS_INT dwMbHeight, 		AVS_INT iBlockDistance, AVS_INT dirBw, 		AVS_BYTE* pPred){	AVS_BOOL A_BlockAvailable = FALSE;	AVS_BOOL B_BlockAvailable = FALSE;	AVS_BOOL C_BlockAvailable = FALSE;	AVS_BOOL D_BlockAvailable = FALSE;	AVS_INT  BlockDistanceA=1;	AVS_INT  BlockDistanceB=1;	AVS_INT  BlockDistanceC=1;	AVS_INT  BlockDistanceD=1;	AVS_INT  RefIdxA = -1;	AVS_INT  RefIdxB = -1;	AVS_INT  RefIdxC = -1;	AVS_INT  RefIdxD = -1;	MOTIONVECTOR mvA={0,0}, mvB={0,0}, mvC={0,0}, mvD={0,0}, mvE={0,0};	MOTIONVECTOR MVEPred={0,0};	AVS_INT MbX = dwMbIndex%dwMbWidth;	AVS_INT MbY = dwMbIndex/dwMbWidth;	if(MbX>0)		A_BlockAvailable = TRUE;	if(MbY>0)		B_BlockAvailable = TRUE;	if(MbX>0 && MbY>0)		D_BlockAvailable = TRUE;	if(MbY>0 && MbX<dwMbWidth-1)		C_BlockAvailable = TRUE; 	if(!A_BlockAvailable || pMbInfo[dwMbIndex-1].dwMbType == I_8x8 ||			(pMbInfo[dwMbIndex-1].predDir[1] != pMbInfo[dwMbIndex].predDir[0] && 			 pMbInfo[dwMbIndex-1].predDir[1] != PREDDIRSYM))	{		mvA.x = mvA.y = 0;		BlockDistanceA = 1;		RefIdxA = -1;	}	else	{		if(!dirBw)		{			mvA = pMbInfo[dwMbIndex-1].mv[1];			BlockDistanceA = pMbInfo[dwMbIndex-1].iBlockDistance[1];			RefIdxA = pMbInfo[dwMbIndex-1].dwMbReferenceIndex[1];		}		else		{			mvA = pMbInfo[dwMbIndex-1].mvBw[1];			BlockDistanceA = pMbInfo[dwMbIndex-1].iBlockDistanceBw[1];			RefIdxA = pMbInfo[dwMbIndex-1].dwMbReferenceIndexBw[1];		}	}	if(!B_BlockAvailable || pMbInfo[dwMbIndex-dwMbWidth].dwMbType == I_8x8 ||			(pMbInfo[dwMbIndex-dwMbWidth].predDir[2] != pMbInfo[dwMbIndex].predDir[0] && 			 pMbInfo[dwMbIndex-dwMbWidth].predDir[2] != PREDDIRSYM))	{		mvB.x = mvB.y = 0;		BlockDistanceB = 1;		RefIdxB = -1;	}	else	{		if(!dirBw)		{			mvB = pMbInfo[dwMbIndex-dwMbWidth].mv[2];			BlockDistanceB = pMbInfo[dwMbIndex-dwMbWidth].iBlockDistance[2];			RefIdxB = pMbInfo[dwMbIndex-dwMbWidth].dwMbReferenceIndex[2];		}		else		{			mvB = pMbInfo[dwMbIndex-dwMbWidth].mvBw[2];			BlockDistanceB = pMbInfo[dwMbIndex-dwMbWidth].iBlockDistanceBw[2];			RefIdxB = pMbInfo[dwMbIndex-dwMbWidth].dwMbReferenceIndexBw[2];		}	}	if(!D_BlockAvailable || pMbInfo[dwMbIndex-dwMbWidth-1].dwMbType == I_8x8 ||			(pMbInfo[dwMbIndex-dwMbWidth-1].predDir[3] != pMbInfo[dwMbIndex].predDir[0] && 			 pMbInfo[dwMbIndex-dwMbWidth-1].predDir[3] != PREDDIRSYM))	{		mvD.x = mvD.y = 0;		BlockDistanceD = 1;		RefIdxD = -1;	}	else	{		if(!dirBw)		{			mvD = pMbInfo[dwMbIndex-dwMbWidth-1].mv[3];			BlockDistanceD = pMbInfo[dwMbIndex-dwMbWidth-1].iBlockDistance[3];			RefIdxD = pMbInfo[dwMbIndex-dwMbWidth-1].dwMbReferenceIndex[3];		}		else		{			mvD = pMbInfo[dwMbIndex-dwMbWidth-1].mvBw[3];			BlockDistanceD = pMbInfo[dwMbIndex-dwMbWidth-1].iBlockDistanceBw[3];			RefIdxD = pMbInfo[dwMbIndex-dwMbWidth-1].dwMbReferenceIndexBw[3];		}	}	if(!C_BlockAvailable)	{		mvC = mvD;

⌨️ 快捷键说明

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