Bi-pred search cleanup

This commit is contained in:
Marko Viitanen 2015-04-23 14:39:41 +03:00
parent 0e958ebe84
commit 79dc7e7270
2 changed files with 17 additions and 8 deletions

View file

@ -339,16 +339,20 @@ void inter_recon_lcu(const encoder_state_t * const state, const image_t * const
*/ */
void inter_recon_lcu_bipred(const encoder_state_t * const state, const image_t * ref1, const image_t * ref2, int32_t xpos, int32_t ypos, int32_t width, const int16_t mv_param[2][2], lcu_t* lcu) { void inter_recon_lcu_bipred(const encoder_state_t * const state, const image_t * ref1, const image_t * ref2, int32_t xpos, int32_t ypos, int32_t width, const int16_t mv_param[2][2], lcu_t* lcu) {
pixel_t *temp_lcu_y = MALLOC(pixel_t, 64 * 64); pixel_t temp_lcu_y[64 * 64];
pixel_t *temp_lcu_u = MALLOC(pixel_t, 32 * 32); pixel_t temp_lcu_u[32 * 32];
pixel_t *temp_lcu_v = MALLOC(pixel_t, 32 * 32); pixel_t temp_lcu_v[32 * 32];
int temp_x, temp_y; int temp_x, temp_y;
// TODO: interpolated values require 14-bit accuracy for bi-prediction, current implementation of ipol filters round the value to 8bits // TODO: interpolated values require 14-bit accuracy for bi-prediction, current implementation of ipol filters round the value to 8bits
//Reconstruct both predictors
inter_recon_lcu(state, ref1, xpos, ypos, width, mv_param[0], lcu); inter_recon_lcu(state, ref1, xpos, ypos, width, mv_param[0], lcu);
memcpy(temp_lcu_y, lcu->rec.y, sizeof(pixel_t) * 64 * 64); memcpy(temp_lcu_y, lcu->rec.y, sizeof(pixel_t) * 64 * 64);
memcpy(temp_lcu_u, lcu->rec.u, sizeof(pixel_t) * 32 * 32); memcpy(temp_lcu_u, lcu->rec.u, sizeof(pixel_t) * 32 * 32);
memcpy(temp_lcu_v, lcu->rec.v, sizeof(pixel_t) * 32 * 32); memcpy(temp_lcu_v, lcu->rec.v, sizeof(pixel_t) * 32 * 32);
inter_recon_lcu(state, ref2, xpos, ypos, width, mv_param[1], lcu); inter_recon_lcu(state, ref2, xpos, ypos, width, mv_param[1], lcu);
// After reconstruction, merge the predictors by taking an average of each pixel
for (temp_y = 0; temp_y < width; ++temp_y) { for (temp_y = 0; temp_y < width; ++temp_y) {
int y_in_lcu = ((ypos + temp_y) & ((LCU_WIDTH)-1)); int y_in_lcu = ((ypos + temp_y) & ((LCU_WIDTH)-1));
for (temp_x = 0; temp_x < width; ++temp_x) { for (temp_x = 0; temp_x < width; ++temp_x) {
@ -368,11 +372,12 @@ void inter_recon_lcu_bipred(const encoder_state_t * const state, const image_t *
(int)temp_lcu_v[y_in_lcu * LCU_WIDTH_C + x_in_lcu] + 1) >> 1); (int)temp_lcu_v[y_in_lcu * LCU_WIDTH_C + x_in_lcu] + 1) >> 1);
} }
} }
FREE_POINTER(temp_lcu_y);
FREE_POINTER(temp_lcu_u);
FREE_POINTER(temp_lcu_v);
} }
/**
* \brief Set unused L0/L1 motion vectors and reference
* \param cu coding unit to clear
*/
static void inter_clear_cu_unused(cu_info_t* cu) { static void inter_clear_cu_unused(cu_info_t* cu) {
if(!(cu->inter.mv_dir & 1)) { if(!(cu->inter.mv_dir & 1)) {
cu->inter.mv[0][0] = 0; cu->inter.mv[0][0] = 0;

View file

@ -1127,11 +1127,12 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in
// Force L0 and L1 references // Force L0 and L1 references
if (state->global->refmap[merge_cand[i].ref[0]].list == 2 || state->global->refmap[merge_cand[j].ref[1]].list == 1) continue; if (state->global->refmap[merge_cand[i].ref[0]].list == 2 || state->global->refmap[merge_cand[j].ref[1]].list == 1) continue;
// TODO: enable fractional pixel bipred search
mv[0][0] = merge_cand[i].mv[0][0] & 0xfff8; mv[0][0] = merge_cand[i].mv[0][0] & 0xfff8;
mv[0][1] = merge_cand[i].mv[0][1] & 0xfff8; mv[0][1] = merge_cand[i].mv[0][1] & 0xfff8;
mv[1][0] = merge_cand[j].mv[1][0] & 0xfff8; mv[1][0] = merge_cand[j].mv[1][0] & 0xfff8;
mv[1][1] = merge_cand[j].mv[1][1] & 0xfff8; mv[1][1] = merge_cand[j].mv[1][1] & 0xfff8;
memset(templcu->rec.y, 0, 64 * 64);
inter_recon_lcu_bipred(state, state->global->ref->images[merge_cand[i].ref[0]], state->global->ref->images[merge_cand[j].ref[1]], x, y, LCU_WIDTH >> depth, mv, templcu); inter_recon_lcu_bipred(state, state->global->ref->images[merge_cand[i].ref[0]], state->global->ref->images[merge_cand[j].ref[1]], x, y, LCU_WIDTH >> depth, mv, templcu);
for (int ypos = 0; ypos < LCU_WIDTH >> depth; ++ypos) { for (int ypos = 0; ypos < LCU_WIDTH >> depth; ++ypos) {
@ -1144,6 +1145,7 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in
cost = satd(tmp_pic, tmp_block); cost = satd(tmp_pic, tmp_block);
// TODO: enable fractional pixel bipred search
cost += calc_mvd_cost(state, merge_cand[i].mv[0][0] & 0xfff8, merge_cand[i].mv[0][1] & 0xfff8, 0, mv_cand, merge_cand, 0, ref_idx, &bitcost[0]); cost += calc_mvd_cost(state, merge_cand[i].mv[0][0] & 0xfff8, merge_cand[i].mv[0][1] & 0xfff8, 0, mv_cand, merge_cand, 0, ref_idx, &bitcost[0]);
cost += calc_mvd_cost(state, merge_cand[i].mv[1][0] & 0xfff8, merge_cand[i].mv[1][1] & 0xfff8, 0, mv_cand, merge_cand, 0, ref_idx, &bitcost[1]); cost += calc_mvd_cost(state, merge_cand[i].mv[1][0] & 0xfff8, merge_cand[i].mv[1][1] & 0xfff8, 0, mv_cand, merge_cand, 0, ref_idx, &bitcost[1]);
@ -1157,6 +1159,8 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in
cur_cu->inter.mv_ref[0] = merge_cand[i].ref[0]; cur_cu->inter.mv_ref[0] = merge_cand[i].ref[0];
cur_cu->inter.mv_ref[1] = merge_cand[j].ref[1]; cur_cu->inter.mv_ref[1] = merge_cand[j].ref[1];
// TODO: enable fractional pixel bipred search
cur_cu->inter.mv[0][0] = merge_cand[i].mv[0][0] & 0xfff8; cur_cu->inter.mv[0][0] = merge_cand[i].mv[0][0] & 0xfff8;
cur_cu->inter.mv[0][1] = merge_cand[i].mv[0][1] & 0xfff8; cur_cu->inter.mv[0][1] = merge_cand[i].mv[0][1] & 0xfff8;
cur_cu->inter.mv[1][0] = merge_cand[j].mv[1][0] & 0xfff8; cur_cu->inter.mv[1][0] = merge_cand[j].mv[1][0] & 0xfff8;
@ -1178,7 +1182,7 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in
} }
} }
// Each motion vector has its own candidate
for (int reflist = 0; reflist < 2; reflist++) { for (int reflist = 0; reflist < 2; reflist++) {
cu_mv_cand = 0; cu_mv_cand = 0;
inter_get_mv_cand(state, x, y, depth, mv_cand, cur_cu, lcu, reflist); inter_get_mv_cand(state, x, y, depth, mv_cand, cur_cu, lcu, reflist);