Split residual quantization to separate luma and chroma function.

This commit is contained in:
Ari Koivula 2014-05-14 11:19:48 +03:00
parent 6c7e4dbeef
commit 9147b7acbf
4 changed files with 49 additions and 18 deletions

View file

@ -892,5 +892,6 @@ void intra_recon_lcu(encoder_state * const encoder_state, int x, int y, int dept
rec_stride, width, width);
}
encode_transform_tree(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

@ -913,7 +913,8 @@ static int search_cu(encoder_state * const encoder_state, int x, int y, int dept
} 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]);
encode_transform_tree(encoder_state, x, y, depth, &work_tree[depth]);
quantize_lcu_luma_residual(encoder_state, x, y, depth, &work_tree[depth]);
quantize_lcu_chroma_residual(encoder_state, x, y, depth, &work_tree[depth]);
cbf = cbf_is_set(cur_cu->cbf.y, depth) || cbf_is_set(cur_cu->cbf.u, depth) || cbf_is_set(cur_cu->cbf.v, depth);

View file

@ -993,7 +993,7 @@ int quantize_residual_trskip(
* - lcu->cbf coded block flags for the area
* - lcu->cu.intra[].tr_skip for the area
*/
void encode_transform_tree(encoder_state * const encoder_state, int32_t x, int32_t y, const uint8_t depth, lcu_t* lcu)
void quantize_lcu_luma_residual(encoder_state * const encoder_state, int32_t x, int32_t y, const uint8_t depth, lcu_t* lcu)
{
// we have 64>>depth transform size
const vector2d lcu_px = {x & 0x3f, y & 0x3f};
@ -1008,10 +1008,10 @@ void encode_transform_tree(encoder_state * const encoder_state, int32_t x, int32
// Split transform and increase depth
if (depth == 0 || cur_cu->tr_depth > depth) {
int offset = width / 2;
encode_transform_tree(encoder_state, x, y, depth+1, lcu);
encode_transform_tree(encoder_state, x + offset, y, depth+1, lcu);
encode_transform_tree(encoder_state, x, y + offset, depth+1, lcu);
encode_transform_tree(encoder_state, x + offset, y + offset, depth+1, lcu);
quantize_lcu_luma_residual(encoder_state, x, y, depth+1, lcu);
quantize_lcu_luma_residual(encoder_state, x + offset, y, depth+1, lcu);
quantize_lcu_luma_residual(encoder_state, x, y + offset, depth+1, lcu);
quantize_lcu_luma_residual(encoder_state, x + offset, y + offset, depth+1, lcu);
// Propagate coded block flags from child CUs to parent CU.
if (depth < MAX_DEPTH) {
@ -1021,12 +1021,6 @@ void encode_transform_tree(encoder_state * const encoder_state, int32_t x, int32
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);
}
}
return;
@ -1052,10 +1046,6 @@ void encode_transform_tree(encoder_state * const encoder_state, int32_t x, int32
// This should ensure that the CBF data doesn't get corrupted if this function
// is called more than once.
cbf_clear(&cur_cu->cbf.y, depth + pu_index);
if (pu_index == 0) {
cbf_clear(&cur_cu->cbf.u, depth);
cbf_clear(&cur_cu->cbf.v, depth);
}
if (width == 4 && encoder_state->encoder_control->trskip_enable) {
// Try quantization with trskip and use it if it's better.
@ -1080,6 +1070,44 @@ void encode_transform_tree(encoder_state * const encoder_state, int32_t x, int32
}
}
}
}
void quantize_lcu_chroma_residual(encoder_state * const encoder_state, int32_t x, int32_t y, const uint8_t depth, lcu_t* lcu)
{
// we have 64>>depth transform size
const vector2d lcu_px = {x & 0x3f, y & 0x3f};
const int pu_index = PU_INDEX(lcu_px.x / 4, lcu_px.y / 4);
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;
// Tell clang-analyzer what is up. For some reason it can't figure out from
// asserting just depth.
assert(width == 4 || width == 8 || width == 16 || width == 32 || width == 64);
// Split transform and increase depth
if (depth == 0 || cur_cu->tr_depth > depth) {
int offset = width / 2;
quantize_lcu_chroma_residual(encoder_state, x, y, depth+1, lcu);
quantize_lcu_chroma_residual(encoder_state, x + offset, y, depth+1, lcu);
quantize_lcu_chroma_residual(encoder_state, x, y + offset, depth+1, lcu);
quantize_lcu_chroma_residual(encoder_state, x + offset, y + offset, depth+1, lcu);
// Propagate coded block flags from child CUs to parent CU.
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.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);
}
}
return;
}
// If luma is 4x4, do chroma for the 8x8 luma area when handling the top
// left PU because the coordinates are correct.

View file

@ -46,6 +46,7 @@ void itransform2d(const encoder_control *encoder, int16_t *block,int16_t *coeff,
int32_t get_scaled_qp(int8_t type, int8_t qp, int8_t qp_offset);
void encode_transform_tree(encoder_state *encoder_state, int32_t x, int32_t y, uint8_t depth, lcu_t* lcu);
void quantize_lcu_luma_residual(encoder_state *encoder_state, int32_t x, int32_t y, uint8_t depth, lcu_t* lcu);
void quantize_lcu_chroma_residual(encoder_state *encoder_state, int32_t x, int32_t y, uint8_t depth, lcu_t* lcu);
#endif