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

📄 encoder.c

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

	if (pEnc->queue == NULL)
		goto xvid_err_memory4;

	for (n = 0; n < pEnc->mbParam.max_bframes+1; n++)
		image_null(&pEnc->queue[n].image);


	for (n = 0; n < pEnc->mbParam.max_bframes+1; n++) {
		if (image_create
			(&pEnc->queue[n].image, pEnc->mbParam.edged_width,
			 pEnc->mbParam.edged_height) < 0)
			goto xvid_err_memory5;
	}

	/* timestamp stuff */

	pEnc->mbParam.m_stamp = 0;
	pEnc->m_framenum = 0;
	pEnc->current->stamp = 0;
	pEnc->reference->stamp = 0;

	/* other stuff */

	pEnc->iFrameNum = 0;
	pEnc->fMvPrevSigma = -1;

	/* multithreaded stuff */
	if (create->num_threads > 0) {
		int t = create->num_threads;
		int rows_per_thread = (pEnc->mbParam.mb_height+t-1)/t;
		pEnc->num_threads = t;
		pEnc->motionData = xvid_malloc(t*sizeof(SMPmotionData), CACHE_LINE);
		if (!pEnc->motionData) 
			goto xvid_err_nosmp;
		
		for (n = 0; n < t; n++) {
			pEnc->motionData[n].complete_count_self =
				xvid_malloc(rows_per_thread * sizeof(int), CACHE_LINE);

			if (!pEnc->motionData[n].complete_count_self)
				goto xvid_err_nosmp;
		
			if (n != 0) 
				pEnc->motionData[n].complete_count_above = 
					pEnc->motionData[n-1].complete_count_self;
		}
		pEnc->motionData[0].complete_count_above =
			pEnc->motionData[t-1].complete_count_self - 1;

	} else {
  xvid_err_nosmp:
		/* no SMP */
		create->num_threads = 0;
		pEnc->motionData = NULL;
	}

	create->handle = (void *) pEnc;

	init_timer();
	init_mpeg_matrix(pEnc->mbParam.mpeg_quant_matrices);

	return 0;   /* ok */

	/*
	 * We handle all XVID_ERR_MEMORY here, this makes the code lighter
	 */

  xvid_err_memory5:

	for (n = 0; n < pEnc->mbParam.max_bframes+1; n++) {
			image_destroy(&pEnc->queue[n].image, pEnc->mbParam.edged_width,
						  pEnc->mbParam.edged_height);
		}

	xvid_free(pEnc->queue);

  xvid_err_memory4:

	if (pEnc->mbParam.max_bframes > 0) {
		int i;

		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);
	}

  xvid_err_memory3:

	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);
	}

	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->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);

/* destroy GMC image */
	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);
	}

	if(pEnc->mbParam.plugin_flags & XVID_REQLAMBDA) {
		xvid_free(pEnc->temp_lambda);
	}

  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, NULL, NULL);
		}
	}
	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
 *
 ****************************************************************************/

int
enc_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->mbParam.plugin_flags & XVID_REQLAMBDA)) {
		xvid_free(pEnc->temp_lambda);
	}

	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, NULL);
			}
		}
		xvid_free(pEnc->plugins);
	}

	xvid_free(pEnc->mbParam.mpeg_quant_matrices);

	if (pEnc->num_zones > 0)
		xvid_free(pEnc->zones);

	if (pEnc->num_threads > 0) {
		for (i = 0; i < pEnc->num_threads; i++)
			xvid_free(pEnc->motionData[i].complete_count_self);

		xvid_free(pEnc->motionData);
	}

	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, k;
	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*sizeof(int));
		}

		if(pEnc->mbParam.plugin_flags & XVID_REQLAMBDA) {
			int block = 0;
			emms();
			data.lambda = pEnc->temp_lambda;
			for(i = 0;i < pEnc->mbParam.mb_height; i++)
				for(j = 0;j < pEnc->mbParam.mb_width; j++)
					for (k = 0; k < 6; k++) 
						data.lambda[block++] = 1.0f;
		}

	} 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;

⌨️ 快捷键说明

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