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

📄 encoder.c

📁 视频压缩编解码标准MPEG4商业级别的VC代码实现标准
💻 C
📖 第 1 页 / 共 4 页
字号:
	image_destroy(&pEnc->vGMC, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);  xvid_err_memory2a:	xvid_free(pEnc->mbParam.mpeg_quant_matrices);  xvid_err_memory2:	xvid_free(pEnc->current->mbs);	xvid_free(pEnc->reference->mbs);  xvid_err_memory1:	xvid_free(pEnc->current);	xvid_free(pEnc->reference);  xvid_err_memory1a:	if ((pEnc->mbParam.plugin_flags & XVID_REQDQUANTS)) {		xvid_free(pEnc->temp_dquants);	}  xvid_err_memory0:	for (n=0; n<pEnc->num_plugins;n++) {		if (pEnc->plugins[n].func) {			pEnc->plugins[n].func(pEnc->plugins[n].param, XVID_PLG_DESTROY, 0, 0);		}	}	xvid_free(pEnc->plugins);	xvid_free(pEnc->zones);	xvid_free(pEnc);	create->handle = NULL;	return XVID_ERR_MEMORY;}/***************************************************************************** * Encoder destruction * * This function destroy the entire encoder structure created by a previous * successful enc_create call. * * Returned values (for now only one returned value) : *	- 0	 - no errors * ****************************************************************************/intenc_destroy(Encoder * pEnc){	int i;	/* B Frames specific */	for (i = 0; i < pEnc->mbParam.max_bframes+1; i++) {		image_destroy(&pEnc->queue[i].image, pEnc->mbParam.edged_width,					  pEnc->mbParam.edged_height);	}	xvid_free(pEnc->queue);	if (pEnc->mbParam.max_bframes > 0) {		for (i = 0; i < pEnc->mbParam.max_bframes; i++) {			if (pEnc->bframes[i] == NULL)				continue;			image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width,					  pEnc->mbParam.edged_height);			xvid_free(pEnc->bframes[i]->mbs);			xvid_free(pEnc->bframes[i]);		}		xvid_free(pEnc->bframes);	}	/* All images, reference, current etc ... */	image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->f_refh, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->f_refv, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->f_refhv, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	image_destroy(&pEnc->vGMC, pEnc->mbParam.edged_width,				  pEnc->mbParam.edged_height);	if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) {		image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width,					  pEnc->mbParam.edged_height);		image_destroy(&pEnc->sOriginal2, pEnc->mbParam.edged_width,					  pEnc->mbParam.edged_height);	}	/* Encoder structure */	xvid_free(pEnc->current->mbs);	xvid_free(pEnc->current);	xvid_free(pEnc->reference->mbs);	xvid_free(pEnc->reference);	if ((pEnc->mbParam.plugin_flags & XVID_REQDQUANTS)) {		xvid_free(pEnc->temp_dquants);	}	if (pEnc->num_plugins>0) {		xvid_plg_destroy_t pdestroy;		memset(&pdestroy, 0, sizeof(xvid_plg_destroy_t));		pdestroy.version = XVID_VERSION;		pdestroy.num_frames = pEnc->m_framenum;		for (i=0; i<pEnc->num_plugins;i++) {			if (pEnc->plugins[i].func) {				pEnc->plugins[i].func(pEnc->plugins[i].param, XVID_PLG_DESTROY, &pdestroy, 0);			}		}		xvid_free(pEnc->plugins);	}	xvid_free(pEnc->mbParam.mpeg_quant_matrices);	if (pEnc->num_plugins>0)		xvid_free(pEnc->zones);	xvid_free(pEnc);	return 0;  /* ok */}/*  call the plugins  */static void call_plugins(Encoder * pEnc, FRAMEINFO * frame, IMAGE * original,						 int opt, int * type, int * quant, xvid_enc_stats_t * stats){	unsigned int i, j;	xvid_plg_data_t data;	/* set data struct */	memset(&data, 0, sizeof(xvid_plg_data_t));	data.version = XVID_VERSION;	/* find zone */	for(i=0; i<pEnc->num_zones && pEnc->zones[i].frame<=frame->frame_num; i++) ;	data.zone = i>0 ? &pEnc->zones[i-1] : NULL;	data.width = pEnc->mbParam.width;	data.height = pEnc->mbParam.height;	data.mb_width = pEnc->mbParam.mb_width;	data.mb_height = pEnc->mbParam.mb_height;	data.fincr = frame->fincr;	data.fbase = pEnc->mbParam.fbase;	data.bquant_ratio = pEnc->mbParam.bquant_ratio;	data.bquant_offset = pEnc->mbParam.bquant_offset;	for (i=0; i<3; i++) {		data.min_quant[i] = pEnc->mbParam.min_quant[i];		data.max_quant[i] = pEnc->mbParam.max_quant[i];	}	data.reference.csp = XVID_CSP_PLANAR;	data.reference.plane[0] = pEnc->reference->image.y;	data.reference.plane[1] = pEnc->reference->image.u;	data.reference.plane[2] = pEnc->reference->image.v;	data.reference.stride[0] = pEnc->mbParam.edged_width;	data.reference.stride[1] = pEnc->mbParam.edged_width/2;	data.reference.stride[2] = pEnc->mbParam.edged_width/2;	data.current.csp = XVID_CSP_PLANAR;	data.current.plane[0] = frame->image.y;	data.current.plane[1] = frame->image.u;	data.current.plane[2] = frame->image.v;	data.current.stride[0] = pEnc->mbParam.edged_width;	data.current.stride[1] = pEnc->mbParam.edged_width/2;	data.current.stride[2] = pEnc->mbParam.edged_width/2;	data.frame_num = frame->frame_num;	if (opt == XVID_PLG_BEFORE) {		data.type = *type;		data.quant = *quant;		data.vol_flags = frame->vol_flags;		data.vop_flags = frame->vop_flags;		data.motion_flags = frame->motion_flags;	} else if (opt == XVID_PLG_FRAME) {		data.type = coding2type(frame->coding_type);		data.quant = frame->quant;		if ((pEnc->mbParam.plugin_flags & XVID_REQDQUANTS)) {			data.dquant = pEnc->temp_dquants;			data.dquant_stride = pEnc->mbParam.mb_width;			memset(data.dquant, 0, data.mb_width*data.mb_height);		}		} else { /* XVID_PLG_AFTER */		if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) {			data.original.csp = XVID_CSP_PLANAR;			data.original.plane[0] = original->y;			data.original.plane[1] = original->u;			data.original.plane[2] = original->v;			data.original.stride[0] = pEnc->mbParam.edged_width;			data.original.stride[1] = pEnc->mbParam.edged_width/2;			data.original.stride[2] = pEnc->mbParam.edged_width/2;		}		if ((frame->vol_flags & XVID_VOL_EXTRASTATS) ||			(pEnc->mbParam.plugin_flags & XVID_REQPSNR)) { 			data.sse_y =				plane_sse( original->y, frame->image.y,						   pEnc->mbParam.edged_width, pEnc->mbParam.width,						   pEnc->mbParam.height);			data.sse_u =				plane_sse( original->u, frame->image.u,						   pEnc->mbParam.edged_width/2, pEnc->mbParam.width/2,						   pEnc->mbParam.height/2); 			data.sse_v =				plane_sse( original->v, frame->image.v,						   pEnc->mbParam.edged_width/2, pEnc->mbParam.width/2,						   pEnc->mbParam.height/2);		}		data.type = coding2type(frame->coding_type);		data.quant = frame->quant;		if ((pEnc->mbParam.plugin_flags & XVID_REQDQUANTS)) {			data.dquant = pEnc->temp_dquants;			data.dquant_stride = pEnc->mbParam.mb_width;			for (j=0; j<pEnc->mbParam.mb_height; j++)			for (i=0; i<pEnc->mbParam.mb_width; i++) {				data.dquant[j*data.dquant_stride + i] = frame->mbs[j*pEnc->mbParam.mb_width + i].dquant;			}		}		data.vol_flags = frame->vol_flags;		data.vop_flags = frame->vop_flags;		data.motion_flags = frame->motion_flags;		data.length = frame->length;		data.kblks = frame->sStat.kblks;		data.mblks = frame->sStat.mblks;		data.ublks = frame->sStat.ublks;		/* New code */		data.stats.type      = coding2type(frame->coding_type);		data.stats.quant     = frame->quant;		data.stats.vol_flags = frame->vol_flags;		data.stats.vop_flags = frame->vop_flags;		data.stats.length    = frame->length;		data.stats.hlength   = frame->length - (frame->sStat.iTextBits / 8);		data.stats.kblks     = frame->sStat.kblks;		data.stats.mblks     = frame->sStat.mblks;		data.stats.ublks     = frame->sStat.ublks;		data.stats.sse_y     = data.sse_y;		data.stats.sse_u     = data.sse_u;		data.stats.sse_v     = data.sse_v;		if (stats)			*stats = data.stats;	}	/* call plugins */	for (i=0; i<(unsigned int)pEnc->num_plugins;i++) {		emms();		if (pEnc->plugins[i].func) {			if (pEnc->plugins[i].func(pEnc->plugins[i].param, opt, &data, 0) < 0) {				continue;			}		}	}	emms();	/* copy modified values back into frame*/	if (opt == XVID_PLG_BEFORE) {		*type = data.type;		*quant = data.quant > 0 ? data.quant : 2;   /* default */		frame->vol_flags = data.vol_flags;		frame->vop_flags = data.vop_flags;		frame->motion_flags = data.motion_flags;		} else if (opt == XVID_PLG_FRAME) {		if ((pEnc->mbParam.plugin_flags & XVID_REQDQUANTS)) {			for (j=0; j<pEnc->mbParam.mb_height; j++)			for (i=0; i<pEnc->mbParam.mb_width; i++) {				frame->mbs[j*pEnc->mbParam.mb_width + i].dquant = data.dquant[j*data.mb_width + i];			}		} else {			for (j=0; j<pEnc->mbParam.mb_height; j++)			for (i=0; i<pEnc->mbParam.mb_width; i++) {				frame->mbs[j*pEnc->mbParam.mb_width + i].dquant = 0;			}		}		frame->mbs[0].quant = data.quant; /* FRAME will not affect the quant in stats */	}}static __inline void inc_frame_num(Encoder * pEnc){	pEnc->current->frame_num = pEnc->m_framenum;	pEnc->current->stamp = pEnc->mbParam.m_stamp;	/* first frame is zero */	pEnc->mbParam.m_stamp += pEnc->current->fincr;	pEnc->m_framenum++;	/* debug ticker */}static __inline void dec_frame_num(Encoder * pEnc){	pEnc->mbParam.m_stamp -= pEnc->mbParam.fincr;	pEnc->m_framenum--;	/* debug ticker */}static __inline void MBSetDquant(MACROBLOCK * pMB, int x, int y, MBParam * mbParam){	if (pMB->cbp == 0) {		/* we want to code dquant but the quantizer value will not be used yet			let's find out if we can postpone dquant to next MB		*/			if (x == mbParam->mb_width-1 && y == mbParam->mb_height-1) {			pMB->dquant = 0; /* it's the last MB of all, the easiest case */			return;		} else {			MACROBLOCK * next = pMB + 1;			const MACROBLOCK * prev = pMB - 1;			if (next->mode != MODE_INTER4V && next->mode != MODE_NOT_CODED)				/* mode allows dquant change in the future */				if (abs(next->quant - prev->quant) <= 2) {					/* quant change is not out of range */					pMB->quant = prev->quant;					pMB->dquant = 0;					next->dquant = next->quant - prev->quant;					return;				}		}			}	/* couldn't skip this dquant */	pMB->mode = MODE_INTER_Q;}			static __inline voidset_timecodes(FRAMEINFO* pCur,FRAMEINFO *pRef, int32_t time_base){	pCur->ticks = (int32_t)pCur->stamp % time_base;	pCur->seconds =  ((int32_t)pCur->stamp / time_base)	- ((int32_t)pRef->stamp / time_base) ;#if 0 	/* HEAVY DEBUG OUTPUT */	fprintf(stderr,"WriteVop:   %d - %d \n",			((int32_t)pCur->stamp / time_base), ((int32_t)pRef->stamp / time_base));	fprintf(stderr,"set_timecodes: VOP %1d   stamp=%lld ref_stamp=%lld  base=%d\n",			pCur->coding_type, pCur->stamp, pRef->stamp, time_base);	fprintf(stderr,"set_timecodes: VOP %1d   seconds=%d   ticks=%d   (ref-sec=%d  ref-tick=%d)\n",			pCur->coding_type, pCur->seconds, pCur->ticks, pRef->seconds, pRef->ticks);#endif}static intgcd(int a, int b){	int r ;	if (b > a) {		r = a;		a = b;		b = r;	}	while ((r = a % b)) {		a = b;		b = r;	}	return b;}static voidsimplify_par(int *par_width, int *par_height){	int _par_width  = (!*par_width)  ? 1 : (*par_width<0)  ? -*par_width:  *par_width;	int _par_height = (!*par_height) ? 1 : (*par_height<0) ? -*par_height: *par_height;	int divisor = gcd(_par_width, _par_height);	_par_width  /= divisor;	_par_height /= divisor;	/* 2^8 precision maximum */	if (_par_width>255 || _par_height>255) {		float div;		emms();		if (_par_width>_par_height)			div = (float)_par_width/255;		else			div = (float)_par_height/255;		_par_width  = (int)((float)_par_width/div);		_par_height = (int)((float)_par_height/div);	}	*par_width = _par_width;	*par_height = _par_height;	return;}/***************************************************************************** * IPB frame encoder entry point * * Returned values : *	- >0			   - output bytes *	- 0				- no output *	- XVID_ERR_VERSION - wrong version passed to core *	- XVID_ERR_END	 - End of stream reached before end of coding *	- XVID_ERR_FORMAT  - the image subsystem reported the image had a wrong *						 format ****************************************************************************/intenc_encode(Encoder * pEnc,			   xvid_enc_frame_t * xFrame,			   xvid_enc_stats_t * stats){	xvid_enc_frame_t * frame;	int type;	Bitstream bs;	if (XVID_VERSION_MAJOR(xFrame->version) != 1 || (stats && XVID_VERSION_MAJOR(stats->version) != 1))	/* v1.x.x */		return XVID_ERR_VERSION;	xFrame->out_flags = 0;	start_global_timer();	BitstreamInit(&bs, xFrame->bitstream, 0);	/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	 * enqueue image to the encoding-queue	 * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */	if (xFrame->input.csp != XVID_CSP_NULL)	{		QUEUEINFO * q = &pEnc->queue[pEnc->queue_tail];		start_timer();		if (image_input			(&q->image, pEnc->mbParam.width, pEnc->mbParam.height,			pEnc->mbParam.edged_width, (uint8_t**)xFrame->input.plane, xFrame->input.stride,			xFrame->input.csp, xFrame->vol_flags & XVID_VOL_INTERLACING))		{			emms();			return XVID_ERR_FORMAT;		}		stop_conv_timer();		if ((xFrame->vop_flags & XVID_VOP_CHROMAOPT)) {			image_chroma_optimize(&q->image,				pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width);		}		q->frame = *xFrame;

⌨️ 快捷键说明

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