📄 encoder.c
字号:
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(¤t->warp, current->mbs, pParam, current, reference, ¤t->image, &reference->image, &pEnc->vInterH, &pEnc->vInterV, &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 */ } } 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 = 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 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 + -