--- trunk/xvidcore/src/motion/motion_est.c 2002/09/06 16:59:47 430 +++ trunk/xvidcore/src/motion/motion_est.c 2002/09/07 09:12:22 437 @@ -6,7 +6,6 @@ * Copyright(C) 2002 Christoph Lampert * Copyright(C) 2002 Michael Militzer * Copyright(C) 2002 Edouard Gomez - * Copyright(C) 2002 chenm001 * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending @@ -3082,341 +3081,3 @@ return iMinSAD; } - - -/* *********************************************************** - bvop motion estimation -***************************************************************/ - -void -MotionEstimationBVOP(MBParam * const pParam, - FRAMEINFO * const frame, - const int32_t time_bp, - const int32_t time_pp, - // forward (past) reference - const MACROBLOCK * const f_mbs, - const IMAGE * const f_ref, - const IMAGE * const f_refH, - const IMAGE * const f_refV, - const IMAGE * const f_refHV, - // backward (future) reference - const MACROBLOCK * const b_mbs, - const IMAGE * const b_ref, - const IMAGE * const b_refH, - const IMAGE * const b_refV, - const IMAGE * const b_refHV) -{ - const int mb_width = pParam->mb_width; - const int mb_height = pParam->mb_height; - const int edged_width = pParam->edged_width; - - const int32_t iWidth = pParam->width; - const int32_t iHeight = pParam->height; - - int i, j, k; - - static const VECTOR zeroMV={0,0}; - - int f_sad16; /* forward (as usual) search */ - int b_sad16; /* backward (only in b-frames) search */ - int i_sad16; /* interpolated (both direction, b-frames only) */ - int d_sad16; /* direct mode (assume almost linear motion) */ - - int best_sad; - - VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ - VECTOR f_interpolMV, b_interpolMV; - VECTOR pmv_dontcare; - - int min_dx, max_dx, min_dy, max_dy; - int f_min_dx, f_max_dx, f_min_dy, f_max_dy; - int b_min_dx, b_max_dx, b_min_dy, b_max_dy; - - int f_count=0; - int b_count=0; - int i_count=0; - int d_count=0; - - const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; - const int64_t TRD = (int32_t)time_pp; - - // fprintf(stderr,"TRB = %lld TRD = %lld time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp); - // note: i==horizontal, j==vertical - for (j = 0; j < mb_height; j++) { - - f_predMV = zeroMV; /* prediction is reset at left boundary */ - b_predMV = zeroMV; - - for (i = 0; i < mb_width; i++) { - MACROBLOCK *mb = &frame->mbs[i + j * mb_width]; - const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; - const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; - - mb->deltamv=zeroMV; - -/* special case, if collocated block is SKIPed: encoding is forward (0,0), cpb=0 without further ado */ - - if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && - b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { - mb->mode = MODE_NOT_CODED; - mb->b_mvs[0] = mb->mvs[0] = zeroMV; - continue; - } - - if (b_mb->mode == MODE_INTER4V) - { - d_sad16 = 0; - /* same method of scaling as in decoder.c, so we copy from there */ - for (k = 0; k < 4; k++) { - - mb->directmv[k] = b_mb->mvs[k]; - - mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); - mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) - ? ((TRB - TRD) * mb->directmv[k].x) / TRD - : mb->mvs[k].x - mb->directmv[k].x); - - mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); - mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0) - ? ((TRB - TRD) * mb->directmv[k].y) / TRD - : mb->mvs[k].y - mb->directmv[k].y); - - d_sad16 += - sad8bi(frame->image.y + (2*i+(k&1))*8 + (2*j+(k>>1))*8*edged_width, - get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - (2*i+(k&1)), (2*j+(k>>1)), 8, &mb->mvs[k], edged_width), - get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - (2*i+(k&1)), (2*j+(k>>1)), 8, &mb->b_mvs[k], edged_width), - edged_width); - } - } - else - { - mb->directmv[3] = mb->directmv[2] = mb->directmv[1] = - mb->directmv[0] = b_mb->mvs[0]; - - mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x); - mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) - ? ((TRB - TRD) * mb->directmv[0].x) / TRD - : mb->mvs[0].x - mb->directmv[0].x); - - mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); - mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) - ? ((TRB - TRD) * mb->directmv[0].y) / TRD - : mb->mvs[0].y - mb->directmv[0].y); - - d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, - get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - i, j, 16, &mb->mvs[0], edged_width), - get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - i, j, 16, &mb->b_mvs[0], edged_width), - edged_width); - - } - d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant); - - // forward search - f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - &frame->image, i, j, - mb->mvs[0].x, mb->mvs[0].y, /* start point f_directMV */ - f_predMV.x, f_predMV.y, /* center is f-prediction */ - frame->motion_flags, - frame->quant, frame->fcode, pParam, - f_mbs, f_mbs, - &mb->mvs[0], &pmv_dontcare); - - - // backward search - b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - &frame->image, i, j, - mb->b_mvs[0].x, mb->b_mvs[0].y, /* start point b_directMV */ - b_predMV.x, b_predMV.y, /* center is b-prediction */ - frame->motion_flags, - frame->quant, frame->bcode, pParam, - b_mbs, b_mbs, - &mb->b_mvs[0], &pmv_dontcare); - - i_sad16 = - sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, - get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - i, j, 16, &mb->mvs[0], edged_width), - get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - i, j, 16, &mb->b_mvs[0], edged_width), - edged_width); - i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y, - frame->fcode, frame->quant); - i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y, - frame->bcode, frame->quant); - - get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight, - frame->fcode); - get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight, - frame->bcode); - -/* Interpolated MC motion vector search, this is tedious and more complicated because there are - two values for everything, always one for backward and one for forward ME. Still, we don't gain - much from this search, maybe it should simply be skipped and simply current i_sad16 value used - as "optimal". */ - - i_sad16 = Diamond16_InterpolMainSearch( - f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - frame->image.y + i * 16 + j * 16 * edged_width, - b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - i, j, - mb->mvs[0].x, mb->mvs[0].y, - mb->b_mvs[0].x, mb->b_mvs[0].y, - i_sad16, - &f_interpolMV, &b_interpolMV, - f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y, - f_min_dx, f_max_dx, f_min_dy, f_max_dy, - b_min_dx, b_max_dx, b_min_dy, b_max_dy, - edged_width, 2, - frame->fcode, frame->bcode,frame->quant,0); - - i_sad16 = Diamond16_InterpolMainSearch( - f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - frame->image.y + i * 16 + j * 16 * edged_width, - b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - i, j, - f_interpolMV.x, f_interpolMV.y, - b_interpolMV.x, b_interpolMV.y, - i_sad16, - &f_interpolMV, &b_interpolMV, - f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y, - f_min_dx, f_max_dx, f_min_dy, f_max_dy, - b_min_dx, b_max_dx, b_min_dy, b_max_dy, - edged_width, 1, - frame->fcode, frame->bcode,frame->quant,0); // equiv to halfpel refine - - -/* DIRECT MODE DELTA VECTOR SEARCH. - This has to be made more effective, but at the moment I'm happy it's running at all */ - -/* There are two range restrictions for direct mode: deltaMV is limited to [-32,31] in halfpel units, and - absolute vector must not lie outside of image dimensions. Constraint one is dealt with by CHECK_MV16_DIRECT - and for constraint two we need distance to boundary. This is done by get_range very large fcode (hack!) */ - - get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19); - - d_sad16 = Diamond16_DirectMainSearch( - f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - frame->image.y + i*16 + j*16*edged_width, - b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - i, j, - TRB,TRD, - 0,0, - d_sad16, - &mb->deltamv, - mb->directmv, // this has to be pre-initialized with b_mb->mvs[] - min_dx, max_dx, min_dy, max_dy, - edged_width, 2, frame->quant, 0); - - d_sad16 = Diamond16_DirectMainSearch( - f_ref->y, f_refH->y, f_refV->y, f_refHV->y, - frame->image.y + i*16 + j*16*edged_width, - b_ref->y, b_refH->y, b_refV->y, b_refHV->y, - i, j, - TRB,TRD, - mb->deltamv.x, mb->deltamv.y, - d_sad16, - &mb->deltamv, - mb->directmv, // this has to be pre-initialized with b_mb->mvs[] - min_dx, max_dx, min_dy, max_dy, - edged_width, 1, frame->quant, 0); // equiv to halfpel refine - - -// i_sad16 = 65535; /* remove the comment to disable any of the MODEs */ -// f_sad16 = 65535; -// b_sad16 = 65535; -// d_sad16 = 65535; - - if (f_sad16 < b_sad16) { - best_sad = f_sad16; - mb->mode = MODE_FORWARD; - } else { - best_sad = b_sad16; - mb->mode = MODE_BACKWARD; - } - - if (i_sad16 < best_sad) { - best_sad = i_sad16; - mb->mode = MODE_INTERPOLATE; - } - - if (d_sad16 < best_sad) { - - if (b_mb->mode == MODE_INTER4V) - { - - /* how to calc vectors is defined in standard. mvs[] and b_mvs[] are only for motion compensation */ - /* for the bitstream, the value mb->deltamv is read directly */ - - for (k = 0; k < 4; k++) { - - mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); - mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) - ? ((TRB - TRD) * mb->directmv[k].x) / TRD - : mb->mvs[k].x - mb->directmv[k].x); - - mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); - mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0) - ? ((TRB - TRD) * mb->directmv[k].y) / TRD - : mb->mvs[k].y - mb->directmv[k].y); - } - } - else - { - mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x); - - mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) - ? ((TRB - TRD) * mb->directmv[0].x) / TRD - : mb->mvs[0].x - mb->directmv[0].x); - - mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); - - mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0) - ? ((TRB - TRD) * mb->directmv[0].y) / TRD - : mb->mvs[0].y - mb->directmv[0].y); - - mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0]; - mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0]; - } - - best_sad = d_sad16; - mb->mode = MODE_DIRECT; - } - - switch (mb->mode) - { - case MODE_FORWARD: - f_count++; - f_predMV = mb->mvs[0]; - break; - case MODE_BACKWARD: - b_count++; - b_predMV = mb->b_mvs[0]; - - break; - case MODE_INTERPOLATE: - i_count++; - mb->mvs[0] = f_interpolMV; - mb->b_mvs[0] = b_interpolMV; - f_predMV = mb->mvs[0]; - b_predMV = mb->b_mvs[0]; - break; - case MODE_DIRECT: - d_count++; - break; - default: - break; - } - - } - } - -#ifdef _DEBUG_BFRAME_STAT - fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D: %04d\n", - f_count,b_count,i_count,d_count); -#endif - -}