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

📄 estimation_pvop.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
			}
		}
	}

	 /* favorize (0,0) or global vector for cartoons */
	if (current->vop_flags & XVID_VOP_CARTOON) {
		if (current->coding_type == S_VOP) {
			int32_t iSAD = sad16(pCurrent->y + (x + y * iEdgedWidth) * 16,
			pGMC->y + 16*y*iEdgedWidth + 16*x, iEdgedWidth, 65536);

			if (Data->chroma) {
				iSAD += sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8, pGMC->u + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);
				iSAD += sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8, pGMC->v + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);
			}

			if (iSAD <= stat_thresh) {		/* mode decision GMC */
				pMB->mode = MODE_INTER;
				pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = iSAD;
				pMB->mcsel = 1;
				if (Data->qpel) {
					pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv;
					pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->amv.x/2;
					pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->amv.y/2;
				} else
					pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;
				
				return 1;
			}
		}
		else if (sad00 < stat_thresh) {
			VECTOR predMV;
			if (Data->qpel)
				predMV = get_qpmv2(current->mbs, pParam->mb_width, 0, x, y, 0);
			else
				predMV = get_pmv2(current->mbs, pParam->mb_width, 0, x, y, 0);

			ZeroMacroblockP(pMB, sad00);
			pMB->cbp = 0x3f;
			pMB->pmvs[0].x = - predMV.x;
			pMB->pmvs[0].y = - predMV.y;
			return 1;
		}
	}

	return 0;
}

static __inline uint32_t
MakeGoodMotionFlags(const uint32_t MotionFlags, const uint32_t VopFlags, const uint32_t VolFlags)
{
	uint32_t Flags = MotionFlags;

	if (!(VopFlags & XVID_VOP_MODEDECISION_RD))
		Flags &= ~(XVID_ME_QUARTERPELREFINE16_RD+XVID_ME_QUARTERPELREFINE8_RD+XVID_ME_HALFPELREFINE16_RD+XVID_ME_HALFPELREFINE8_RD+XVID_ME_EXTSEARCH_RD);

	if (Flags & XVID_ME_EXTSEARCH_RD)
		Flags |= XVID_ME_HALFPELREFINE16_RD;

	if (Flags & XVID_ME_EXTSEARCH_RD && MotionFlags & XVID_ME_EXTSEARCH8)
		Flags |= XVID_ME_HALFPELREFINE8_RD;

	if (Flags & XVID_ME_HALFPELREFINE16_RD)
		Flags |= XVID_ME_QUARTERPELREFINE16_RD;

	if (Flags & XVID_ME_HALFPELREFINE8_RD) {
		Flags |= XVID_ME_QUARTERPELREFINE8_RD;
		Flags &= ~XVID_ME_HALFPELREFINE8;
	}

	if (Flags & XVID_ME_QUARTERPELREFINE8_RD)
		Flags &= ~XVID_ME_QUARTERPELREFINE8;

	if (Flags & XVID_ME_QUARTERPELREFINE16_RD)
		Flags &= ~XVID_ME_QUARTERPELREFINE16;

	if (!(VolFlags & XVID_VOL_QUARTERPEL))
		Flags &= ~(XVID_ME_QUARTERPELREFINE16+XVID_ME_QUARTERPELREFINE8+XVID_ME_QUARTERPELREFINE16_RD+XVID_ME_QUARTERPELREFINE8_RD);

	if (!(VopFlags & XVID_VOP_HALFPEL))
		Flags &= ~(XVID_ME_EXTSEARCH16+XVID_ME_HALFPELREFINE16+XVID_ME_HALFPELREFINE8+XVID_ME_HALFPELREFINE16_RD+XVID_ME_HALFPELREFINE8_RD);

	if (VopFlags & XVID_VOP_GREYSCALE)
		Flags &= ~(XVID_ME_CHROMA_PVOP + XVID_ME_CHROMA_BVOP);

	if (Flags & XVID_ME_FASTREFINE8)
		Flags &= ~XVID_ME_HALFPELREFINE8_RD;

	if (Flags & XVID_ME_FASTREFINE16)
		Flags &= ~XVID_ME_HALFPELREFINE16_RD;

	return Flags;
}

static __inline void
motionStatsPVOP(int * const MVmax, int * const mvCount, int * const mvSum,
				const MACROBLOCK * const pMB, const int qpel)
{
	const VECTOR * const mv = qpel ? pMB->qmvs : pMB->mvs;
	int i;
	int max = *MVmax;

	switch (pMB->mode) {
	case MODE_INTER4V:
		*mvCount += 3;
		for(i = 3; i; i--) {
			if (mv[i].x > max) max = mv[i].x;
			else if (-mv[i].x - 1 > max) max = -mv[i].x - 1;
			*mvSum += mv[i].x * mv[i].x;
			if (mv[i].y > max) max = mv[i].y;
			else if (-mv[i].y - 1 > max) max = -mv[i].y - 1;
			*mvSum += mv[i].y * mv[i].y;
		}
	case MODE_INTER:
		(*mvCount)++;
		*mvSum += mv[0].x * mv[0].x;
		*mvSum += mv[0].y * mv[0].y;
		if (mv[0].x > max) max = mv[0].x;
		else if (-mv[0].x - 1 > max) max = -mv[0].x - 1;
		if (mv[0].y > max) max = mv[0].y;
		else if (-mv[0].y - 1 > max) max = -mv[0].y - 1;
		*MVmax = max;
	default:
		break;
	}
}

void
MotionEstimation(MBParam * const pParam,
				 FRAMEINFO * const current,
				 FRAMEINFO * const reference,
				 const IMAGE * const pRefH,
				 const IMAGE * const pRefV,
				 const IMAGE * const pRefHV,
				 const IMAGE * const pGMC,
				 const uint32_t iLimit)
{
	MACROBLOCK *const pMBs = current->mbs;
	const IMAGE *const pCurrent = &current->image;
	const IMAGE *const pRef = &reference->image;

	const uint32_t mb_width = pParam->mb_width;
	const uint32_t mb_height = pParam->mb_height;
	const uint32_t iEdgedWidth = pParam->edged_width;
	const uint32_t MotionFlags = MakeGoodMotionFlags(current->motion_flags, current->vop_flags, current->vol_flags);
	int stat_thresh = 0;
	int MVmax = 0, mvSum = 0, mvCount = 0;

	uint32_t x, y;
	int sad00;
	int skip_thresh = INITIAL_SKIP_THRESH * \
		(current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);
	int block = 0;

	/* some pre-initialized thingies for SearchP */
	DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
	SearchData Data;
	memset(&Data, 0, sizeof(SearchData));
	Data.iEdgedWidth = iEdgedWidth;
	Data.iFcode = current->fcode;
	Data.rounding = pParam->m_rounding_type;
	Data.qpel = (current->vol_flags & XVID_VOL_QUARTERPEL ? 1:0);
	Data.chroma = MotionFlags & XVID_ME_CHROMA_PVOP;
	Data.dctSpace = dct_space;
	Data.quant_type = !(pParam->vol_flags & XVID_VOL_MPEGQUANT);
	Data.mpeg_quant_matrices = pParam->mpeg_quant_matrices;

	Data.RefQ = pRefV->u; /* a good place, also used in MC (for similar purpose) */
	if (sadInit) (*sadInit) ();

	for (y = 0; y < mb_height; y++)	{
		for (x = 0; x < mb_width; x++)	{
			MACROBLOCK *pMB = &pMBs[block];
			MACROBLOCK *prevMB = &reference->mbs[block];
			int skip;
			block++;

			pMB->sad16 =
				sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,
							pRef->y + (x + y * iEdgedWidth) * 16,
							pParam->edged_width, pMB->sad8);

			sad00 = 4*MAX(MAX(pMB->sad8[0], pMB->sad8[1]), MAX(pMB->sad8[2], pMB->sad8[3]));

			if (Data.chroma) {
				Data.chromaSAD = sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8,
									pRef->u + x*8 + y*(iEdgedWidth/2)*8, iEdgedWidth/2)
								+ sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8,
									pRef->v + (x + y*(iEdgedWidth/2))*8, iEdgedWidth/2);
				pMB->sad16 += Data.chromaSAD;
				sad00 += Data.chromaSAD;
			}

			skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC, 
										pCurrent, pRef, MotionFlags);
			if (skip) continue;

			SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
					y, MotionFlags, current->vop_flags,
					&Data, pParam, pMBs, reference->mbs, pMB);

			if (current->vop_flags & XVID_VOP_MODEDECISION_RD)
				xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,
								MotionFlags, current->vop_flags, current->vol_flags,
								pCurrent, pRef, pGMC, current->coding_type);

			else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)
				xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,
								MotionFlags, current->vop_flags, current->vol_flags,
								pCurrent, pRef, pGMC, current->coding_type);
			else
				ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,
								MotionFlags, current->vop_flags, current->vol_flags,
								pCurrent, pRef, pGMC, current->coding_type, sad00);


			motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);
		}
	}

	current->fcode = getMinFcode(MVmax);
	current->sStat.iMvSum = mvSum;
	current->sStat.iMvCount = mvCount;
}

void
MotionEstimateSMP(SMPmotionData * h)
{
	const MBParam * const pParam = h->pParam;
	const FRAMEINFO * const current = h->current;
	const FRAMEINFO * const reference = h->reference;
	const IMAGE * const pRefH = h->pRefH;
	const IMAGE * const pRefV = h->pRefV;
	const IMAGE * const pRefHV = h->pRefHV;
	const IMAGE * const pGMC = h->pGMC;
	uint32_t MotionFlags = MakeGoodMotionFlags(current->motion_flags,
												current->vop_flags,
												current->vol_flags);

	MACROBLOCK *const pMBs = current->mbs;
	const IMAGE *const pCurrent = &current->image;
	const IMAGE *const pRef = &reference->image;

	const uint32_t mb_width = pParam->mb_width;
	const uint32_t mb_height = pParam->mb_height;
	const uint32_t iEdgedWidth = pParam->edged_width;
	int stat_thresh = 0;
	int MVmax = 0, mvSum = 0, mvCount = 0;
	int y_step = h->y_step;
	int start_y = h->start_y;

	uint32_t x, y;
	int sad00;
	int skip_thresh = INITIAL_SKIP_THRESH * \
		(current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);
	int block = start_y*mb_width;
	int * complete_count_self = h->complete_count_self;
	const volatile int * complete_count_above = h->complete_count_above;
	int max_mbs;
	int current_mb = 0;

	/* some pre-initialized thingies for SearchP */
	DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
	SearchData Data;
	memset(&Data, 0, sizeof(SearchData));
	Data.iEdgedWidth = iEdgedWidth;
	Data.iFcode = current->fcode;
	Data.rounding = pParam->m_rounding_type;
	Data.qpel = (current->vol_flags & XVID_VOL_QUARTERPEL ? 1:0);
	Data.chroma = MotionFlags & XVID_ME_CHROMA_PVOP;
	Data.dctSpace = dct_space;
	Data.quant_type = !(pParam->vol_flags & XVID_VOL_MPEGQUANT);
	Data.mpeg_quant_matrices = pParam->mpeg_quant_matrices;

	/* todo: sort out temp memory space */
	Data.RefQ = h->RefQ;
	if (sadInit) (*sadInit) ();

	max_mbs = 0;

	for (y = start_y; y < mb_height; y += y_step)	{
		if (y == 0) max_mbs = mb_width; /* we can process all blocks of the first row */

		for (x = 0; x < mb_width; x++)	{
			
			MACROBLOCK *pMB, *prevMB;
			int skip;

			if (current_mb >= max_mbs) {
				/* we ME-ed all macroblocks we safely could. grab next portion */
				int above_count = *complete_count_above; /* sync point */
				if (above_count == mb_width) {
					/* full line above is ready */
					above_count = mb_width+1;
					if (y < mb_height-y_step) {
						/* this is not last line, grab a portion of MBs from the next line too */
						above_count += MAX(0, complete_count_above[1] - 1);
					}
				}

				max_mbs = current_mb + above_count - x - 1;
				
				if (current_mb >= max_mbs) {
					/* current workload is zero */
					x--;
					sched_yield();
					continue;
				}
			}


			pMB = &pMBs[block];
			prevMB = &reference->mbs[block];

			pMB->sad16 =
				sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,
							pRef->y + (x + y * iEdgedWidth) * 16,
							pParam->edged_width, pMB->sad8);

			sad00 = 4*MAX(MAX(pMB->sad8[0], pMB->sad8[1]), MAX(pMB->sad8[2], pMB->sad8[3]));

			if (Data.chroma) {
				Data.chromaSAD = sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8,
									pRef->u + x*8 + y*(iEdgedWidth/2)*8, iEdgedWidth/2)
								+ sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8,
									pRef->v + (x + y*(iEdgedWidth/2))*8, iEdgedWidth/2);
				pMB->sad16 += Data.chromaSAD;
				sad00 += Data.chromaSAD;
			}

			skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC, 
										pCurrent, pRef, MotionFlags);

			if (skip) {
				current_mb++;
				block++;
				*complete_count_self = x+1;
				continue;
			}

			SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
					y, MotionFlags, current->vop_flags,
					&Data, pParam, pMBs, reference->mbs, pMB);

			if (current->vop_flags & XVID_VOP_MODEDECISION_RD)
				xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,
								MotionFlags, current->vop_flags, current->vol_flags,
								pCurrent, pRef, pGMC, current->coding_type);

			else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)
				xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,
								MotionFlags, current->vop_flags, current->vol_flags,
								pCurrent, pRef, pGMC, current->coding_type);
			else
				ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,
								MotionFlags, current->vop_flags, current->vol_flags,
								pCurrent, pRef, pGMC, current->coding_type, sad00);

			*complete_count_self = x+1;

			current_mb++;
			block++;

			motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);
			
		}
		block += (y_step-1)*pParam->mb_width;
		complete_count_self++;
		complete_count_above++;
	}

	h->minfcode = getMinFcode(MVmax);

	h->MVmax = MVmax;
	h->mvSum = mvSum;
	h->mvCount = mvCount;
}


⌨️ 快捷键说明

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