📄 inter.c
字号:
{
t->mb.mb_part = part;
}
t->mb.mb_mode = best_mode;
t->mb.sad = sad_min;
return t->mb.sad;
}
/*
0 median
1 left
2 top
3 topright
4 topleft
5 0, 0
6 last frame
*/
void
get_pmv(T264_t* t, int32_t list, T264_vector_t* vec, int32_t part, int32_t idx, int32_t width, int32_t* n)
{
int32_t count = 0;
int32_t row;
int32_t col;
T264_predict_mv(t, list, idx, width, vec);
col = idx % 4;
row = idx / 4;
vec[1].x = t->mb.vec_ref[VEC_LUMA - 1 + row * 8 + col].vec[list].x;
vec[1].y = t->mb.vec_ref[VEC_LUMA - 1 + row * 8 + col].vec[list].y;
vec[1].refno = vec[0].refno;
vec[2].x = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col].vec[list].x;
vec[2].y = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col].vec[list].y;
vec[2].refno = vec[0].refno;
vec[3].x = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col + width].vec[list].x;
vec[3].y = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col + width].vec[list].y;
vec[3].refno = vec[0].refno;
vec[4].x = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec[list].x;
vec[4].y = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec[list].y;
vec[4].refno = vec[0].refno;
vec[5 + 0].x = 0;
vec[5 + 0].y = 0;
vec[5 + 0].refno = 0;
*n = 5 + 1;
}
uint32_t
T264_mode_decision_inter_16x16p(_RW T264_t* t, search_data_t* s)
{
DECLARE_ALIGNED_MATRIX(pred_16x16, 16, 16, uint8_t, 16);
T264_vector_t vec[5 + 10]; // NOTE: max 10 refs
T264_search_context_t context;
T264_vector_t vec_skip;
int32_t num;
int32_t i;
uint32_t sad;
uint8_t* p_min = t->mb.pred_p16x16;
uint8_t* p_buf = pred_16x16;
vec[0].refno = 0;
get_pmv(t, 0, vec, MB_16x16, 0, 4, &num);
context.height = 16;
context.width = 16;
context.limit_x= t->param.search_x;
context.limit_y= t->param.search_y;
context.vec = vec;
context.vec_num= num;
context.mb_part= MB_16x16;
context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
context.list_index = s->list_index;
s->src[0] = t->mb.src_y;
s->sad[0] = t->search(t, &context);
s->vec[0] = context.vec_best;
s->ref[0] = t->ref[context.list_index][s->vec[0].refno];
s->offset[0] = context.offset;
s->vec_median[0] = vec[0];
s->sad[0] = T264_quarter_pixel_search(t, 0, s->src[0], s->ref[0], s->offset[0], &s->vec[0], &s->vec_median[0], s->sad[0], 16, 16, p_min, MB_16x16);
for(i = 1 ; i < t->refl0_num ; i ++)
{
vec[0].refno = i;
get_pmv(t, 0, vec, MB_16x16, 0, 4, &num);
context.vec_num = 1;
sad = t->search(t, &context);
sad+= REFCOST(context.vec_best.refno);
sad = T264_quarter_pixel_search(t, 0, s->src[0], t->ref[0][i],
s->offset[0], &context.vec_best, &vec[0], sad, 16, 16, p_buf, MB_16x16);
if (sad < s->sad[0])
{
SWAP(uint8_t, p_buf, p_min);
s->sad[0] = sad;
s->vec[0] = context.vec_best;
s->ref[0] = t->ref[0][i];
s->vec_median[0] = vec[0];
}
}
// xxx
#ifndef USE_PREV_DETECT
T264_predict_mv_skip(t, 0, &vec_skip);
sad = T264_get_pos_sad(t, p_buf, &vec_skip);
sad += t->mb.lambda * (eg_size_se(t->bs, (t->mb.vec[0][0].x - vec[0].x)) +
eg_size_se(t->bs, (t->mb.vec[0][0].y - vec[0].y)));
#else
sad = -1;
#endif
if (sad < s->sad[0] + (uint32_t)8 * t->mb.lambda)
{
s->sad[0] = sad;
SWAP(uint8_t, p_buf, p_min);
copy_nvec(&vec_skip, &t->mb.vec[0][0], 4, 4, 4);
}
else
{
copy_nvec(&s->vec[0], &t->mb.vec[0][0], 4, 4, 4);
}
if (p_min != t->mb.pred_p16x16)
{
memcpy(t->mb.pred_p16x16, p_min, sizeof(uint8_t) * 16 * 16);
}
return s->sad[0];
}
uint32_t
T264_mode_decision_inter_16x8p(_RW T264_t* t, search_data_t* s)
{
T264_vector_t vec[5 + 10]; // NOTE: max 10 refs
T264_search_context_t context;
int32_t num;
uint8_t old_part = t->mb.mb_part;
t->mb.mb_part = MB_16x8;
vec[0].refno = s->vec[0].refno;
get_pmv(t, 0, vec, MB_16x8, 0, 4, &num);
vec[num ++] = s->vec[0];
context.height = 8;
context.width = 16;
context.limit_x= t->param.search_x;
context.limit_y= t->param.search_y;
context.vec = vec;
context.vec_num= num;
context.mb_part= MB_16x8;
context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
context.list_index = s->list_index;
s->src[1] = t->mb.src_y;
s->sad[1] = t->search(t, &context);
s->sad[1]+= REFCOST(context.vec_best.refno);
s->vec[1] = context.vec_best;
s->ref[1] = t->ref[context.list_index][s->vec[1].refno];
s->offset[1] = context.offset;
s->vec_median[1] = vec[0];
t->mb.vec_ref[VEC_LUMA + 8].vec[0] = s->vec[1];
get_pmv(t, 0, vec, MB_16x8, luma_index[8], 4, &num);
vec[num ++] = s->vec[0];
s->src[2] = t->mb.src_y + 8 * t->stride;
context.offset += 8 * t->edged_stride;
s->sad[2] = t->search(t, &context);
s->sad[2]+= REFCOST(context.vec_best.refno);
s->vec[2] = context.vec_best;
s->ref[2] = t->ref[context.list_index][s->vec[2].refno];
s->offset[2] = context.offset;
s->vec_median[2] = vec[0];
t->mb.mb_part = old_part;
return s->sad[1] + s->sad[2];
}
uint32_t
T264_mode_decision_inter_8x16p(_RW T264_t * t, search_data_t* s)
{
T264_vector_t vec[5 + 10]; // NOTE: max 10 refs
T264_search_context_t context;
int32_t num;
uint8_t old_part = t->mb.mb_part;
t->mb.mb_part = MB_8x16;
vec[0].refno = s->vec[0].refno;
get_pmv(t, 0, vec, MB_8x16, 0, 2, &num);
vec[num ++] = s->vec[0];
context.height = 16;
context.width = 8;
context.limit_x= t->param.search_x;
context.limit_y= t->param.search_y;
context.vec = vec;
context.vec_num= num;
context.mb_part= MB_8x16;
context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
context.list_index = s->list_index;
s->src[3] = t->mb.src_y;
s->sad[3] = t->search(t, &context);
s->sad[3]+= REFCOST(context.vec_best.refno);
s->vec[3] = context.vec_best;
s->ref[3] = t->ref[context.list_index][s->vec[3].refno];
s->offset[3] = context.offset;
s->vec_median[3] = vec[0];
t->mb.vec_ref[VEC_LUMA + 1].vec[0] = s->vec[3];
get_pmv(t, 0, vec, MB_8x16, luma_index[4], 2, &num);
vec[num ++] = s->vec[0];
s->src[4] = t->mb.src_y + 8;
context.offset += 8;
s->sad[4] = t->search(t, &context);
s->sad[4]+= REFCOST(context.vec_best.refno);
s->vec[4] = context.vec_best;
s->ref[4] = t->ref[context.list_index][s->vec[4].refno];
s->offset[4] = context.offset;
s->vec_median[4] = vec[0];
t->mb.mb_part = old_part;
return s->sad[3] + s->sad[4];
}
uint32_t
T264_mode_decision_inter_8x8p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
{
T264_vector_t vec[5 + 10]; // NOTE: max 10 refs
T264_search_context_t context;
int32_t num;
vec[0].refno = s->vec[0][0].refno;
get_pmv(t, 0, vec, MB_8x8, luma_index[4 * i], 2, &num);
context.height = 8;
context.width = 8;
context.limit_x= t->param.search_x;
context.limit_y= t->param.search_y;
context.vec = vec;
context.vec_num= num;
context.mb_part= MB_8x8;
context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
context.list_index = s->list_index;
s->src[i][0] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
s->sad[i][0] = t->search(t, &context);
s->sad[i][0]+= REFCOST(context.vec_best.refno);
s->vec[i][0] = context.vec_best;
s->offset[i][0] = context.offset;
s->ref[i][0] = t->ref[context.list_index][s->vec[i][0].refno];
s->vec_median[i][0] = vec[0];
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = s->vec[i][0];
return s->sad[i][0] + eg_size_ue(t->bs, MB_8x8);
}
uint32_t
T264_mode_decision_inter_8x4p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
{
T264_vector_t vec[5 + 10]; // NOTE: max 10 refs
T264_search_context_t context;
int32_t num;
vec[0].refno = s->vec[0][0].refno;
get_pmv(t, 0, vec, MB_8x4, luma_index[4 * i + 0], 2, &num);
context.height = 4;
context.width = 8;
context.limit_x= t->param.search_x;
context.limit_y= t->param.search_y;
context.vec = vec;
/* because get_pmv maybe return some ref does not equal, and the sub 8x8 ref framenum must be the same, so candidate we use only median vector */
context.vec_num= 1;
context.mb_part= MB_8x4;
context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
context.list_index = s->list_index;
s->src[i][1] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
s->sad[i][1] = t->search(t, &context);
s->sad[i][1]+= REFCOST(context.vec_best.refno);
s->vec[i][1] = context.vec_best;
s->offset[i][1] = context.offset;
s->ref[i][1] = t->ref[context.list_index][s->vec[i][1].refno];
s->vec_median[i][1] = vec[0];
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] = s->vec[i][1];
get_pmv(t, 0, vec, MB_8x4, luma_index[4 * i + 2], 2, &num);
s->src[i][2] = s->src[i][1] + 4 * t->stride;
context.offset += 4 * t->edged_stride;
s->sad[i][2] = t->search(t, &context);
s->sad[i][2]+= REFCOST(context.vec_best.refno);
s->vec[i][2] = context.vec_best;
s->offset[i][2] = context.offset;
s->ref[i][2] = t->ref[context.list_index][s->vec[i][2].refno];
s->vec_median[i][2] = vec[0];
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = s->vec[i][2];
return s->sad[i][1] + s->sad[i][2] + eg_size_ue(t->bs, MB_8x4);
}
uint32_t
T264_mode_decision_inter_4x8p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
{
T264_vector_t vec[5 + 10]; // NOTE: max 10 refs
T264_search_context_t context;
int32_t num;
vec[0].refno = s->vec[0][0].refno;
get_pmv(t, 0, vec, MB_4x8, luma_index[4 * i + 0], 1, &num);
context.height = 8;
context.width = 4;
context.limit_x= t->param.search_x;
context.limit_y= t->param.search_y;
context.vec = vec;
/* see 4x8 note */
context.vec_num= 1; /* num; */
context.mb_part= MB_4x8;
context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
context.list_index = s->list_index;
s->src[i][3] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
s->sad[i][3] = t->search(t, &context);
s->sad[i][3]+= REFCOST(context.vec_best.refno);
s->vec[i][3] = context.vec_best;
s->offset[i][3] = context.offset;
s->ref[i][3] = t->ref[context.list_index][s->vec[i][3].refno];
s->vec_median[i][3] = vec[0];
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] = s->vec[i][3];
get_pmv(t, 0, vec, MB_4x8, luma_index[4 * i + 1], 1, &num);
s->src[i][4] = s->src[i][3] + 4;
context.offset += 4;
s->sad[i][4] = t->search(t, &context);
s->sad[i][4]+= REFCOST(context.vec_best.refno);
s->vec[i][4] = context.vec_best;
s->offset[i][4] = context.offset;
s->ref[i][4] = t->ref[context.list_index][s->vec[i][4].refno];
s->vec_median[i][4] = vec[0];
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = s->vec[i][4];
return s->sad[i][3] + s->sad[i][4] + eg_size_ue(t->bs, MB_4x8);
}
uint32_t
T264_mode_decision_inter_4x4p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
{
T264_vector_t vec[5 + 10]; // NOTE: max 10 refs
T264_search_context_t context;
int32_t num;
vec[0].refno = s->vec[0][0].refno;
get_pmv(t, 0, vec, MB_4x4, luma_index[4 * i + 0], 1, &num);
context.height = 4;
context.width = 4;
context.limit_x= t->param.search_x;
context.limit_y= t->param.search_y;
context.vec = vec;
/* see 4x8 note */
context.vec_num= 1; /* num; */
context.mb_part= MB_4x4;
context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
context.list_index = s->list_index;
s->src[i][5] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
s->sad[i][5] = t->search(t, &context);
s->sad[i][5]+= REFCOST(context.vec_best.refno);
s->vec[i][5] = context.vec_best;
s->offset[i][5] = context.offset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -