--- trunk/xvidcore/src/motion/motion_est.c 2003/02/19 21:59:30 876 +++ trunk/xvidcore/src/motion/motion_est.c 2003/04/05 15:54:59 973 @@ -81,30 +81,28 @@ static __inline uint32_t d_mv_bits(int x, int y, const VECTOR pred, const uint32_t iFcode, const int qpel, const int rrv) { - int xb, yb; - x = qpel ? x<<1 : x; - y = qpel ? y<<1 : y; + int bits; + const int q = (1 << (iFcode - 1)) - 1; + + x <<= qpel; + y <<= qpel; if (rrv) { x = RRV_MV_SCALEDOWN(x); y = RRV_MV_SCALEDOWN(y); } x -= pred.x; + bits = (x != 0 ? iFcode:0); + x = abs(x); + x += q; + x >>= (iFcode - 1); + bits += mvtab[x]; + y -= pred.y; + bits += (y != 0 ? iFcode:0); + y = abs(y); + y += q; + y >>= (iFcode - 1); + bits += mvtab[y]; - if (x) { - x = ABS(x); - x += (1 << (iFcode - 1)) - 1; - x >>= (iFcode - 1); - if (x > 32) x = 32; - xb = mvtab[x] + iFcode; - } else xb = 1; - - if (y) { - y = ABS(y); - y += (1 << (iFcode - 1)) - 1; - y >>= (iFcode - 1); - if (y > 32) y = 32; - yb = mvtab[y] + iFcode; - } else yb = 1; - return xb + yb; + return bits; } static int32_t ChromaSAD2(int fx, int fy, int bx, int by, const SearchData * const data) @@ -249,8 +247,15 @@ ref1 = GetReferenceB(halfpel_x, halfpel_y, dir, data); ref1 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; switch( ((x&1)<<1) + (y&1) ) { - case 0: // pure halfpel position - return (uint8_t *) ref1; + case 3: // x and y in qpel resolution - the "corners" (top left/right and + // bottom left/right) during qpel refinement + ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data); + ref3 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data); + ref4 = GetReferenceB(x - halfpel_x, y - halfpel_y, dir, data); + ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; + ref3 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; + ref4 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; + interpolate8x8_avg4(Reference, ref1, ref2, ref3, ref4, iEdgedWidth, rounding); break; case 1: // x halfpel, y qpel - top or bottom during qpel refinement @@ -265,16 +270,9 @@ interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); break; - default: // x and y in qpel resolution - the "corners" (top left/right and - // bottom left/right) during qpel refinement - ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data); - ref3 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data); - ref4 = GetReferenceB(x - halfpel_x, y - halfpel_y, dir, data); - ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; - ref3 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; - ref4 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; - interpolate8x8_avg4(Reference, ref1, ref2, ref3, ref4, iEdgedWidth, rounding); - break; + default: // pure halfpel position + return (uint8_t *) ref1; + } return Reference; } @@ -319,7 +317,7 @@ interpolate8x8_avg2(Reference+8*iEdgedWidth+8, ref1+8*iEdgedWidth+8, ref2+8*iEdgedWidth+8, iEdgedWidth, rounding, 8); break; - case 0: // pure halfpel position + default: // pure halfpel position return (uint8_t *) ref1; } return Reference; @@ -355,7 +353,7 @@ data->temp[1] += (data->lambda8 * t * (data->temp[1] + NEIGH_8X8_BIAS))>>10; if (data->chroma) sad += ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3], - (yc >> 1) + roundtab_79[yc & 0x3], data); + (yc >> 1) + roundtab_79[yc & 0x3], data); if (sad < data->iMinSAD[0]) { data->iMinSAD[0] = sad; @@ -379,12 +377,18 @@ { int32_t sad; uint32_t t; const uint8_t * Reference; + VECTOR * current; if ( (x > data->max_dx) || (x < data->min_dx) || (y > data->max_dy) || (y < data->min_dy) ) return; - if (!data->qpel_precision) Reference = GetReference(x, y, data); - else Reference = Interpolate8x8qpel(x, y, 0, 0, data); + if (!data->qpel_precision) { + Reference = GetReference(x, y, data); + current = data->currentMV; + } else { // x and y are in 1/4 precision + Reference = Interpolate8x8qpel(x, y, 0, 0, data); + current = data->currentQMV; + } sad = sad8(data->Cur, Reference, data->iEdgedWidth); t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0); @@ -393,7 +397,7 @@ if (sad < *(data->iMinSAD)) { *(data->iMinSAD) = sad; - data->currentMV->x = x; data->currentMV->y = y; + current->x = x; current->y = y; *dir = Direction; } } @@ -405,7 +409,7 @@ uint32_t t; const uint8_t * Reference; - if ( (!(x&1) && x !=0) || (!(y&1) && y !=0) || //non-zero integer value + if ( (!(x&1) && x !=0) || (!(y&1) && y !=0) || //non-zero even value (x > data->max_dx) || (x < data->min_dx) || (y > data->max_dy) || (y < data->min_dy) ) return; @@ -440,8 +444,8 @@ uint32_t t; VECTOR * current; - if ( (x > data->max_dx) | ( x < data->min_dx) - | (y > data->max_dy) | (y < data->min_dy) ) return; + if ( (x > data->max_dx) || ( x < data->min_dx) + || (y > data->max_dy) || (y < data->min_dy) ) return; if (data->rrv && (!(x&1) && x !=0) | (!(y&1) && y !=0) ) return; //non-zero even value @@ -506,8 +510,9 @@ const uint8_t *ReferenceF, *ReferenceB; VECTOR *current; - if ( (xf > data->max_dx) | (xf < data->min_dx) - | (yf > data->max_dy) | (yf < data->min_dy) ) return; + if ((xf > data->max_dx) || (xf < data->min_dx) || + (yf > data->max_dy) || (yf < data->min_dy)) + return; if (!data->qpel_precision) { ReferenceF = GetReference(xf, yf, data); @@ -552,7 +557,7 @@ const uint8_t *ReferenceB; VECTOR mvs, b_mvs; - if (( x > 31) | ( x < -32) | ( y > 31) | (y < -32)) return; + if (( x > 31) || ( x < -32) || ( y > 31) || (y < -32)) return; for (k = 0; k < 4; k++) { mvs.x = data->directmvF[k].x + x; @@ -565,10 +570,11 @@ data->directmvB[k].y : mvs.y - data->referencemv[k].y); - if ( (mvs.x > data->max_dx) | (mvs.x < data->min_dx) - | (mvs.y > data->max_dy) | (mvs.y < data->min_dy) - | (b_mvs.x > data->max_dx) | (b_mvs.x < data->min_dx) - | (b_mvs.y > data->max_dy) | (b_mvs.y < data->min_dy) ) return; + if ((mvs.x > data->max_dx) || (mvs.x < data->min_dx) || + (mvs.y > data->max_dy) || (mvs.y < data->min_dy) || + (b_mvs.x > data->max_dx) || (b_mvs.x < data->min_dx) || + (b_mvs.y > data->max_dy) || (b_mvs.y < data->min_dy) ) + return; if (data->qpel) { xcf += mvs.x/2; ycf += mvs.y/2; @@ -610,7 +616,7 @@ const uint8_t *ReferenceB; VECTOR mvs, b_mvs; - if (( x > 31) | ( x < -32) | ( y > 31) | (y < -32)) return; + if (( x > 31) || ( x < -32) || ( y > 31) || (y < -32)) return; mvs.x = data->directmvF[0].x + x; b_mvs.x = ((x == 0) ? @@ -622,10 +628,10 @@ data->directmvB[0].y : mvs.y - data->referencemv[0].y); - if ( (mvs.x > data->max_dx) | (mvs.x < data->min_dx) - | (mvs.y > data->max_dy) | (mvs.y < data->min_dy) - | (b_mvs.x > data->max_dx) | (b_mvs.x < data->min_dx) - | (b_mvs.y > data->max_dy) | (b_mvs.y < data->min_dy) ) return; + if ( (mvs.x > data->max_dx) || (mvs.x < data->min_dx) + || (mvs.y > data->max_dy) || (mvs.y < data->min_dy) + || (b_mvs.x > data->max_dx) || (b_mvs.x < data->min_dx) + || (b_mvs.y > data->max_dy) || (b_mvs.y < data->min_dy) ) return; if (data->qpel) { xcf = 4*(mvs.x/2); ycf = 4*(mvs.y/2); @@ -659,7 +665,7 @@ CheckCandidateBits16(const int x, const int y, const int Direction, int * const dir, const SearchData * const data) { - static int16_t in[64], coeff[64]; + int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64; int32_t bits = 0, sum; VECTOR * current; const uint8_t * ptr; @@ -721,7 +727,7 @@ } } - bits += cbpy_tab[15-(cbp>>2)].len; + bits += xvid_cbpy_tab[15-(cbp>>2)].len; bits += mcbpc_inter_tab[(MODE_INTER & 7) | ((cbp & 3) << 3)].len; if (bits < data->iMinSAD[0]) { @@ -744,7 +750,7 @@ CheckCandidateBits8(const int x, const int y, const int Direction, int * const dir, const SearchData * const data) { - static int16_t in[64], coeff[64]; + int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64; int32_t sum, bits; VECTOR * current; const uint8_t * ptr; @@ -950,21 +956,22 @@ const uint32_t stride, const uint32_t iQuant, int rrv) { + int offset = (x + y*stride)*8; if(!rrv) { - uint32_t sadC = sad8(current->u + x*8 + y*stride*8, - reference->u + x*8 + y*stride*8, stride); + uint32_t sadC = sad8(current->u + offset, + reference->u + offset, stride); if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0; - sadC += sad8(current->v + (x + y*stride)*8, - reference->v + (x + y*stride)*8, stride); + sadC += sad8(current->v + offset, + reference->v + offset, stride); if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0; return 1; } else { - uint32_t sadC = sad16(current->u + x*16 + y*stride*16, - reference->u + x*16 + y*stride*16, stride, 256*4096); + uint32_t sadC = sad16(current->u + 2*offset, + reference->u + 2*offset, stride, 256*4096); if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP*4) return 0; - sadC += sad16(current->v + (x + y*stride)*16, - reference->v + (x + y*stride)*16, stride, 256*4096); + sadC += sad16(current->v + 2*offset, + reference->v + 2*offset, stride, 256*4096); if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP*4) return 0; return 1; } @@ -1000,12 +1007,16 @@ uint32_t x, y; uint32_t iIntra = 0; int32_t quant = current->quant, sad00; + int skip_thresh = INITIAL_SKIP_THRESH * + (current->global_flags & XVID_REDUCED ? 4:1) * + (current->global_flags & XVID_MODEDECISION_BITS ? 2:1); // some pre-initialized thingies for SearchP int32_t temp[8]; VECTOR currentMV[5]; VECTOR currentQMV[5]; int32_t iMinSAD[5]; + DECLARE_ALIGNED_MATRIX(dct_space, 2, 64, int16_t, CACHE_LINE); SearchData Data; memset(&Data, 0, sizeof(SearchData)); Data.iEdgedWidth = iEdgedWidth; @@ -1018,6 +1029,7 @@ Data.qpel = pParam->m_quarterpel; Data.chroma = MotionFlags & PMV_CHROMA16; Data.rrv = current->global_flags & XVID_REDUCED; + Data.dctSpace = dct_space; if ((current->global_flags & XVID_REDUCED)) { mb_width = (pParam->width + 31) / 32; @@ -1066,7 +1078,7 @@ //initial skip decision /* no early skip for GMC (global vector = skip vector is unknown!) */ if (!(current->global_flags & XVID_GMC)) { /* no fast SKIP for S(GMC)-VOPs */ - if (pMB->dquant == NO_CHANGE && sad00 < pMB->quant * INITIAL_SKIP_THRESH * (Data.rrv ? 4:1) ) + if (pMB->dquant == NO_CHANGE && sad00 < pMB->quant * skip_thresh) if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv)) { SkipMacroblockP(pMB, sad00); continue; @@ -1079,17 +1091,11 @@ current->global_flags & XVID_INTER4V, pMB); /* final skip decision, a.k.a. "the vector you found, really that good?" */ - if (!(current->global_flags & XVID_GMC)) { + if (!(current->global_flags & XVID_GMC || current->global_flags & XVID_MODEDECISION_BITS)) { if ( pMB->dquant == NO_CHANGE && sad00 < pMB->quant * MAX_SAD00_FOR_SKIP) { - if (!(current->global_flags & XVID_MODEDECISION_BITS)) { - if ( (100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH * (Data.rrv ? 4:1) ) - if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv)) - SkipMacroblockP(pMB, sad00); - } else { // BITS mode decision - if (pMB->sad16 > 10) - SkipMacroblockP(pMB, sad00); // more than 10 bits would be used for this MB - skip - - } + if ( (100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH * (Data.rrv ? 4:1) ) + if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv)) + SkipMacroblockP(pMB, sad00); } } if (pMB->mode == MODE_INTRA) @@ -1178,13 +1184,12 @@ int mode = MODE_INTER; if (!(GlobalFlags & XVID_MODEDECISION_BITS)) { //normal, fast, SAD-based mode decision -// int intra = 0; int sad; int InterBias = MV16_INTER_BIAS; if (inter4v == 0 || Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] + Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant) { - mode = 0; //inter - sad = Data->iMinSAD[0]; + mode = MODE_INTER; + sad = Data->iMinSAD[0]; } else { mode = MODE_INTER4V; sad = Data->iMinSAD[1] + Data->iMinSAD[2] + @@ -1211,7 +1216,7 @@ dev16(Data->Cur + 8*Data->iEdgedWidth, Data->iEdgedWidth) + dev16(Data->Cur+8+8*Data->iEdgedWidth, Data->iEdgedWidth); - if (deviation < (sad - InterBias)) return MODE_INTRA;// intra + if (deviation < (sad - InterBias)) return MODE_INTRA; } return mode; @@ -1232,8 +1237,8 @@ if (bits == 0) return MODE_INTER; // quick stop if (inter4v) { - int inter4v = CountMBBitsInter4v(Data, pMB, pMBs, x, y, pParam, MotionFlags, backup); - if (inter4v < bits) { Data->iMinSAD[0] = bits = inter4v; mode = MODE_INTER4V; } + int bits_inter4v = CountMBBitsInter4v(Data, pMB, pMBs, x, y, pParam, MotionFlags, backup); + if (bits_inter4v < bits) { Data->iMinSAD[0] = bits = bits_inter4v; mode = MODE_INTER4V; } } @@ -1291,8 +1296,7 @@ if (pMB->dquant != NO_CHANGE) inter4v = 0; - for(i = 0; i < 5; i++) - Data->currentMV[i].x = Data->currentMV[i].y = 0; + memset(Data->currentMV, 0, 5*sizeof(VECTOR)); if (Data->qpel) Data->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x, y, 0); else Data->predMV = pmv[0]; @@ -1384,14 +1388,16 @@ Data->currentQMV[i].y = 2 * Data->currentMV[i].y; } - if (MotionFlags & PMV_QUARTERPELREFINE16) + if (MotionFlags & PMV_QUARTERPELREFINE16) { + + get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, + pParam->width, pParam->height, Data->iFcode, 1, 0); + if ((!(MotionFlags & QUARTERPELREFINE16_BITS)) || (Data->iMinSAD[0] < 200*(int)iQuant)) { Data->qpel_precision = 1; - get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, - pParam->width, pParam->height, Data->iFcode, 1, 0); - SubpelRefine(Data); } + } if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) && (Data->iMinSAD[0] < (int32_t)iQuant * 30)) inter4v = 0; @@ -1712,9 +1718,9 @@ for (k = 0; k < 4; k++) { dy += Data->directmvF[k].y / div; - dx += Data->directmvF[0].x / div; - b_dy += Data->directmvB[0].y / div; - b_dx += Data->directmvB[0].x / div; + dx += Data->directmvF[k].x / div; + b_dy += Data->directmvB[k].y / div; + b_dx += Data->directmvB[k].x / div; } dy = (dy >> 3) + roundtab_76[dy & 0xf]; @@ -1734,7 +1740,13 @@ b_Ref->v + (y*8 + b_dy/2) * stride + x*8 + b_dx/2, stride); - if (sum < 2 * MAX_CHROMA_SAD_FOR_SKIP * pMB->quant) pMB->mode = MODE_DIRECT_NONE_MV; //skipped + if (sum < 2 * MAX_CHROMA_SAD_FOR_SKIP * pMB->quant) { + pMB->mode = MODE_DIRECT_NONE_MV; //skipped + for (k = 0; k < 4; k++) { + pMB->qmvs[k] = pMB->mvs[k]; + pMB->b_qmvs[k] = pMB->b_mvs[k]; + } + } } static __inline uint32_t @@ -1823,6 +1835,7 @@ } } + *Data->iMinSAD += Data->lambda16; skip_sad = *Data->iMinSAD; // DIRECT MODE DELTA VECTOR SEARCH. @@ -2149,7 +2162,7 @@ int i, mask; VECTOR pmv[3]; - MACROBLOCK * pMB = &pMBs[x + y * pParam->mb_width]; + MACROBLOCK * const pMB = &pMBs[x + y * pParam->mb_width]; for (i = 0; i < 5; i++) Data->iMinSAD[i] = MV_MAX_ERROR; @@ -2163,7 +2176,7 @@ else Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0); //else median get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, - pParam->width, pParam->height, Data->iFcode - pParam->m_quarterpel, 0, Data->rrv); + pParam->width, pParam->height, Data->iFcode - pParam->m_quarterpel, 0, 0); Data->Cur = pCur + (x + y * pParam->edged_width) * 16; Data->Ref = pRef + (x + y * pParam->edged_width) * 16; @@ -2175,43 +2188,48 @@ pmv[0].x = pmv[0].y = 0; CheckCandidate32I(0, 0, 255, &i, Data); + Data->iMinSAD[1] -= 50; + Data->iMinSAD[2] -= 50; + Data->iMinSAD[3] -= 50; + Data->iMinSAD[4] -= 50; - if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP * 4) { + if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP) { if (!(mask = make_mask(pmv, 1))) CheckCandidate32I(pmv[1].x, pmv[1].y, mask, &i, Data); if (!(mask = make_mask(pmv, 2))) CheckCandidate32I(pmv[2].x, pmv[2].y, mask, &i, Data); - if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP * 4) // diamond only if needed + if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP) // diamond only if needed DiamondSearch(Data->currentMV->x, Data->currentMV->y, Data, i); + } - for (i = 0; i < 4; i++) { - MACROBLOCK * MB = &pMBs[x + (i&1) + (y+(i>>1)) * pParam->mb_width]; - MB->mvs[0] = MB->mvs[1] = MB->mvs[2] = MB->mvs[3] = Data->currentMV[i]; - MB->mode = MODE_INTER; - MB->sad16 = Data->iMinSAD[i+1]; - } + for (i = 0; i < 4; i++) { + MACROBLOCK * MB = &pMBs[x + (i&1) + (y+(i>>1)) * pParam->mb_width]; + MB->mvs[0] = MB->mvs[1] = MB->mvs[2] = MB->mvs[3] = Data->currentMV[i]; + MB->mode = MODE_INTER; + MB->sad16 = Data->iMinSAD[i+1]; } } -#define INTRA_BIAS 2500 -#define INTRA_THRESH 1500 -#define INTER_THRESH 1400 +#define INTRA_THRESH 2400 +#define INTER_THRESH 1100 int MEanalysis( const IMAGE * const pRef, - FRAMEINFO * const Current, - MBParam * const pParam, - int maxIntra, //maximum number if non-I frames - int intraCount, //number of non-I frames after last I frame; 0 if we force P/B frame - int bCount) // number of B frames in a row + const FRAMEINFO * const Current, + const MBParam * const pParam, + const int maxIntra, //maximum number if non-I frames + const int intraCount, //number of non-I frames after last I frame; 0 if we force P/B frame + const int bCount, // number of B frames in a row + const int b_thresh) { uint32_t x, y, intra = 0; int sSAD = 0; MACROBLOCK * const pMBs = Current->mbs; const IMAGE * const pCurrent = &Current->image; - int IntraThresh = INTRA_THRESH, InterThresh = INTER_THRESH; + int IntraThresh = INTRA_THRESH, InterThresh = INTER_THRESH + 10*b_thresh; + int s = 0, blocks = 0; int32_t iMinSAD[5], temp[5]; VECTOR currentMV[5]; @@ -2220,26 +2238,32 @@ Data.currentMV = currentMV; Data.iMinSAD = iMinSAD; Data.iFcode = Current->fcode; - Data.rrv = Current->global_flags & XVID_REDUCED; Data.temp = temp; CheckCandidate = CheckCandidate32I; if (intraCount != 0 && intraCount < 10) // we're right after an I frame - IntraThresh += 4 * (intraCount - 10) * (intraCount - 10); + IntraThresh += 8 * (intraCount - 10) * (intraCount - 10); else if ( 5*(maxIntra - intraCount) < maxIntra) // we're close to maximum. 2 sec when max is 10 sec IntraThresh -= (IntraThresh * (maxIntra - 5*(maxIntra - intraCount)))/maxIntra; - InterThresh += 400 * (1 - bCount); - if (InterThresh < 300) InterThresh = 300; + InterThresh -= (350 - 8*b_thresh) * bCount; + if (InterThresh < 300 + 5*b_thresh) InterThresh = 300 + 5*b_thresh; if (sadInit) (*sadInit) (); for (y = 1; y < pParam->mb_height-1; y += 2) { for (x = 1; x < pParam->mb_width-1; x += 2) { int i; + blocks += 4; if (bCount == 0) pMBs[x + y * pParam->mb_width].mvs[0] = zeroMV; + else { //extrapolation of the vector found for last frame + pMBs[x + y * pParam->mb_width].mvs[0].x = + (pMBs[x + y * pParam->mb_width].mvs[0].x * (bCount+1) ) / bCount; + pMBs[x + y * pParam->mb_width].mvs[0].y = + (pMBs[x + y * pParam->mb_width].mvs[0].y * (bCount+1) ) / bCount; + } MEanalyzeMB(pRef->y, pCurrent->y, x, y, pParam, pMBs, &Data); @@ -2251,19 +2275,24 @@ pParam->edged_width); if (dev + IntraThresh < pMB->sad16) { pMB->mode = MODE_INTRA; - if (++intra > (pParam->mb_height-2)*(pParam->mb_width-2)/2) return I_VOP; + if (++intra > ((pParam->mb_height-2)*(pParam->mb_width-2))/2) return I_VOP; } } + if (pMB->mvs[0].x == 0 && pMB->mvs[0].y == 0) s++; + sSAD += pMB->sad16; } } } - sSAD /= (pParam->mb_height-2)*(pParam->mb_width-2); -// if (sSAD > IntraThresh + INTRA_BIAS) return I_VOP; + + sSAD /= blocks; + s = (10*s) / blocks; + + if (s > 5) sSAD += (s - 4) * (180 - 2*b_thresh); //static block - looks bad when in bframe... + if (sSAD > InterThresh ) return P_VOP; emms(); return B_VOP; - } @@ -2531,7 +2560,7 @@ int cbp = 0, bits = 0, t = 0, i, iDirection; SearchData Data2, *Data8 = &Data2; int sumx = 0, sumy = 0; - int16_t in[64], coeff[64]; + int16_t *in = Data->dctSpace, *coeff = Data->dctSpace + 64; memcpy(Data8, Data, sizeof(SearchData)); CheckCandidate = CheckCandidateBits8; @@ -2658,7 +2687,7 @@ bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]); cbp |= 1 << (5 - 5); } - bits += cbpy_tab[15-(cbp>>2)].len; + bits += xvid_cbpy_tab[15-(cbp>>2)].len; bits += mcbpc_inter_tab[(MODE_INTER4V & 7) | ((cbp & 3) << 3)].len; } } @@ -2673,7 +2702,7 @@ int bits = 1; //this one is ac/dc prediction flag. always 1. int cbp = 0, i, t, dc = 0, b_dc = 1024; const uint32_t iQuant = Data->lambda16; - int16_t in[64], coeff[64]; + int16_t *in = Data->dctSpace, * coeff = Data->dctSpace + 64; for(i = 0; i < 4; i++) { uint32_t iDcScaler = get_dc_scaler(iQuant, 1); @@ -2708,9 +2737,9 @@ bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcc_tab[coeff[0] + 255].len; if (t != 0) cbp |= 1 << (5 - 4); - Data->temp[4] = t; if (bits < Data->iMinSAD[0]) { + iDcScaler = get_dc_scaler(iQuant, 1); //chroma V transfer_8to16copy(in, Data->CurV, Data->iEdgedWidth/2); fdct(in); @@ -2721,16 +2750,9 @@ bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcc_tab[coeff[0] + 255].len; if (t != 0) cbp |= 1 << (5 - 5); - Data->temp[5] = t; - - bits += t = cbpy_tab[cbp>>2].len; - Data->temp[6] = t; - - bits += t = mcbpc_inter_tab[(MODE_INTRA & 7) | ((cbp & 3) << 3)].len; - Data->temp[7] = t; - + bits += xvid_cbpy_tab[cbp>>2].len; + bits += mcbpc_inter_tab[(MODE_INTRA & 7) | ((cbp & 3) << 3)].len; } } - return bits; }