📄 encoder.c
字号:
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 + -