📄 encoder.c
字号:
&pEnc->vInterHV);
} else {
gmcval = globalSAD(¤t->warp, pParam, current->mbs,
current,
&reference->image,
¤t->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, ¤t->warp,
pParam->width, pParam->height,
¤t->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(¤t->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(¤t->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 */
}
}
if (pEnc->num_threads > 0) {
/* multithreaded motion estimation - dispatch threads */
void * status;
int rows_per_thread = (pParam->mb_height + pEnc->num_threads - 1)/pEnc->num_threads;
for (k = 0; k < pEnc->num_threads; k++) {
memset(pEnc->motionData[k].complete_count_self, 0, rows_per_thread * sizeof(int));
pEnc->motionData[k].pParam = &pEnc->mbParam;
pEnc->motionData[k].current = current;
pEnc->motionData[k].reference = reference;
pEnc->motionData[k].pRefH = &pEnc->vInterH;
pEnc->motionData[k].pRefV = &pEnc->vInterV;
pEnc->motionData[k].pRefHV = &pEnc->vInterHV;
pEnc->motionData[k].pGMC = &pEnc->vGMC;
pEnc->motionData[k].y_step = pEnc->num_threads;
pEnc->motionData[k].start_y = k;
/* todo: sort out temp space once and for all */
pEnc->motionData[k].RefQ = pEnc->vInterH.u + 16*k*pParam->edged_width;
}
for (k = 1; k < pEnc->num_threads; k++) {
pthread_create(&pEnc->motionData[k].handle, NULL,
(void*)MotionEstimateSMP, (void*)&pEnc->motionData[k]);
}
MotionEstimateSMP(&pEnc->motionData[0]);
for (k = 1; k < pEnc->num_threads; k++) {
pthread_join(pEnc->motionData[k].handle, &status);
}
current->fcode = 0;
for (k = 0; k < pEnc->num_threads; k++) {
current->sStat.iMvSum += pEnc->motionData[k].mvSum;
current->sStat.iMvCount += pEnc->motionData[k].mvCount;
if (pEnc->motionData[k].minfcode > current->fcode)
current->fcode = pEnc->motionData[k].minfcode;
}
} else {
/* regular ME */
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 = ¤t->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, ¤t->sStat);
stop_coding_timer();
continue;
}
start_timer();
MBMotionCompensation(pMB, x, y, &reference->image,
&pEnc->vInterH, &pEnc->vInterV,
&pEnc->vInterHV, &pEnc->vGMC,
¤t->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(¤t->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 = current->sStat.iTextBits = 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(¤t->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(¤t->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 void
FrameCodeB(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->y, pEnc->f_refh.y, pEnc->f_refv.y, pEnc->f_refhv.y,
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->y, pEnc->vInterH.y, pEnc->vInterV.y, pEnc->vInterHV.y,
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, frame, NULL, XVID_PLG_FRAME, NULL, NULL, NULL);
frame->fcode = frame->bcode = pEnc->current->fcode;
start_timer();
if (pEnc->num_threads > 0) {
void * status;
int k;
/* multithreaded motion estimation - dispatch threads */
int rows_per_thread = (pEnc->mbParam.mb_height + pEnc->num_threads - 1)/pEnc->num_threads;
for (k = 0; k < pEnc->num_threads; k++) {
memset(pEnc->motionData[k].complete_count_self, 0, rows_per_thread * sizeof(int));
pEnc->motionData[k].pParam = &pEnc->mbParam;
pEnc->motionData[k].current = frame;
pEnc->motionData[k].reference = pEnc->current;
pEnc->motionData[k].fRef = f_ref;
pEnc->motionData[k].fRefH = &pEnc->f_refh;
pEnc->motionData[k].fRefV = &pEnc->f_refv;
pEnc->motionData[k].fRefHV = &pEnc->f_refhv;
pEnc->motionData[k].pRef = b_ref;
pEnc->motionData[k].pRefH = &pEnc->vInterH;
pEnc->motionData[k].pRefV = &pEnc->vInterV;
pEnc->motionData[k].pRefHV = &pEnc->vInterHV;
pEnc->motionData[k].time_bp = (int32_t)(pEnc->current->stamp - frame->stamp);
pEnc->motionData[k].time_pp = (int32_t)(pEnc->current->stamp - pEnc->reference->stamp);
pEnc->motionData[k].y_step = pEnc->num_threads;
pEnc->motionData[k].start_y = k;
/* todo: sort out temp space once and for all */
pEnc->motionData[k].RefQ = pEnc->vInterH.u + 16*k*pEnc->mbParam.edged_width;
}
for (k = 1; k < pEnc->num_threads; k++) {
pthread_create(&pEnc->motionData[k].handle, NULL,
(void*)SMPMotionEstimationBVOP, (void*)&pEnc->motionData[k]);
}
SMPMotionEstimationBVOP(&pEnc->motionData[0]);
for (k = 1; k < pEnc->num_threads; k++) {
pthread_join(pEnc->motionData[k].handle, &status);
}
frame->fcode = frame->bcode = 0;
for (k = 0; k < pEnc->num_threads; k++) {
if (pEnc->motionData[k].minfcode > frame->fcode)
frame->fcode = pEnc->motionData[k].minfcode;
if (pEnc->motionData[k].minbcode > frame->bcode)
frame->bcode = pEnc->motionData[k].minbcode;
}
} else {
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.iMVBits = 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_REQORIGINA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -