21 |
* along with this program ; if not, write to the Free Software |
* along with this program ; if not, write to the Free Software |
22 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 |
* |
* |
24 |
* $Id: estimation_bvop.c,v 1.27 2010-12-18 16:02:00 Isibaar Exp $ |
* $Id: estimation_bvop.c,v 1.28 2010-12-24 13:21:35 Isibaar Exp $ |
25 |
* |
* |
26 |
****************************************************************************/ |
****************************************************************************/ |
27 |
|
|
800 |
MACROBLOCK * const pMB, |
MACROBLOCK * const pMB, |
801 |
const MACROBLOCK * const b_mb, |
const MACROBLOCK * const b_mb, |
802 |
VECTOR * f_predMV, |
VECTOR * f_predMV, |
803 |
VECTOR * b_predMV) |
VECTOR * b_predMV, |
804 |
|
int force_direct) |
805 |
{ |
{ |
806 |
int mode = MODE_DIRECT, k; |
int mode = MODE_DIRECT, k; |
807 |
int best_sad, f_sad, b_sad, i_sad; |
int best_sad, f_sad, b_sad, i_sad; |
813 |
f_sad = Data_f->iMinSAD[0] + 4*Data_d->lambda16; |
f_sad = Data_f->iMinSAD[0] + 4*Data_d->lambda16; |
814 |
i_sad = Data_i->iMinSAD[0] + 2*Data_d->lambda16; |
i_sad = Data_i->iMinSAD[0] + 2*Data_d->lambda16; |
815 |
|
|
816 |
|
if (force_direct) |
817 |
|
goto set_mode; /* bypass checks for non-direct modes */ |
818 |
|
|
819 |
if (b_sad < best_sad) { |
if (b_sad < best_sad) { |
820 |
mode = MODE_BACKWARD; |
mode = MODE_BACKWARD; |
821 |
best_sad = b_sad; |
best_sad = b_sad; |
831 |
best_sad = i_sad; |
best_sad = i_sad; |
832 |
} |
} |
833 |
|
|
834 |
|
set_mode: |
835 |
pMB->sad16 = best_sad; |
pMB->sad16 = best_sad; |
836 |
pMB->mode = mode; |
pMB->mode = mode; |
837 |
pMB->cbp = 63; |
pMB->cbp = 63; |
966 |
const IMAGE * const b_ref, |
const IMAGE * const b_ref, |
967 |
const IMAGE * const b_refH, |
const IMAGE * const b_refH, |
968 |
const IMAGE * const b_refV, |
const IMAGE * const b_refV, |
969 |
const IMAGE * const b_refHV) |
const IMAGE * const b_refHV, |
970 |
|
const int num_slices) |
971 |
{ |
{ |
972 |
uint32_t i, j; |
uint32_t i, j; |
973 |
int32_t best_sad = 256*4096; |
int32_t best_sad = 256*4096; |
977 |
|
|
978 |
VECTOR f_predMV, b_predMV; |
VECTOR f_predMV, b_predMV; |
979 |
|
|
980 |
|
int mb_width = pParam->mb_width; |
981 |
|
int mb_height = pParam->mb_height; |
982 |
int MVmaxF = 0, MVmaxB = 0; |
int MVmaxF = 0, MVmaxB = 0; |
983 |
const int32_t TRB = time_pp - time_bp; |
const int32_t TRB = time_pp - time_bp; |
984 |
const int32_t TRD = time_pp; |
const int32_t TRD = time_pp; |
1008 |
Data_b.iFcode = Data_i.bFcode = frame->bcode = b_reference->fcode; |
Data_b.iFcode = Data_i.bFcode = frame->bcode = b_reference->fcode; |
1009 |
|
|
1010 |
for (j = 0; j < pParam->mb_height; j++) { |
for (j = 0; j < pParam->mb_height; j++) { |
1011 |
|
int new_bound = mb_width * ((((j*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices); |
1012 |
|
|
1013 |
f_predMV = b_predMV = zeroMV; /* prediction is reset at left boundary */ |
f_predMV = b_predMV = zeroMV; /* prediction is reset at left boundary */ |
1014 |
|
|
1015 |
for (i = 0; i < pParam->mb_width; i++) { |
for (i = 0; i < pParam->mb_width; i++) { |
1016 |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
1017 |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
1018 |
|
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 |
1019 |
|
by placing the slice border on second MB in a row and then force the first MB to be direct mode */ |
1020 |
|
|
1021 |
pMB->mode = -1; |
pMB->mode = -1; |
1022 |
|
|
1023 |
initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i, |
initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i, |
1093 |
|
|
1094 |
if (frame->vop_flags & XVID_VOP_RD_BVOP) |
if (frame->vop_flags & XVID_VOP_RD_BVOP) |
1095 |
ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i, |
ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i, |
1096 |
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); |
1097 |
else |
else |
1098 |
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); |
1099 |
|
|
1100 |
maxMotionBVOP(&MVmaxF, &MVmaxB, pMB, Data_d.qpel); |
maxMotionBVOP(&MVmaxF, &MVmaxB, pMB, Data_d.qpel); |
1101 |
|
|
1129 |
const IMAGE * const b_refV = &pEnc->vInterV; |
const IMAGE * const b_refV = &pEnc->vInterV; |
1130 |
const IMAGE * const b_refHV = &pEnc->vInterHV; |
const IMAGE * const b_refHV = &pEnc->vInterHV; |
1131 |
|
|
1132 |
|
int mb_width = pParam->mb_width; |
1133 |
|
int mb_height = pParam->mb_height; |
1134 |
|
int num_slices = pEnc->num_slices; |
1135 |
int y_row = h->y_row; |
int y_row = h->y_row; |
1136 |
int y_step = h->y_step; |
int y_step = h->y_step; |
1137 |
int start_y = h->start_y; |
int start_y = h->start_y; |
1180 |
max_mbs = 0; |
max_mbs = 0; |
1181 |
|
|
1182 |
for (j = (start_y+y_row); j < stop_y; j += y_step) { |
for (j = (start_y+y_row); j < stop_y; j += y_step) { |
1183 |
|
int new_bound = mb_width * ((((j*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices); |
1184 |
|
|
1185 |
if (j == start_y) max_mbs = pParam->mb_width; /* we can process all blocks of the first row */ |
if (j == start_y) max_mbs = pParam->mb_width; /* we can process all blocks of the first row */ |
1186 |
|
|
1187 |
f_predMV = b_predMV = zeroMV; /* prediction is reset at left boundary */ |
f_predMV = b_predMV = zeroMV; /* prediction is reset at left boundary */ |
1189 |
for (i = 0; i < (int) pParam->mb_width; i++) { |
for (i = 0; i < (int) pParam->mb_width; i++) { |
1190 |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
1191 |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
1192 |
|
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 |
1193 |
|
by placing the slice border on second MB in a row and then force the first MB to be direct mode */ |
1194 |
pMB->mode = -1; |
pMB->mode = -1; |
1195 |
|
|
1196 |
initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i, |
initialize_searchData(&Data_d, &Data_f, &Data_b, &Data_i, |
1294 |
|
|
1295 |
if (frame->vop_flags & XVID_VOP_RD_BVOP) |
if (frame->vop_flags & XVID_VOP_RD_BVOP) |
1296 |
ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i, |
ModeDecision_BVOP_RD(&Data_d, &Data_b, &Data_f, &Data_i, |
1297 |
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); |
1298 |
else |
else |
1299 |
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); |
1300 |
|
|
1301 |
*complete_count_self = i+1; |
*complete_count_self = i+1; |
1302 |
current_mb++; |
current_mb++; |