📄 encoder.c
字号:
for (y = 0; y < mb_height; y++) { for (x = 0; x < mb_width; x++) { MACROBLOCK *pMB = ¤t->mbs[x + y * pParam->mb_width]; int bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q); if (bIntra) { 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++; if (pEnc->current->vop_flags & XVID_VOP_GREYSCALE) { pMB->cbp &= 0x3C; /* keep only bits 5-2 */ qcoeff[4*64+0]=0; /* zero, because for INTRA MBs DC value is saved */ qcoeff[5*64+0]=0; } 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->vop_flags & XVID_VOP_REDUCED), current->rounding_type); stop_comp_timer(); pMB->field_pred = 0; if (pMB->mode != MODE_NOT_CODED) { 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) && (pMB->dquant == 0); if (current->coding_type == S_VOP) skip_possible &= (pMB->mcsel == 1); else if (current->coding_type == P_VOP) { if ((pParam->vol_flags & XVID_VOL_QUARTERPEL)) skip_possible &= ( (pMB->qmvs[0].x == 0) && (pMB->qmvs[0].y == 0) ); else skip_possible &= ( (pMB->mvs[0].x == 0) && (pMB->mvs[0].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 */ if (current->coding_type == P_VOP) /* special rule for P-VOP's SKIP */ { int bSkip = 1; 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); if (iSAD >= BFRAME_SKIP_THRESHHOLD * pMB->quant) { bSkip = 0; break; } } if (!bSkip) { /* no SKIP, but trivial block */ 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; MBCoding(current, pMB, qcoeff, bs, ¤t->sStat); stop_coding_timer(); continue; /* next MB */ } } /* do SKIP */ pMB->mode = MODE_NOT_CODED; MBSkip(bs); stop_coding_timer(); continue; /* next MB */ } /* ordinary case: normal coded INTER/INTER4V block */ if ((current->vop_flags & XVID_VOP_GREYSCALE)) { pMB->cbp &= 0x3C; /* keep only bits 5-2 */ qcoeff[4*64+0]=0; /* zero, because DC for INTRA MBs DC value is saved */ qcoeff[5*64+0]=0; } if((pParam->vol_flags & XVID_VOL_QUARTERPEL)) { VECTOR predMV = get_qpmv2(current->mbs, pParam->mb_width, 0, x, y, 0); pMB->pmvs[0].x = pMB->qmvs[0].x - predMV.x; pMB->pmvs[0].y = pMB->qmvs[0].y - predMV.y; DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", pMB->pmvs[0].x, pMB->pmvs[0].y, predMV.x, predMV.y, pMB->mvs[0].x, pMB->mvs[0].y); } else { VECTOR predMV = get_pmv2(current->mbs, pParam->mb_width, 0, x, y, 0); pMB->pmvs[0].x = pMB->mvs[0].x - predMV.x; pMB->pmvs[0].y = pMB->mvs[0].y - predMV.y; DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", pMB->pmvs[0].x, pMB->pmvs[0].y, predMV.x, predMV.y, pMB->mvs[0].x, pMB->mvs[0].y); } if (pMB->mode == MODE_INTER4V) { int k; for (k=1;k<4;k++) { if((pParam->vol_flags & XVID_VOL_QUARTERPEL)) { VECTOR predMV = get_qpmv2(current->mbs, pParam->mb_width, 0, x, y, k); pMB->pmvs[k].x = pMB->qmvs[k].x - predMV.x; pMB->pmvs[k].y = pMB->qmvs[k].y - predMV.y; DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", pMB->pmvs[k].x, pMB->pmvs[k].y, predMV.x, predMV.y, pMB->mvs[k].x, pMB->mvs[k].y); } else { VECTOR predMV = get_pmv2(current->mbs, pParam->mb_width, 0, x, y, k); pMB->pmvs[k].x = pMB->mvs[k].x - predMV.x; pMB->pmvs[k].y = pMB->mvs[k].y - predMV.y; DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", pMB->pmvs[k].x, pMB->pmvs[k].y, predMV.x, predMV.y, pMB->mvs[k].x, pMB->mvs[k].y); } } } MBCoding(current, pMB, qcoeff, bs, &pEnc->current->sStat); stop_coding_timer(); } } if ((current->vop_flags & XVID_VOP_REDUCED)) { image_deblock_rrv(¤t->image, pParam->edged_width, current->mbs, mb_width, mb_height, pParam->mb_width, 16, 0); } emms(); if (current->sStat.iMvCount == 0) current->sStat.iMvCount = 1; fSigma = (float) sqrt((float) current->sStat.iMvSum / current->sStat.iMvCount); iSearchRange = 1 << (3 + pParam->m_fcode); if ((fSigma > iSearchRange / 3) && (pParam->m_fcode <= (3 + (pParam->vol_flags & XVID_VOL_QUARTERPEL?1:0) ))) /* maximum search range 128 */ { pParam->m_fcode++; iSearchRange *= 2; } else if ((fSigma < iSearchRange / 6) && (pEnc->fMvPrevSigma >= 0) && (pEnc->fMvPrevSigma < iSearchRange / 6) && (pParam->m_fcode >= (2 + (pParam->vol_flags & XVID_VOL_QUARTERPEL?1:0) ))) /* minimum search range 16 */ { pParam->m_fcode--; iSearchRange /= 2; } pEnc->fMvPrevSigma = fSigma; /* 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->mbParam.max_bframes == 0) { 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); \ } /* XXX: pEnc->current->global_flags &= ~XVID_VOP_REDUCED; reduced resoltion not yet supported */ 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, 0); } continue; } if (mb->mode != MODE_DIRECT_NONE_MV || pEnc->mbParam.plugin_flags & XVID_REQORIGINAL) { 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); if (mb->mode == MODE_DIRECT_NO4V) mb->mode = MODE_DIRECT; mb->quant = frame->quant; if (mb->mode != MODE_DIRECT_NONE_MV) mb->cbp = MBTransQuantInterBVOP(&pEnc->mbParam, frame, mb, x, y, dct_codes, qcoeff); if ( (mb->mode == MODE_DIRECT) && (mb->cbp == 0) && (mb->pmvs[3].x == 0) && (mb->pmvs[3].y == 0) ) { mb->mode = MODE_DIRECT_NONE_MV; /* skipped */ } } /* keep only bits 5-2 -- Chroma blocks will just be skipped by the * coding function for BFrames, that's why we don't zero teh DC * coeffs */ if ((frame->vop_flags & XVID_VOP_GREYSCALE)) mb->cbp &= 0x3C; start_timer(); MBCodingBVOP(frame, mb, qcoeff, frame->fcode, frame->bcode, bs, &frame->sStat); stop_coding_timer(); } } emms(); /* TODO: dynamic fcode/bcode ??? */ 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 + -