Merge branch 'intra-split'

This commit is contained in:
Ari Koivula 2014-05-19 16:07:09 +03:00
commit 3d460c6f31
4 changed files with 91 additions and 57 deletions

View file

@ -392,6 +392,7 @@ void filter_deblock_cu(encoder_state * const encoder_state, int32_t x, int32_t y
const picture * const cur_pic = encoder_state->tile->cur_pic;
cu_info *cur_cu = &cur_pic->cu_array[x + y*(cur_pic->width_in_lcu << MAX_DEPTH)];
uint8_t split_flag = (cur_cu->depth > depth) ? 1 : 0;
uint8_t tr_split = (cur_cu->tr_depth > depth) ? 1 : 0;
uint8_t border_x = (cur_pic->width < x*(LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> depth)) ? 1 : 0;
uint8_t border_y = (cur_pic->height < y*(LCU_WIDTH >> MAX_DEPTH) + (LCU_WIDTH >> depth)) ? 1 : 0;
uint8_t border_split_x = (cur_pic->width < ((x + 1) * (LCU_WIDTH >> MAX_DEPTH)) + (LCU_WIDTH >> (depth + 1))) ? 0 : 1;
@ -400,10 +401,10 @@ void filter_deblock_cu(encoder_state * const encoder_state, int32_t x, int32_t y
uint8_t border = border_x | border_y; // are we in any border CU?
// split 64x64, on split flag and on border
if (depth == 0 || split_flag || border) {
if (depth < MAX_DEPTH && (depth == 0 || split_flag || border || tr_split)) {
// Split the four sub-blocks of this block recursively.
uint8_t change;
assert(depth >= 0 && depth < MAX_DEPTH); // for clang-analyzer
assert(depth >= 0); // for clang-analyzer
change = 1 << (MAX_DEPTH - 1 - depth);
filter_deblock_cu(encoder_state, x, y, depth + 1, edge);

View file

@ -833,63 +833,92 @@ void intra_get_planar_pred(pixel* src, int32_t srcstride, uint32_t width, pixel*
}
}
void intra_recon_lcu(encoder_state * const encoder_state, int x, int y, int depth, lcu_t *lcu, uint32_t pic_width, uint32_t pic_height)
void intra_recon_lcu(encoder_state * const encoder_state, int x, int y, int depth, lcu_t *lcu)
{
const encoder_control * const encoder = encoder_state->encoder_control;
int x_local = (x&0x3f), y_local = (y&0x3f);
cu_info *cur_cu = &lcu->cu[LCU_CU_OFFSET + (x_local>>3) + (y_local>>3)*LCU_T_CU_WIDTH];
const vector2d lcu_px = { x & 0x3f, y & 0x3f };
cu_info *cur_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x>>3) + (lcu_px.y>>3)*LCU_T_CU_WIDTH];
const int8_t width = LCU_WIDTH >> depth;
const int8_t width_c = (depth == MAX_PU_DEPTH ? width : width / 2);
const int pu_index = PU_INDEX(x >> 2, y >> 2);
// Pointers to reconstruction arrays
pixel *recbase_y = &lcu->rec.y[x_local + y_local * LCU_WIDTH];
pixel *recbase_u = &lcu->rec.u[x_local/2 + (y_local * LCU_WIDTH)/4];
pixel *recbase_v = &lcu->rec.v[x_local/2 + (y_local * LCU_WIDTH)/4];
int32_t rec_stride = LCU_WIDTH;
if (depth == 0 || cur_cu->tr_depth > depth) {
int offset = width / 2;
int8_t width = LCU_WIDTH >> depth;
int8_t width_c = (depth == MAX_PU_DEPTH ? width : width / 2);
intra_recon_lcu(encoder_state, x, y, depth+1, lcu);
intra_recon_lcu(encoder_state, x + offset, y, depth+1, lcu);
intra_recon_lcu(encoder_state, x, y + offset, depth+1, lcu);
intra_recon_lcu(encoder_state, x + offset, y + offset, depth+1, lcu);
pixel rec[(LCU_WIDTH*2+8)*(LCU_WIDTH*2+8)];
pixel *rec_shift = &rec[width * 2 + 8 + 1];
if (depth < MAX_DEPTH) {
cu_info *cu_a = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset)>>3) + (lcu_px.y>>3) *LCU_T_CU_WIDTH];
cu_info *cu_b = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x>>3) + ((lcu_px.y+offset)>>3)*LCU_T_CU_WIDTH];
cu_info *cu_c = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset)>>3) + ((lcu_px.y+offset)>>3)*LCU_T_CU_WIDTH];
if (cbf_is_set(cu_a->cbf.y, depth+1) || cbf_is_set(cu_b->cbf.y, depth+1) || cbf_is_set(cu_c->cbf.y, depth+1)) {
cbf_set(&cur_cu->cbf.y, depth);
}
if (cbf_is_set(cu_a->cbf.u, depth+1) || cbf_is_set(cu_b->cbf.u, depth+1) || cbf_is_set(cu_c->cbf.u, depth+1)) {
cbf_set(&cur_cu->cbf.u, depth);
}
if (cbf_is_set(cu_a->cbf.v, depth+1) || cbf_is_set(cu_b->cbf.v, depth+1) || cbf_is_set(cu_c->cbf.v, depth+1)) {
cbf_set(&cur_cu->cbf.v, depth);
}
}
int i = PU_INDEX(x >> 2, y >> 2);
// Reconstruct chroma.
if (!(x & 4 || y & 4)) {
pixel *rec_shift_c = &rec[width_c * 2 + 8 + 1];
intra_build_reference_border(encoder, x, y,(int16_t)width_c * 2 + 8, rec, (int16_t)width_c * 2 + 8, 1,
pic_width/2, pic_height/2, lcu);
intra_recon(encoder,
rec_shift_c,
width_c * 2 + 8,
width_c,
recbase_u,
rec_stride >> 1,
cur_cu->intra[0].mode_chroma,
1);
intra_build_reference_border(encoder, x, y,(int16_t)width_c * 2 + 8, rec, (int16_t)width_c * 2 + 8, 2,
pic_width/2, pic_height/2, lcu);
intra_recon(encoder,
rec_shift_c,
width_c * 2 + 8,
width_c,
recbase_v,
rec_stride >> 1,
cur_cu->intra[0].mode_chroma,
2);
return;
}
{
const uint32_t pic_width = encoder_state->tile->cur_pic->width;
const uint32_t pic_height = encoder_state->tile->cur_pic->height;
intra_build_reference_border(encoder, x, y,(int16_t)width * 2 + 8, rec, (int16_t)width * 2 + 8, 0,
pic_width, pic_height, lcu);
intra_recon(encoder, rec_shift, width * 2 + 8,
width, recbase_y, rec_stride, cur_cu->intra[i].mode, 0);
// Pointers to reconstruction arrays
pixel *recbase_y = &lcu->rec.y[lcu_px.x + lcu_px.y * LCU_WIDTH];
pixel *recbase_u = &lcu->rec.u[lcu_px.x/2 + (lcu_px.y * LCU_WIDTH)/4];
pixel *recbase_v = &lcu->rec.v[lcu_px.x/2 + (lcu_px.y * LCU_WIDTH)/4];
// Filter DC-prediction
if (cur_cu->intra[i].mode == 1 && width < 32) {
intra_dc_pred_filtering(rec_shift, width * 2 + 8, recbase_y,
rec_stride, width, width);
pixel rec[(LCU_WIDTH*2+8)*(LCU_WIDTH*2+8)];
pixel *rec_shift = &rec[width * 2 + 8 + 1];
int32_t rec_stride = LCU_WIDTH;
// Reconstruct chroma.
if (!(x & 4 || y & 4)) {
pixel *rec_shift_c = &rec[width_c * 2 + 8 + 1];
intra_build_reference_border(encoder, x, y,(int16_t)width_c * 2 + 8, rec, (int16_t)width_c * 2 + 8, 1,
pic_width/2, pic_height/2, lcu);
intra_recon(encoder,
rec_shift_c,
width_c * 2 + 8,
width_c,
recbase_u,
rec_stride >> 1,
cur_cu->intra[0].mode_chroma,
1);
intra_build_reference_border(encoder, x, y,(int16_t)width_c * 2 + 8, rec, (int16_t)width_c * 2 + 8, 2,
pic_width/2, pic_height/2, lcu);
intra_recon(encoder,
rec_shift_c,
width_c * 2 + 8,
width_c,
recbase_v,
rec_stride >> 1,
cur_cu->intra[0].mode_chroma,
2);
}
intra_build_reference_border(encoder, x, y,(int16_t)width * 2 + 8, rec, (int16_t)width * 2 + 8, 0,
pic_width, pic_height, lcu);
intra_recon(encoder, rec_shift, width * 2 + 8,
width, recbase_y, rec_stride, cur_cu->intra[pu_index].mode, 0);
// Filter DC-prediction
if (cur_cu->intra[pu_index].mode == 1 && width < 32) {
intra_dc_pred_filtering(rec_shift, width * 2 + 8, recbase_y,
rec_stride, width, width);
}
quantize_lcu_luma_residual(encoder_state, x, y, depth, lcu);
quantize_lcu_chroma_residual(encoder_state, x, y, depth, lcu);
}
quantize_lcu_luma_residual(encoder_state, x, y, depth, lcu);
quantize_lcu_chroma_residual(encoder_state, x, y, depth, lcu);
}

View file

@ -49,6 +49,6 @@ void intra_get_angular_pred(const encoder_control *encoder, pixel* src, int32_t
void intra_recon(const encoder_control *encoder, pixel* rec, int32_t rec_stride, uint32_t width, pixel* dst, int32_t dst_stride, int8_t mode, int8_t chroma);
void intra_recon_lcu(encoder_state *encoder_state, int x, int y, int depth, lcu_t *lcu, uint32_t pic_width, uint32_t pic_height);
void intra_recon_lcu(encoder_state *encoder_state, int x, int y, int depth, lcu_t *lcu);
#endif

View file

@ -576,7 +576,7 @@ static void work_tree_copy_down(int x_px, int y_px, int depth, lcu_t work_tree[M
}
static void lcu_set_intra_mode(lcu_t *lcu, int x_px, int y_px, int depth, int pred_mode, int part_mode)
static void lcu_set_intra_mode(lcu_t *lcu, int x_px, int y_px, int depth, int tr_depth, int pred_mode, int chroma_mode, int part_mode)
{
const int width_cu = LCU_CU_WIDTH >> depth;
const int x_cu = SUB_SCU(x_px) >> MAX_DEPTH;
@ -591,7 +591,7 @@ static void lcu_set_intra_mode(lcu_t *lcu, int x_px, int y_px, int depth, int pr
cu->type = CU_INTRA;
// It is assumed that cu->intra[].mode's are already set.
cu->part_size = part_mode;
cu->tr_depth = depth;
cu->tr_depth = tr_depth;
return;
}
@ -605,8 +605,9 @@ static void lcu_set_intra_mode(lcu_t *lcu, int x_px, int y_px, int depth, int pr
cu->intra[1].mode = pred_mode;
cu->intra[2].mode = pred_mode;
cu->intra[3].mode = pred_mode;
cu->intra[0].mode_chroma = chroma_mode;
cu->part_size = part_mode;
cu->tr_depth = depth;
cu->tr_depth = tr_depth;
cu->coded = 1;
}
}
@ -889,8 +890,11 @@ static int search_cu(encoder_state * const encoder_state, int x, int y, int dept
// Reconstruct best mode because we need the reconstructed pixels for
// mode search of adjacent CUs.
if (cur_cu->type == CU_INTRA) {
lcu_set_intra_mode(&work_tree[depth], x, y, depth, cur_cu->intra[PU_INDEX(x >> 2, y >> 2)].mode, cur_cu->part_size);
intra_recon_lcu(encoder_state, x, y, depth,&work_tree[depth], cur_pic->width, cur_pic->height);
lcu_set_intra_mode(&work_tree[depth], x, y, depth, cur_cu->tr_depth,
cur_cu->intra[PU_INDEX(x >> 2, y >> 2)].mode,
cur_cu->intra[0].mode_chroma,
cur_cu->part_size);
intra_recon_lcu(encoder_state, x, y, depth, &work_tree[depth]);
} else if (cur_cu->type == CU_INTER) {
int cbf;
inter_recon_lcu(encoder_state, encoder_state->global->ref->pics[cur_cu->inter.mv_ref], x, y, LCU_WIDTH>>depth, cur_cu->inter.mv, &work_tree[depth]);