From 0e6f1c99fc8e60fa04199faa26f34eb07f044709 Mon Sep 17 00:00:00 2001 From: Laurent Fasnacht Date: Wed, 7 May 2014 11:18:10 +0200 Subject: [PATCH] Refactor picture to remove hidden dependency between slice and tiles picture.type -> encoder_state->global->pictype picture.slicetype -> encoder_state->global->slicetype picture.slice_sao_luma_flag -> 1 (was constant) picture.slice_sao_chroma_flag -> 1 (was constant) This may be changed later. For now it's better to avoid having slice related stuff in picture. --- src/encmain.c | 2 +- src/encoder.c | 86 +++++++++++++++++-------------------------------- src/encoder.h | 4 +++ src/picture.c | 2 -- src/picture.h | 4 --- src/search.c | 2 +- src/transform.c | 2 +- 7 files changed, 36 insertions(+), 66 deletions(-) diff --git a/src/encmain.c b/src/encmain.c index 9170fc40..43101584 100644 --- a/src/encmain.c +++ b/src/encmain.c @@ -355,7 +355,7 @@ int main(int argc, char *argv[]) temp_psnr[2] = image_psnr(cur_pic->v_data, cur_pic->v_recdata, cfg->width>>1, cfg->height>>1); fprintf(stderr, "POC %4d (%c-frame) %10d bits PSNR: %2.4f %2.4f %2.4f\n", encoder_state.global->frame, - "BPI"[cur_pic->slicetype%3], diff<<3, + "BPI"[encoder_state.global->slicetype%3], diff<<3, temp_psnr[0], temp_psnr[1], temp_psnr[2]); // Increment total PSNR diff --git a/src/encoder.c b/src/encoder.c index 65bc9e45..bae5d9f7 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -58,7 +58,6 @@ static void encode_sao(encoder_state *encoder, */ void encoder_state_init_lambda(encoder_state * const encoder_state) { - const picture * const cur_pic = encoder_state->tile->cur_pic; double qp = encoder_state->global->QP; double lambda_scale = 1.0; double qp_temp = qp - 12; @@ -67,13 +66,13 @@ void encoder_state_init_lambda(encoder_state * const encoder_state) // Default QP-factor from HM config double qp_factor = 0.4624; - if (cur_pic->slicetype == SLICE_I) { + if (encoder_state->global->slicetype == SLICE_I) { qp_factor=0.57*lambda_scale; } lambda = qp_factor*pow( 2.0, qp_temp/3.0 ); - if (cur_pic->slicetype != SLICE_I ) { + if (encoder_state->global->slicetype != SLICE_I ) { lambda *= 0.95; } @@ -1050,7 +1049,7 @@ static void encoder_state_encode_tile(encoder_state * const encoder_state) { yuv_t *ver_buf = yuv_t_alloc(LCU_WIDTH + 2); cabac_start(&encoder_state->cabac); - init_contexts(encoder_state, encoder_state->global->QP, encoder_state->tile->cur_pic->slicetype); + init_contexts(encoder_state, encoder_state->global->QP, encoder_state->global->slicetype); // Initialize lambda value(s) to use in search encoder_state_init_lambda(encoder_state); @@ -1160,10 +1159,6 @@ static void encoder_state_encode(encoder_state * const main_state) { encoder_state *sub_state = &(main_state->children[i]); if (sub_state->tile != main_state->tile) { - //FIXME: remove this once these are in slice - sub_state->tile->cur_pic->slicetype = main_state->tile->cur_pic->slicetype; - sub_state->tile->cur_pic->type = main_state->tile->cur_pic->type; - encoder_state_blit_pixels(sub_state, sub_state->tile->cur_pic->y_data, main_state, main_state->tile->cur_pic->y_data, 1); encoder_state_blit_pixels(sub_state, sub_state->tile->cur_pic->u_data, main_state, main_state->tile->cur_pic->u_data, 0); encoder_state_blit_pixels(sub_state, sub_state->tile->cur_pic->v_data, main_state, main_state->tile->cur_pic->v_data, 0); @@ -1198,24 +1193,24 @@ static void encoder_state_new_frame(encoder_state * const main_state) { const int is_first_frame = (main_state->global->frame == 0); const int is_i_radl = (encoder->cfg->intra_period == 1 && main_state->global->frame % 2 == 0); const int is_p_radl = (encoder->cfg->intra_period > 1 && (main_state->global->frame % encoder->cfg->intra_period) == 0); - const int is_radl_frame = is_first_frame || is_i_radl || is_p_radl; + main_state->global->is_radl_frame = is_first_frame || is_i_radl || is_p_radl; - if (is_radl_frame) { + if (main_state->global->is_radl_frame) { // Clear the reference list encoder_state_clear_refs(main_state); - main_state->tile->cur_pic->slicetype = SLICE_I; - main_state->tile->cur_pic->type = NAL_IDR_W_RADL; + main_state->global->slicetype = SLICE_I; + main_state->global->pictype = NAL_IDR_W_RADL; } else { - main_state->tile->cur_pic->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : SLICE_P; - main_state->tile->cur_pic->type = NAL_TRAIL_R; + main_state->global->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : SLICE_P; + main_state->global->pictype = NAL_TRAIL_R; } } else { //Clear the bitstream if it's not the main encoder bitstream_clear(&main_state->stream); } - init_contexts(main_state, main_state->global->QP, main_state->tile->cur_pic->slicetype); + init_contexts(main_state, main_state->global->QP, main_state->global->slicetype); for (i = 0; main_state->children[i].encoder_control; ++i) { encoder_state_new_frame(&main_state->children[i]); @@ -1228,25 +1223,10 @@ static void encoder_state_write_bitstream_main(encoder_state * const main_state) const encoder_control * const encoder = main_state->encoder_control; bitstream * const stream = &main_state->stream; - const int is_first_frame = (main_state->global->frame == 0); - const int is_i_radl = (encoder->cfg->intra_period == 1 && main_state->global->frame % 2 == 0); - const int is_p_radl = (encoder->cfg->intra_period > 1 && (main_state->global->frame % encoder->cfg->intra_period) == 0); - const int is_radl_frame = is_first_frame || is_i_radl || is_p_radl; - int i; - /** IDR picture when: period == 0 and frame == 0 - * period == 1 && frame%2 == 0 - * period != 0 && frame%period == 0 - **/ - if (is_radl_frame) { - // Clear the reference list - encoder_state_clear_refs(main_state); - - main_state->tile->cur_pic->slicetype = SLICE_I; - main_state->tile->cur_pic->type = NAL_IDR_W_RADL; - + if (main_state->global->is_radl_frame) { // Access Unit Delimiter (AUD) if (encoder->aud_enable) write_aud(main_state); @@ -1273,10 +1253,6 @@ static void encoder_state_write_bitstream_main(encoder_state * const main_state) bitstream_align(stream); } } else { - // When intra period == 1, all pictures are intra - main_state->tile->cur_pic->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : SLICE_P; - main_state->tile->cur_pic->type = NAL_TRAIL_R; - // Access Unit Delimiter (AUD) if (encoder->aud_enable) write_aud(main_state); @@ -1285,10 +1261,10 @@ static void encoder_state_write_bitstream_main(encoder_state * const main_state) { // Not quite sure if this is correct, but it seems to have worked so far // so I tried to not change it's behavior. - int long_start_code = is_radl_frame || encoder->aud_enable ? 0 : 1; + int long_start_code = main_state->global->is_radl_frame || encoder->aud_enable ? 0 : 1; nal_write(stream, - is_radl_frame ? NAL_IDR_W_RADL : NAL_TRAIL_R, 0, long_start_code); + main_state->global->is_radl_frame ? NAL_IDR_W_RADL : NAL_TRAIL_R, 0, long_start_code); } for (i = 0; main_state->children[i].encoder_control; ++i) { @@ -1344,8 +1320,6 @@ static void encoder_state_write_bitstream_slice(encoder_state * const main_state for (i = 0; main_state->children[i].encoder_control; ++i) { //Append bitstream to main stream bitstream_append(&main_state->stream, &main_state->children[i].stream); - //FIXME: Move this... - bitstream_clear(&main_state->children[i].stream); } } @@ -1494,9 +1468,8 @@ static void add_checksum(encoder_state * const encoder_state) void encode_access_unit_delimiter(encoder_state * const encoder_state) { bitstream * const stream = &encoder_state->stream; - const picture * const cur_pic = encoder_state->tile->cur_pic; - uint8_t pic_type = cur_pic->slicetype == SLICE_I ? 0 - : cur_pic->slicetype == SLICE_P ? 1 + uint8_t pic_type = encoder_state->global->slicetype == SLICE_I ? 0 + : encoder_state->global->slicetype == SLICE_P ? 1 : 2; WRITE_U(stream, pic_type, 3, "pic_type"); } @@ -1998,7 +1971,6 @@ void encode_slice_header(encoder_state * const encoder_state) { const encoder_control * const encoder = encoder_state->encoder_control; bitstream * const stream = &encoder_state->stream; - const picture * const cur_pic = encoder_state->tile->cur_pic; #ifdef _DEBUG printf("=========== Slice ===========\n"); @@ -2006,8 +1978,8 @@ void encode_slice_header(encoder_state * const encoder_state) WRITE_U(stream, 1, 1, "first_slice_segment_in_pic_flag"); - if (cur_pic->type >= NAL_BLA_W_LP - && cur_pic->type <= NAL_RSV_IRAP_VCL23) { + if (encoder_state->global->pictype >= NAL_BLA_W_LP + && encoder_state->global->pictype <= NAL_RSV_IRAP_VCL23) { WRITE_U(stream, 1, 1, "no_output_of_prior_pics_flag"); } @@ -2015,7 +1987,7 @@ void encode_slice_header(encoder_state * const encoder_state) //WRITE_U(stream, 0, 1, "dependent_slice_segment_flag"); - WRITE_UE(stream, cur_pic->slicetype, "slice_type"); + WRITE_UE(stream, encoder_state->global->slicetype, "slice_type"); // if !entropy_slice_flag @@ -2023,8 +1995,8 @@ void encode_slice_header(encoder_state * const encoder_state) //WRITE_U(stream, 1, 1, "pic_output_flag"); //end if //if( IdrPicFlag ) <- nal_unit_type == 5 - if (cur_pic->type != NAL_IDR_W_RADL - && cur_pic->type != NAL_IDR_N_LP) { + if (encoder_state->global->pictype != NAL_IDR_W_RADL + && encoder_state->global->pictype != NAL_IDR_N_LP) { int j; int ref_negative = encoder_state->global->ref->used_size; int ref_positive = 0; @@ -2045,17 +2017,17 @@ void encode_slice_header(encoder_state * const encoder_state) //end if //end if if (encoder->sao_enable) { - WRITE_U(stream, cur_pic->slice_sao_luma_flag, 1, "slice_sao_luma_flag"); - WRITE_U(stream, cur_pic->slice_sao_chroma_flag, 1, "slice_sao_chroma_flag"); + WRITE_U(stream, 1, 1, "slice_sao_luma_flag"); + WRITE_U(stream, 1, 1, "slice_sao_chroma_flag"); } - if (cur_pic->slicetype != SLICE_I) { + if (encoder_state->global->slicetype != SLICE_I) { WRITE_U(stream, 1, 1, "num_ref_idx_active_override_flag"); WRITE_UE(stream, encoder_state->global->ref->used_size-1, "num_ref_idx_l0_active_minus1"); WRITE_UE(stream, 5-MRG_MAX_NUM_CANDS, "five_minus_max_num_merge_cand"); } - if (cur_pic->slicetype == SLICE_B) { + if (encoder_state->global->slicetype == SLICE_B) { WRITE_U(stream, 0, 1, "mvd_l1_zero_flag"); } @@ -2075,12 +2047,12 @@ static void encode_sao_color(encoder_state * const encoder_state, sao_info *sao, color_index color_i) { cabac_data * const cabac = &encoder_state->cabac; - const picture * const cur_pic = encoder_state->tile->cur_pic; sao_eo_cat i; // Skip colors with no SAO. - if (color_i == COLOR_Y && !cur_pic->slice_sao_luma_flag) return; - if (color_i != COLOR_Y && !cur_pic->slice_sao_chroma_flag) return; + //FIXME: for now, we always have SAO for all channels + if (color_i == COLOR_Y && 0) return; + if (color_i != COLOR_Y && 0) return; /// sao_type_idx_luma: TR, cMax = 2, cRiceParam = 0, bins = {0, bypass} /// sao_type_idx_chroma: TR, cMax = 2, cRiceParam = 0, bins = {0, bypass} @@ -2214,7 +2186,7 @@ void encode_coding_tree(encoder_state * const encoder_state, // Encode skip flag - if (cur_pic->slicetype != SLICE_I) { + if (encoder_state->global->slicetype != SLICE_I) { int8_t ctx_skip = 0; // uiCtxSkip = aboveskipped + leftskipped; int ui; int16_t num_cand = MRG_MAX_NUM_CANDS; @@ -2253,7 +2225,7 @@ void encode_coding_tree(encoder_state * const encoder_state, // ENDIF SKIP // Prediction mode - if (cur_pic->slicetype != SLICE_I) { + if (encoder_state->global->slicetype != SLICE_I) { cabac->ctx = &(cabac->ctx_cu_pred_mode_model); CABAC_BIN(cabac, (cur_cu->type == CU_INTRA), "PredMode"); } diff --git a/src/encoder.h b/src/encoder.h index 7c80c5f1..688a7249 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -152,6 +152,10 @@ typedef struct { int8_t ref_list; //int8_t ref_idx_num[2]; + int is_radl_frame; + uint8_t pictype; + uint8_t slicetype; + } encoder_state_config_global; typedef struct { diff --git a/src/picture.c b/src/picture.c index 034bb97d..ee0added 100644 --- a/src/picture.c +++ b/src/picture.c @@ -302,8 +302,6 @@ picture *picture_alloc(const int32_t width, const int32_t height, pic->coeff_y = NULL; pic->coeff_u = NULL; pic->coeff_v = NULL; - pic->slice_sao_luma_flag = 1; - pic->slice_sao_chroma_flag = 1; pic->sao_luma = MALLOC(sao_info, width_in_lcu * height_in_lcu); pic->sao_chroma = MALLOC(sao_info, width_in_lcu * height_in_lcu); diff --git a/src/picture.h b/src/picture.h index 117a69b6..f73859fd 100644 --- a/src/picture.h +++ b/src/picture.h @@ -126,10 +126,6 @@ typedef struct picture_struct uint8_t referenced; //!< \brief Whether this picture is referenced. int32_t refcount; //!< \brief Number of references in reflist to the picture cu_info* cu_array; //!< \brief Info for each CU at each depth. - uint8_t type; - uint8_t slicetype; - uint8_t slice_sao_luma_flag; - uint8_t slice_sao_chroma_flag; struct sao_info_struct *sao_luma; //!< \brief Array of sao parameters for every LCU. struct sao_info_struct *sao_chroma; //!< \brief Array of sao parameters for every LCU. int32_t poc; //!< \brief Picture order count diff --git a/src/search.c b/src/search.c index 99434380..ab7f5202 100644 --- a/src/search.c +++ b/src/search.c @@ -883,7 +883,7 @@ static int search_cu(encoder_state * const encoder_state, int x, int y, int dept y + cu_width <= cur_pic->height) { - if (cur_pic->slicetype != SLICE_I && + if (encoder_state->global->slicetype != SLICE_I && depth >= MIN_INTER_SEARCH_DEPTH && depth <= MAX_INTER_SEARCH_DEPTH) { diff --git a/src/transform.c b/src/transform.c index ea3d9f40..dabf971f 100644 --- a/src/transform.c +++ b/src/transform.c @@ -646,7 +646,7 @@ void quant(const encoder_state * const encoder_state, int16_t *coef, int16_t *q_ int32_t transform_shift = MAX_TR_DYNAMIC_RANGE - encoder->bitdepth - log2_tr_size; //!< Represents scaling through forward transform int32_t q_bits = QUANT_SHIFT + qp_scaled/6 + transform_shift; - int32_t add = ((encoder_state->tile->cur_pic->slicetype == SLICE_I) ? 171 : 85) << (q_bits - 9); + int32_t add = ((encoder_state->global->slicetype == SLICE_I) ? 171 : 85) << (q_bits - 9); int32_t q_bits8 = q_bits - 8; for (n = 0; n < width * height; n++) {