--- encoder.c 2002/11/28 14:45:21 1.76.2.23 +++ encoder.c 2002/12/14 06:07:02 1.76.2.31 @@ -39,7 +39,7 @@ * MinChen * 14.04.2002 added FrameCodeB() * - * $Id: encoder.c,v 1.76.2.23 2002/11/28 14:45:21 syskin Exp $ + * $Id: encoder.c,v 1.76.2.31 2002/12/14 06:07:02 suxen_drol Exp $ * ****************************************************************************/ @@ -224,14 +224,14 @@ pEnc->mbParam.m_quant_type = H263_QUANT; - pEnc->sStat.fMvPrevSigma = -1; + pEnc->fMvPrevSigma = -1; /* Fill rate control parameters */ pEnc->bitrate = pParam->rc_bitrate; pEnc->iFrameNum = 0; - pEnc->iMaxKeyInterval = pParam->max_key_interval; + pEnc->mbParam.iMaxKeyInterval = pParam->max_key_interval; /* try to allocate frame memory */ @@ -324,11 +324,11 @@ /* B Frames specific init */ - pEnc->global = pParam->global; + pEnc->mbParam.global = pParam->global; pEnc->mbParam.max_bframes = pParam->max_bframes; - pEnc->bquant_ratio = pParam->bquant_ratio; - pEnc->bquant_offset = pParam->bquant_offset; - pEnc->frame_drop_ratio = pParam->frame_drop_ratio; + pEnc->mbParam.bquant_ratio = pParam->bquant_ratio; + pEnc->mbParam.bquant_offset = pParam->bquant_offset; + pEnc->mbParam.frame_drop_ratio = pParam->frame_drop_ratio; pEnc->bframes = NULL; if (pEnc->mbParam.max_bframes > 0) { @@ -646,6 +646,16 @@ +/* convert pFrame->intra to coding_type */ +static int intra2coding_type(int intra) +{ + if (intra < 0) return -1; + if (intra == 1) return I_VOP; + if (intra == 2) return B_VOP; + + return P_VOP; +} + /***************************************************************************** @@ -749,7 +759,7 @@ indentical to the future-referece frame. */ - if ((pEnc->global & XVID_GLOBAL_PACKED)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_PACKED)) { int tmp; DPRINTF(DPRINTF_DEBUG,"*** EMPTY bf: head=%i tail=%i queue: head=%i tail=%i size=%i", @@ -784,7 +794,7 @@ SWAP(pEnc->current, pEnc->reference); SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_dx50bvop]); - if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 100, "DX50 IVOP"); } @@ -855,6 +865,7 @@ // only inc frame num, adapt quant, etc. if we havent seen it before if (pEnc->bframenum_dx50bvop < 0 ) { + mode = intra2coding_type(pFrame->intra); if (pFrame->quant == 0) pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0); else @@ -882,7 +893,7 @@ emms(); - if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 5, "%i if:%i st:%i", pEnc->m_framenum++, pEnc->iFrameNum, pEnc->current->stamp); } @@ -928,14 +939,19 @@ * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ pEnc->iFrameNum++; - if (pEnc->iFrameNum == 0 || pFrame->intra == 1 || pEnc->bframenum_dx50bvop >= 0 || - (pFrame->intra < 0 && pEnc->iMaxKeyInterval > 0 && - pEnc->iFrameNum >= pEnc->iMaxKeyInterval) - || 2 == (mode = MEanalysis(&pEnc->reference->image, pEnc->current, - &pEnc->mbParam, pEnc->iMaxKeyInterval, - (pFrame->intra < 0) ? pEnc->iFrameNum : 0, - bframes_count++))) { + if (pEnc->iFrameNum == 0 || pEnc->bframenum_dx50bvop >= 0 || + (mode < 0 && pEnc->mbParam.iMaxKeyInterval > 0 && + pEnc->iFrameNum >= pEnc->mbParam.iMaxKeyInterval)) + { + mode = I_VOP; + }else{ + mode = MEanalysis(&pEnc->reference->image, pEnc->current, + &pEnc->mbParam, pEnc->mbParam.iMaxKeyInterval, + (mode < 0) ? pEnc->iFrameNum : 0, + bframes_count++); + } + if (mode == I_VOP) { /* * This will be coded as an Intra Frame */ @@ -958,19 +974,19 @@ pEnc->bframenum_head, pEnc->bframenum_tail, pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); - if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "IVOP"); } // when we reach an iframe in DX50BVOP mode, encode the last bframe as a pframe - if ((pEnc->global & XVID_GLOBAL_DX50BVOP) && pEnc->bframenum_tail > 0) { + if ((pEnc->mbParam.global & XVID_GLOBAL_DX50BVOP) && pEnc->bframenum_tail > 0) { pEnc->bframenum_tail--; pEnc->bframenum_dx50bvop = pEnc->bframenum_tail; SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_dx50bvop]); - if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 100, "DX50 BVOP->PVOP"); } FrameCodeP(pEnc, &bs, &bits, 1, 0); @@ -989,7 +1005,7 @@ pEnc->flush_bframes = 1; - if ((pEnc->global & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail > 0) { + if ((pEnc->mbParam.global & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail > 0) { BitstreamPadAlways(&bs); input_valid = 0; goto ipvop_loop; @@ -999,8 +1015,7 @@ * NB : sequences like "IIBB" decode fine with msfdam but, * go screwy with divx 5.00 */ - } else if (pEnc->bframenum_tail >= pEnc->mbParam.max_bframes || mode != 0) { -// } else if (pFrame->intra == 0 || pEnc->bframenum_tail >= pEnc->mbParam.max_bframes || mode != 0) { + } else if (mode == P_VOP || pEnc->bframenum_tail >= pEnc->mbParam.max_bframes) { /* * This will be coded as a Predicted Frame */ @@ -1009,7 +1024,7 @@ pEnc->bframenum_head, pEnc->bframenum_tail, pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); - if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "PVOP"); } @@ -1018,24 +1033,24 @@ pFrame->intra = 0; pEnc->flush_bframes = 1; - if ((pEnc->global & XVID_GLOBAL_PACKED) && (pEnc->bframenum_tail > 0)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_PACKED) && (pEnc->bframenum_tail > 0)) { BitstreamPadAlways(&bs); input_valid = 0; goto ipvop_loop; } - } else { + } else { /* mode == B_VOP */ /* * This will be coded as a Bidirectional Frame */ - if ((pEnc->global & XVID_GLOBAL_DEBUG)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "BVOP"); } if (pFrame->bquant < 1) { pEnc->current->quant = ((((pEnc->reference->quant + pEnc->current->quant) * - pEnc->bquant_ratio) / 2) + pEnc->bquant_offset)/100; + pEnc->mbParam.bquant_ratio) / 2) + pEnc->mbParam.bquant_offset)/100; } else { pEnc->current->quant = pFrame->bquant; @@ -1069,10 +1084,10 @@ if (pResult) { pResult->quant = pEnc->current->quant; - pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8); - pResult->kblks = pEnc->sStat.kblks; - pResult->mblks = pEnc->sStat.mblks; - pResult->ublks = pEnc->sStat.ublks; + pResult->hlength = pFrame->length - (pEnc->current->sStat.iTextBits / 8); + pResult->kblks = pEnc->current->sStat.kblks; + pResult->mblks = pEnc->current->sStat.mblks; + pResult->ublks = pEnc->current->sStat.ublks; } emms(); @@ -1235,8 +1250,8 @@ if (pFrame->intra < 0) { if ((pEnc->iFrameNum == 0) - || ((pEnc->iMaxKeyInterval > 0) - && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval))) { + || ((pEnc->mbParam.iMaxKeyInterval > 0) + && (pEnc->iFrameNum >= pEnc->mbParam.iMaxKeyInterval))) { pFrame->intra = FrameCodeI(pEnc, &bs, &bits); } else { pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header); @@ -1257,10 +1272,10 @@ if (pResult) { pResult->quant = pEnc->current->quant; - pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8); - pResult->kblks = pEnc->sStat.kblks; - pResult->mblks = pEnc->sStat.mblks; - pResult->ublks = pEnc->sStat.ublks; + pResult->hlength = pFrame->length - (pEnc->current->sStat.iTextBits / 8); + pResult->kblks = pEnc->current->sStat.kblks; + pResult->mblks = pEnc->current->sStat.mblks; + pResult->ublks = pEnc->current->sStat.ublks; } emms(); @@ -1518,12 +1533,28 @@ Bitstream * bs, uint32_t * pBits) { + int mb_width = pEnc->mbParam.mb_width; + int mb_height = pEnc->mbParam.mb_height; DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE); uint16_t x, y; + if ((pEnc->current->global_flags & XVID_REDUCED)) + { + mb_width = (pEnc->mbParam.width + 31) / 32; + mb_height = (pEnc->mbParam.height + 31) / 32; + + /* 16x16->8x8 downsample requires 1 additional edge pixel*/ + /* XXX: setedges is overkill */ + start_timer(); + image_setedges(&pEnc->current->image, + pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, + pEnc->mbParam.width, pEnc->mbParam.height); + stop_edges_timer(); + } + pEnc->iFrameNum = 0; pEnc->mbParam.m_rounding_type = 1; pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type; @@ -1532,8 +1563,9 @@ BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current); + /* XXX: move this stuff to BitstreamWriteVolHeader */ #define DIVX501B481P "DivX501b481p" - if ((pEnc->global & XVID_GLOBAL_PACKED)) { + if ((pEnc->mbParam.global & XVID_GLOBAL_PACKED)) { BitstreamWriteUserData(bs, DIVX501B481P, strlen(DIVX501B481P)); } @@ -1545,12 +1577,12 @@ *pBits = BitstreamPos(bs); - pEnc->sStat.iTextBits = 0; - pEnc->sStat.kblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; - pEnc->sStat.mblks = pEnc->sStat.ublks = 0; + pEnc->current->sStat.iTextBits = 0; + pEnc->current->sStat.kblks = mb_width * mb_height; + pEnc->current->sStat.mblks = pEnc->current->sStat.ublks = 0; - for (y = 0; y < pEnc->mbParam.mb_height; y++) - for (x = 0; x < pEnc->mbParam.mb_width; x++) { + for (y = 0; y < mb_height; y++) + for (x = 0; x < mb_width; x++) { MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width]; @@ -1569,16 +1601,20 @@ qcoeff[4*64+0]=0; /* zero, because for INTRA MBs DC value is saved */ qcoeff[5*64+0]=0; } - MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat); + MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat); stop_coding_timer(); } + if ((pEnc->current->global_flags & XVID_REDUCED)) + { + image_deblock_rrv(&pEnc->current->image, pEnc->mbParam.edged_width, + pEnc->current->mbs, mb_width, mb_height, pEnc->mbParam.mb_width, + 16, XVID_DEC_DEBLOCKY|XVID_DEC_DEBLOCKUV); + } emms(); *pBits = BitstreamPos(bs) - *pBits; - pEnc->sStat.fMvPrevSigma = -1; - pEnc->sStat.iMvSum = 0; - pEnc->sStat.iMvCount = 0; + pEnc->fMvPrevSigma = -1; pEnc->mbParam.m_fcode = 2; if (pEnc->current->global_flags & XVID_HINTEDME_GET) { @@ -1604,6 +1640,9 @@ DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE); + int mb_width = pEnc->mbParam.mb_width; + int mb_height = pEnc->mbParam.mb_height; + int iLimit; int x, y, k; int iSearchRange; @@ -1612,6 +1651,13 @@ /* IMAGE *pCurrent = &pEnc->current->image; */ IMAGE *pRef = &pEnc->reference->image; + if ((pEnc->current->global_flags & XVID_REDUCED)) + { + mb_width = (pEnc->mbParam.width + 31) / 32; + mb_height = (pEnc->mbParam.height + 31) / 32; + } + + start_timer(); image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height); @@ -1623,11 +1669,9 @@ pEnc->current->fcode = pEnc->mbParam.m_fcode; if (!force_inter) - iLimit = - (int) (pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * - INTRA_THRESHOLD); + iLimit = (int)(mb_width * mb_height * INTRA_THRESHOLD); else - iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1; + iLimit = mb_width * mb_height + 1; if ((pEnc->current->global_flags & XVID_HALFPEL)) { start_timer(); @@ -1647,21 +1691,15 @@ pEnc->current->coding_type = P_VOP; start_timer(); - if (pEnc->current->global_flags & XVID_HINTEDME_SET) { + if (pEnc->current->global_flags & XVID_HINTEDME_SET) HintedMESet(pEnc, &bIntra); - if (bIntra == 0) { - pEnc->current->fcode = FindFcode(&pEnc->mbParam, pEnc->current); - MotionEstimationHinted(&pEnc->mbParam, pEnc->current, pEnc->reference, - &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV); - } - - } else { + else bIntra = MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, iLimit); - } + stop_motion_timer(); if (bIntra == 1) return FrameCodeI(pEnc, bs, pBits); @@ -1679,11 +1717,11 @@ *pBits = BitstreamPos(bs); - pEnc->sStat.iTextBits = pEnc->sStat.iMvSum = pEnc->sStat.iMvCount = - pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0; + pEnc->current->sStat.iTextBits = pEnc->current->sStat.iMvSum = pEnc->current->sStat.iMvCount = + pEnc->current->sStat.kblks = pEnc->current->sStat.mblks = pEnc->current->sStat.ublks = 0; - for (y = 0; y < pEnc->mbParam.mb_height; y++) { - for (x = 0; x < pEnc->mbParam.mb_width; x++) { + for (y = 0; y < mb_height; y++) { + for (x = 0; x < mb_width; x++) { MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width]; @@ -1698,6 +1736,7 @@ pEnc->mbParam.height, pEnc->mbParam.edged_width, pEnc->mbParam.m_quarterpel, + (pEnc->current->global_flags & XVID_REDUCED), pEnc->current->rounding_type); stop_comp_timer(); @@ -1730,13 +1769,13 @@ stop_prediction_timer(); if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) { - pEnc->sStat.kblks++; + pEnc->current->sStat.kblks++; } else 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) { - pEnc->sStat.mblks++; + pEnc->current->sStat.mblks++; } else { - pEnc->sStat.ublks++; + pEnc->current->sStat.ublks++; } start_timer(); @@ -1786,7 +1825,7 @@ } pMB->mode = MODE_INTER; pMB->cbp = 0; - MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat); + MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat); } else { @@ -1800,23 +1839,30 @@ qcoeff[4*64+0]=0; /* zero, because DC for INTRA MBs DC value is saved */ qcoeff[5*64+0]=0; } - MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat); + MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat); } stop_coding_timer(); } } + if ((pEnc->current->global_flags & XVID_REDUCED)) + { + image_deblock_rrv(&pEnc->current->image, pEnc->mbParam.edged_width, + pEnc->current->mbs, mb_width, mb_height, pEnc->mbParam.mb_width, + 16, XVID_DEC_DEBLOCKY|XVID_DEC_DEBLOCKUV); + } + emms(); if (pEnc->current->global_flags & XVID_HINTEDME_GET) { HintedMEGet(pEnc, 0); } - if (pEnc->sStat.iMvCount == 0) - pEnc->sStat.iMvCount = 1; + if (pEnc->current->sStat.iMvCount == 0) + pEnc->current->sStat.iMvCount = 1; - fSigma = (float) sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount); + fSigma = (float) sqrt((float) pEnc->current->sStat.iMvSum / pEnc->current->sStat.iMvCount); iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode); @@ -1826,24 +1872,23 @@ pEnc->mbParam.m_fcode++; iSearchRange *= 2; } else if ((fSigma < iSearchRange / 6) - && (pEnc->sStat.fMvPrevSigma >= 0) - && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6) + && (pEnc->fMvPrevSigma >= 0) + && (pEnc->fMvPrevSigma < iSearchRange / 6) && (pEnc->mbParam.m_fcode >= (2 + pEnc->mbParam.m_quarterpel))) // minimum search range 16 { pEnc->mbParam.m_fcode--; iSearchRange /= 2; } - pEnc->sStat.fMvPrevSigma = fSigma; + pEnc->fMvPrevSigma = fSigma; -#ifdef FRAMEDROP /* frame drop code */ - // DPRINTF(DPRINTF_DEBUG, "kmu %i %i %i", pEnc->sStat.kblks, pEnc->sStat.mblks, pEnc->sStat.ublks); - if (pEnc->sStat.kblks + pEnc->sStat.mblks < - (pEnc->frame_drop_ratio * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height) / 100) + // DPRINTF(DPRINTF_DEBUG, "kmu %i %i %i", pEnc->current->sStat.kblks, pEnc->current->sStat.mblks, pEnc->current->sStat.ublks); + if (pEnc->current->sStat.kblks + pEnc->current->sStat.mblks < + (pEnc->mbParam.frame_drop_ratio * mb_width * mb_height) / 100) { - pEnc->sStat.kblks = pEnc->sStat.mblks = 0; - pEnc->sStat.ublks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; + pEnc->current->sStat.kblks = pEnc->current->sStat.mblks = 0; + pEnc->current->sStat.ublks = mb_width * mb_height; BitstreamReset(bs); @@ -1858,10 +1903,24 @@ pEnc->current->fcode = pEnc->reference->fcode; pEnc->current->bcode = pEnc->reference->bcode; image_copy(&pEnc->current->image, &pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.height); - memcpy(pEnc->current->mbs, pEnc->reference->mbs, sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height); - + memcpy(pEnc->current->mbs, pEnc->reference->mbs, sizeof(MACROBLOCK) * mb_width * mb_height); } -#endif + + /* XXX: debug + { + char s[100]; + sprintf(s, "\\%05i_cur.pgm", pEnc->m_framenum); + image_dump_yuvpgm(&pEnc->current->image, + pEnc->mbParam.edged_width, + pEnc->mbParam.width, pEnc->mbParam.height, s); + + sprintf(s, "\\%05i_ref.pgm", pEnc->m_framenum); + image_dump_yuvpgm(&pEnc->reference->image, + pEnc->mbParam.edged_width, + pEnc->mbParam.width, pEnc->mbParam.height, s); + } + */ + *pBits = BitstreamPos(bs) - *pBits; @@ -1869,7 +1928,7 @@ } -static __inline void +static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, @@ -1889,6 +1948,8 @@ fprintf(fp,"Y=%3d X=%3d MB=%2d CBP=%02X\n",y,x,mb->mode,mb->cbp); \ } + pEnc->current->global_flags &= ~XVID_REDUCED; /* reduced resoltion not yet supported */ + if (!first){ fp=fopen("C:\\XVIDDBGE.TXT","w"); } @@ -1941,16 +2002,16 @@ *pBits = BitstreamPos(bs); - pEnc->sStat.iTextBits = 0; - pEnc->sStat.iMvSum = 0; - pEnc->sStat.iMvCount = 0; - pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0; + frame->sStat.iTextBits = 0; + frame->sStat.iMvSum = 0; + frame->sStat.iMvCount = 0; + frame->sStat.kblks = frame->sStat.mblks = 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]; - int direction = pEnc->global & XVID_ALTERNATESCAN ? 2 : 0; + int direction = pEnc->mbParam.global & XVID_ALTERNATESCAN ? 2 : 0; // decoder ignores mb when refence block is INTER(0,0), CBP=0 if (mb->mode == MODE_NOT_CODED) { @@ -1982,7 +2043,7 @@ #endif start_timer(); MBCodingBVOP(mb, qcoeff, frame->fcode, frame->bcode, bs, - &pEnc->sStat, direction); + &frame->sStat, direction); stop_coding_timer(); } }