--- estimation_bvop.c 2010/11/28 15:18:21 1.26 +++ estimation_bvop.c 2010/12/24 13:21:35 1.28 @@ -21,7 +21,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: estimation_bvop.c,v 1.26 2010/11/28 15:18:21 Isibaar Exp $ + * $Id: estimation_bvop.c,v 1.28 2010/12/24 13:21:35 Isibaar Exp $ * ****************************************************************************/ @@ -800,7 +800,8 @@ MACROBLOCK * const pMB, const MACROBLOCK * const b_mb, VECTOR * f_predMV, - VECTOR * b_predMV) + VECTOR * b_predMV, + int force_direct) { int mode = MODE_DIRECT, k; int best_sad, f_sad, b_sad, i_sad; @@ -812,6 +813,9 @@ f_sad = Data_f->iMinSAD[0] + 4*Data_d->lambda16; i_sad = Data_i->iMinSAD[0] + 2*Data_d->lambda16; + if (force_direct) + goto set_mode; /* bypass checks for non-direct modes */ + if (b_sad < best_sad) { mode = MODE_BACKWARD; best_sad = b_sad; @@ -827,6 +831,7 @@ best_sad = i_sad; } +set_mode: pMB->sad16 = best_sad; pMB->mode = mode; pMB->cbp = 63; @@ -961,7 +966,8 @@ const IMAGE * const b_ref, const IMAGE * const b_refH, const IMAGE * const b_refV, - const IMAGE * const b_refHV) + const IMAGE * const b_refHV, + const int num_slices) { uint32_t i, j; int32_t best_sad = 256*4096; @@ -971,6 +977,8 @@ VECTOR f_predMV, b_predMV; + int mb_width = pParam->mb_width; + int mb_height = pParam->mb_height; int MVmaxF = 0, MVmaxB = 0; const int32_t TRB = time_pp - time_bp; const int32_t TRD = time_pp; @@ -1000,12 +1008,16 @@ Data_b.iFcode = Data_i.bFcode = frame->bcode = b_reference->fcode; for (j = 0; j < pParam->mb_height; j++) { + int new_bound = mb_width * ((((j*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices); f_predMV = b_predMV = zeroMV; /* prediction is reset at left boundary */ for (i = 0; i < pParam->mb_width; i++) { MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; + int force_direct = (((j*mb_width+i)==new_bound) && (j > 0)) ? 1 : 0; /* MTK decoder chipsets do NOT reset predMVs upon resync marker in BVOPs. We workaround this problem + by placing the slice border on second MB in a row and then force the first MB to be direct mode */ + pMB->mode = -1; initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i, @@ -1081,9 +1093,9 @@ if (frame->vop_flags & XVID_VOP_RD_BVOP) ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i, - pMB, b_mb, &f_predMV, &b_predMV, frame->motion_flags, frame->vop_flags, pParam, i, j, best_sad); + pMB, b_mb, &f_predMV, &b_predMV, frame->motion_flags, frame->vop_flags, pParam, i, j, best_sad, force_direct); else - ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV); + ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV, force_direct); maxMotionBVOP(&MVmaxF, &MVmaxB, pMB, Data_d.qpel); @@ -1097,27 +1109,33 @@ void -SMPMotionEstimationBVOP(SMPmotionData * h) +SMPMotionEstimationBVOP(SMPData * h) { - const MBParam * const pParam = h->pParam; + Encoder *pEnc = (Encoder *) h->pEnc; + + const MBParam * const pParam = &pEnc->mbParam; const FRAMEINFO * const frame = h->current; - const int32_t time_bp = h->time_bp; - const int32_t time_pp = h->time_pp; + const int32_t time_bp = (int32_t)(pEnc->current->stamp - frame->stamp); + const int32_t time_pp = (int32_t)(pEnc->current->stamp - pEnc->reference->stamp); /* forward (past) reference */ - const MACROBLOCK * const f_mbs = h->f_mbs; - const IMAGE * const f_ref = h->fRef; - const IMAGE * const f_refH = h->fRefH; - const IMAGE * const f_refV = h->fRefV; - const IMAGE * const f_refHV = h->fRefHV; + const IMAGE * const f_ref = &pEnc->reference->image; + const IMAGE * const f_refH = &pEnc->f_refh; + const IMAGE * const f_refV = &pEnc->f_refv; + const IMAGE * const f_refHV = &pEnc->f_refhv; /* backward (future) reference */ - const FRAMEINFO * const b_reference = h->reference; - const IMAGE * const b_ref = h->pRef; - const IMAGE * const b_refH = h->pRefH; - const IMAGE * const b_refV = h->pRefV; - const IMAGE * const b_refHV = h->pRefHV; - + const FRAMEINFO * const b_reference = pEnc->current; + const IMAGE * const b_ref = &pEnc->current->image; + const IMAGE * const b_refH = &pEnc->vInterH; + const IMAGE * const b_refV = &pEnc->vInterV; + const IMAGE * const b_refHV = &pEnc->vInterHV; + + int mb_width = pParam->mb_width; + int mb_height = pParam->mb_height; + int num_slices = pEnc->num_slices; + int y_row = h->y_row; int y_step = h->y_step; int start_y = h->start_y; + int stop_y = h->stop_y; int * complete_count_self = h->complete_count_self; const int * complete_count_above = h->complete_count_above; int max_mbs; @@ -1161,14 +1179,18 @@ max_mbs = 0; - for (j = start_y; j < pParam->mb_height; j += y_step) { - if (j == 0) max_mbs = pParam->mb_width; /* we can process all blocks of the first row */ + for (j = (start_y+y_row); j < stop_y; j += y_step) { + int new_bound = mb_width * ((((j*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices); + + if (j == start_y) max_mbs = pParam->mb_width; /* we can process all blocks of the first row */ f_predMV = b_predMV = zeroMV; /* prediction is reset at left boundary */ - for (i = 0; i < pParam->mb_width; i++) { + for (i = 0; i < (int) pParam->mb_width; i++) { MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; + int force_direct = (((j*mb_width+i)==new_bound) && (j > 0)) ? 1 : 0; /* MTK decoder chipsets do NOT reset predMVs upon resync marker in BVOPs. We workaround this problem + by placing the slice border on second MB in a row and then force the first MB to be direct mode */ pMB->mode = -1; initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i, @@ -1182,7 +1204,7 @@ if (above_count == pParam->mb_width) { /* full line above is ready */ above_count = pParam->mb_width+1; - if (j < pParam->mb_height-y_step) { + if (j < stop_y-y_step) { /* this is not last line, grab a portion of MBs from the next line too */ above_count += MAX(0, complete_count_above[1] - 1); } @@ -1272,9 +1294,9 @@ if (frame->vop_flags & XVID_VOP_RD_BVOP) ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i, - pMB, b_mb, &f_predMV, &b_predMV, frame->motion_flags, frame->vop_flags, pParam, i, j, best_sad); + pMB, b_mb, &f_predMV, &b_predMV, frame->motion_flags, frame->vop_flags, pParam, i, j, best_sad, force_direct); else - ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV); + ModeDecision_BVOP_SAD(&Data_d, &Data_b, &Data_f, &Data_i, pMB, b_mb, &f_predMV, &b_predMV, force_direct); *complete_count_self = i+1; current_mb++;