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

📄 encoder.c

📁 视频压缩编解码标准MPEG4商业级别的VC代码实现标准
💻 C
📖 第 1 页 / 共 4 页
字号:
			CodeIntraMB(pEnc, pMB);			MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,							  dct_codes, qcoeff);			start_timer();			MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);			stop_prediction_timer();			start_timer();			MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat);			stop_coding_timer();		}	emms();	BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */	pEnc->current->length = (BitstreamPos(bs) - bits) / 8;	pEnc->fMvPrevSigma = -1;	pEnc->mbParam.m_fcode = 2;	pEnc->current->is_edged = 0; /* not edged */	pEnc->current->is_interpolated = -1; /* not interpolated (fake rounding -1) */	return 1;					/* intra */}static __inline voidupdateFcode(Statistics * sStat, Encoder * pEnc){	float fSigma;	int iSearchRange;	if (sStat->iMvCount == 0)		sStat->iMvCount = 1;	fSigma = (float) sqrt((float) sStat->iMvSum / sStat->iMvCount);	iSearchRange = 16 << pEnc->mbParam.m_fcode;	if ((3.0 * fSigma > iSearchRange) && (pEnc->mbParam.m_fcode <= 5) )		pEnc->mbParam.m_fcode++;	else if ((5.0 * fSigma < iSearchRange)			   && (4.0 * pEnc->fMvPrevSigma < iSearchRange)			   && (pEnc->mbParam.m_fcode >= 2) )		pEnc->mbParam.m_fcode--;	pEnc->fMvPrevSigma = fSigma;}#define BFRAME_SKIP_THRESHHOLD 30/* FrameCodeP also handles S(GMC)-VOPs */static intFrameCodeP(Encoder * pEnc,		   Bitstream * bs){	int bits = BitstreamPos(bs);	DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);	DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);	int x, y, k;	FRAMEINFO *const current = pEnc->current;	FRAMEINFO *const reference = pEnc->reference;	MBParam * const pParam = &pEnc->mbParam;	int mb_width = pParam->mb_width;	int mb_height = pParam->mb_height;	int coded = 1;	IMAGE *pRef = &reference->image;	if (!reference->is_edged) {			start_timer();		image_setedges(pRef, pParam->edged_width, pParam->edged_height,					   pParam->width, pParam->height, 0);		stop_edges_timer();		reference->is_edged = 1;	}	pParam->m_rounding_type = 1 - pParam->m_rounding_type;	current->rounding_type = pParam->m_rounding_type;	current->fcode = pParam->m_fcode;	if ((current->vop_flags & XVID_VOP_HALFPEL)) {		if (reference->is_interpolated != current->rounding_type) {			start_timer();			image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV,							  &pEnc->vInterHV, pParam->edged_width,							  pParam->edged_height,							  (pParam->vol_flags & XVID_VOL_QUARTERPEL),							  current->rounding_type);			stop_inter_timer();			reference->is_interpolated = current->rounding_type;		}	}	current->sStat.iTextBits = current->sStat.iMvSum = current->sStat.iMvCount =		current->sStat.kblks = current->sStat.mblks = current->sStat.ublks = 0;	current->coding_type = P_VOP;	call_plugins(pEnc, pEnc->current, NULL, XVID_PLG_FRAME, NULL, NULL, NULL);	SetMacroblockQuants(&pEnc->mbParam, current);	start_timer();	if (current->vol_flags & XVID_VOL_GMC )	/* GMC only for S(GMC)-VOPs */	{	int gmcval;		current->warp = GlobalMotionEst( current->mbs, pParam, current, reference,								 &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);		if (current->motion_flags & XVID_ME_GME_REFINE) {			gmcval = GlobalMotionEstRefine(&current->warp,										   current->mbs, pParam,										   current, reference,										   &current->image,										   &reference->image,										   &pEnc->vInterH,										   &pEnc->vInterV,										   &pEnc->vInterHV);		} else {			gmcval = globalSAD(&current->warp, pParam, current->mbs,							   current,							   &reference->image,							   &current->image,							   pEnc->vGMC.y);		}		gmcval += /*current->quant*/ 2 * (int)(pParam->mb_width*pParam->mb_height);		/* 1st '3': 3 warpoints, 2nd '3': 16th pel res (2<<3) */		generate_GMCparameters(	3, 3, &current->warp,				pParam->width, pParam->height,				&current->new_gmc_data);		if ( (gmcval<0) && ( (current->warp.duv[1].x != 0) || (current->warp.duv[1].y != 0) ||			 (current->warp.duv[2].x != 0) || (current->warp.duv[2].y != 0) ) )		{			current->coding_type = S_VOP;			generate_GMCimage(&current->new_gmc_data, &reference->image,				pParam->mb_width, pParam->mb_height,				pParam->edged_width, pParam->edged_width/2,				pParam->m_fcode, ((pParam->vol_flags & XVID_VOL_QUARTERPEL)?1:0), 0,				current->rounding_type, current->mbs, &pEnc->vGMC);		} else {			generate_GMCimage(&current->new_gmc_data, &reference->image,				pParam->mb_width, pParam->mb_height,				pParam->edged_width, pParam->edged_width/2,				pParam->m_fcode, ((pParam->vol_flags & XVID_VOL_QUARTERPEL)?1:0), 0,				current->rounding_type, current->mbs, NULL);	/* no warping, just AMV */		}	}	MotionEstimation(&pEnc->mbParam, current, reference,					 &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,					 &pEnc->vGMC, 256*4096);	stop_motion_timer();	set_timecodes(current,reference,pParam->fbase);	BitstreamWriteVopHeader(bs, &pEnc->mbParam, current, 1, current->mbs[0].quant);	for (y = 0; y < mb_height; y++) {		for (x = 0; x < mb_width; x++) {			MACROBLOCK *pMB = &current->mbs[x + y * pParam->mb_width];			int skip_possible;			if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) {				CodeIntraMB(pEnc, pMB);				MBTransQuantIntra(&pEnc->mbParam, current, pMB, x, y,								  dct_codes, qcoeff);				start_timer();				MBPrediction(current, x, y, pParam->mb_width, qcoeff);				stop_prediction_timer();				current->sStat.kblks++;				MBCoding(current, pMB, qcoeff, bs, &current->sStat);				stop_coding_timer();				continue;			}			start_timer();			MBMotionCompensation(pMB, x, y, &reference->image,								 &pEnc->vInterH, &pEnc->vInterV,								 &pEnc->vInterHV, &pEnc->vGMC,								 &current->image,								 dct_codes, pParam->width,								 pParam->height,								 pParam->edged_width,								 (current->vol_flags & XVID_VOL_QUARTERPEL),								 current->rounding_type);			stop_comp_timer();			pMB->field_pred = 0;			if (pMB->cbp != 0) {				pMB->cbp = MBTransQuantInter(&pEnc->mbParam, current, pMB, x, y,									  dct_codes, qcoeff);			}			if (pMB->dquant != 0)				MBSetDquant(pMB, x, y, &pEnc->mbParam);			if (pMB->cbp || pMB->mvs[0].x || pMB->mvs[0].y ||				   pMB->mvs[1].x || pMB->mvs[1].y || pMB->mvs[2].x ||				   pMB->mvs[2].y || pMB->mvs[3].x || pMB->mvs[3].y) {				current->sStat.mblks++;			}  else {				current->sStat.ublks++;			}			start_timer();			/* Finished processing the MB, now check if to CODE or SKIP */			skip_possible = (pMB->cbp == 0) && (pMB->mode == MODE_INTER);			if (current->coding_type == S_VOP)				skip_possible &= (pMB->mcsel == 1);			else { /* PVOP */				const VECTOR * const mv = (pParam->vol_flags & XVID_VOL_QUARTERPEL) ?										pMB->qmvs : pMB->mvs;				skip_possible &= ((mv->x|mv->y) == 0);			}			if ((pMB->mode == MODE_NOT_CODED) || (skip_possible)) {				/* This is a candidate for SKIPping, but for P-VOPs check intermediate B-frames first */				int bSkip = 1;				if (current->coding_type == P_VOP) {	/* special rule for P-VOP's SKIP */					for (k = pEnc->bframenum_head; k < pEnc->bframenum_tail; k++) {						int iSAD;						iSAD = sad16(reference->image.y + 16*y*pParam->edged_width + 16*x,										pEnc->bframes[k]->image.y + 16*y*pParam->edged_width + 16*x,										pParam->edged_width, BFRAME_SKIP_THRESHHOLD * pMB->quant);						if (iSAD >= BFRAME_SKIP_THRESHHOLD * pMB->quant) {							bSkip = 0; /* could not SKIP */							if (pParam->vol_flags & XVID_VOL_QUARTERPEL) {								VECTOR predMV = get_qpmv2(current->mbs, pParam->mb_width, 0, x, y, 0);								pMB->pmvs[0].x = - predMV.x;								pMB->pmvs[0].y = - predMV.y;							} else {								VECTOR predMV = get_pmv2(current->mbs, pParam->mb_width, 0, x, y, 0);								pMB->pmvs[0].x = - predMV.x;								pMB->pmvs[0].y = - predMV.y;							}							pMB->mode = MODE_INTER;							pMB->cbp = 0;							break;						}					}				}				if (bSkip) {					/* do SKIP */					pMB->mode = MODE_NOT_CODED;					MBSkip(bs);					stop_coding_timer();					continue;	/* next MB */				}			}			/* ordinary case: normal coded INTER/INTER4V block */			MBCoding(current, pMB, qcoeff, bs, &pEnc->current->sStat);			stop_coding_timer();		}	}	emms();	updateFcode(&current->sStat, pEnc);	/* frame drop code */#if 0	DPRINTF(XVID_DEBUG_DEBUG, "kmu %i %i %i\n", current->sStat.kblks, current->sStat.mblks, current->sStat.ublks);#endif	if (current->sStat.kblks + current->sStat.mblks <=		(pParam->frame_drop_ratio * mb_width * mb_height) / 100 &&		( (pEnc->bframenum_head >= pEnc->bframenum_tail) || !(pEnc->mbParam.global_flags & XVID_GLOBAL_CLOSED_GOP)) )	{		current->sStat.kblks = current->sStat.mblks = 0;		current->sStat.ublks = mb_width * mb_height;		BitstreamReset(bs);		set_timecodes(current,reference,pParam->fbase);		BitstreamWriteVopHeader(bs, &pEnc->mbParam, current, 0, current->mbs[0].quant);		/* copy reference frame details into the current frame */		current->quant = reference->quant;		current->motion_flags = reference->motion_flags;		current->rounding_type = reference->rounding_type;		current->fcode = reference->fcode;		current->bcode = reference->bcode;		current->stamp = reference->stamp;		image_copy(&current->image, &reference->image, pParam->edged_width, pParam->height);		memcpy(current->mbs, reference->mbs, sizeof(MACROBLOCK) * mb_width * mb_height);		coded = 0;		} else {		pEnc->current->is_edged = 0; /* not edged */		pEnc->current->is_interpolated = -1; /* not interpolated (fake rounding -1) */		/* what was this frame's interpolated reference will become 			forward (past) reference in b-frame coding */		image_swap(&pEnc->vInterH, &pEnc->f_refh);		image_swap(&pEnc->vInterV, &pEnc->f_refv);		image_swap(&pEnc->vInterHV, &pEnc->f_refhv);	}	/* XXX: debug	{		char s[100];		sprintf(s, "\\%05i_cur.pgm", pEnc->m_framenum);		image_dump_yuvpgm(&current->image,			pParam->edged_width,			pParam->width, pParam->height, s);		sprintf(s, "\\%05i_ref.pgm", pEnc->m_framenum);		image_dump_yuvpgm(&reference->image,			pParam->edged_width,			pParam->width, pParam->height, s);	}	*/	BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */	current->length = (BitstreamPos(bs) - bits) / 8;	return coded;}static voidFrameCodeB(Encoder * pEnc,		   FRAMEINFO * frame,		   Bitstream * bs){	int bits = BitstreamPos(bs);	DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);	DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);	uint32_t x, y;	IMAGE *f_ref = &pEnc->reference->image;	IMAGE *b_ref = &pEnc->current->image;	#ifdef BFRAMES_DEC_DEBUG	FILE *fp;	static char first=0;#define BFRAME_DEBUG  	if (!first && fp){ \		fprintf(fp,"Y=%3d   X=%3d   MB=%2d   CBP=%02X\n",y,x,mb->mode,mb->cbp); \	}	if (!first){		fp=fopen("C:\\XVIDDBGE.TXT","w");	}#endif	/* forward  */	if (!pEnc->reference->is_edged) {		image_setedges(f_ref, pEnc->mbParam.edged_width,					   pEnc->mbParam.edged_height, pEnc->mbParam.width,					   pEnc->mbParam.height, 0);		pEnc->current->is_edged = 1;		}	if (pEnc->reference->is_interpolated != 0) {		start_timer();		image_interpolate(f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,						  pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,						  (pEnc->mbParam.vol_flags & XVID_VOL_QUARTERPEL), 0);		stop_inter_timer();		pEnc->reference->is_interpolated = 0;	}	/* backward */	if (!pEnc->current->is_edged) {		image_setedges(b_ref, pEnc->mbParam.edged_width,					   pEnc->mbParam.edged_height, pEnc->mbParam.width,					   pEnc->mbParam.height, 0);		pEnc->current->is_edged = 1;	}	if (pEnc->current->is_interpolated != 0) {		start_timer();		image_interpolate(b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,						pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,						(pEnc->mbParam.vol_flags & XVID_VOL_QUARTERPEL), 0);		stop_inter_timer();		pEnc->current->is_interpolated = 0;	}	frame->coding_type = B_VOP;	call_plugins(pEnc, pEnc->current, NULL, XVID_PLG_FRAME, NULL, NULL, NULL);	start_timer();	MotionEstimationBVOP(&pEnc->mbParam, frame,						 ((int32_t)(pEnc->current->stamp - frame->stamp)),				/* time_bp */						 ((int32_t)(pEnc->current->stamp - pEnc->reference->stamp)), 	/* time_pp */						 pEnc->reference->mbs, f_ref,						 &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,						 pEnc->current, b_ref, &pEnc->vInterH,						 &pEnc->vInterV, &pEnc->vInterHV);	stop_motion_timer();	set_timecodes(frame, pEnc->reference,pEnc->mbParam.fbase);	BitstreamWriteVopHeader(bs, &pEnc->mbParam, frame, 1, frame->quant);	frame->sStat.iTextBits = 0;	frame->sStat.iMvSum = 0;	frame->sStat.iMvCount = 0;	frame->sStat.kblks = frame->sStat.mblks = frame->sStat.ublks = 0;	frame->sStat.mblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height;	frame->sStat.kblks = frame->sStat.ublks = 0;	for (y = 0; y < pEnc->mbParam.mb_height; y++) {		for (x = 0; x < pEnc->mbParam.mb_width; x++) {			MACROBLOCK * const mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];			/* decoder ignores mb when refence block is INTER(0,0), CBP=0 */			if (mb->mode == MODE_NOT_CODED) {				if (pEnc->mbParam.plugin_flags & XVID_REQORIGINAL) {					MBMotionCompensation(mb, x, y, f_ref, NULL, f_ref, NULL, NULL, &frame->image,											NULL, 0, 0, pEnc->mbParam.edged_width, 0, 0);				}				continue;			}			mb->quant = frame->quant;			if (mb->cbp != 0 || pEnc->mbParam.plugin_flags & XVID_REQORIGINAL) {				/* we have to motion-compensate, transfer etc, 					because there might be blocks to code */				MBMotionCompensationBVOP(&pEnc->mbParam, mb, x, y, &frame->image,										 f_ref, &pEnc->f_refh, &pEnc->f_refv,										 &pEnc->f_refhv, b_ref, &pEnc->vInterH,										 &pEnc->vInterV, &pEnc->vInterHV,										 dct_codes);				mb->cbp = MBTransQuantInterBVOP(&pEnc->mbParam, frame, mb, x, y,  dct_codes, qcoeff);			}						if (mb->mode == MODE_DIRECT_NO4V)				mb->mode = MODE_DIRECT;			if (mb->mode == MODE_DIRECT && (mb->cbp | mb->pmvs[3].x | mb->pmvs[3].y) == 0)				mb->mode = MODE_DIRECT_NONE_MV;	/* skipped */			else 				if (frame->vop_flags & XVID_VOP_GREYSCALE)					/* keep only bits 5-2 -- Chroma blocks will just be skipped by MBCodingBVOP */					mb->cbp &= 0x3C;			start_timer();			MBCodingBVOP(frame, mb, qcoeff, frame->fcode, frame->bcode, bs,						 &frame->sStat);			stop_coding_timer();		}	}	emms();	BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */	frame->length = (BitstreamPos(bs) - bits) / 8;#ifdef BFRAMES_DEC_DEBUG	if (!first){		first=1;		if (fp)			fclose(fp);	}#endif}

⌨️ 快捷键说明

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