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.
This commit is contained in:
Laurent Fasnacht 2014-05-07 11:18:10 +02:00
parent 39d96e0546
commit 0e6f1c99fc
7 changed files with 36 additions and 66 deletions

View file

@ -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); 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, 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]); temp_psnr[0], temp_psnr[1], temp_psnr[2]);
// Increment total PSNR // Increment total PSNR

View file

@ -58,7 +58,6 @@ static void encode_sao(encoder_state *encoder,
*/ */
void encoder_state_init_lambda(encoder_state * const encoder_state) 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 qp = encoder_state->global->QP;
double lambda_scale = 1.0; double lambda_scale = 1.0;
double qp_temp = qp - 12; 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 // Default QP-factor from HM config
double qp_factor = 0.4624; double qp_factor = 0.4624;
if (cur_pic->slicetype == SLICE_I) { if (encoder_state->global->slicetype == SLICE_I) {
qp_factor=0.57*lambda_scale; qp_factor=0.57*lambda_scale;
} }
lambda = qp_factor*pow( 2.0, qp_temp/3.0 ); 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; 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); yuv_t *ver_buf = yuv_t_alloc(LCU_WIDTH + 2);
cabac_start(&encoder_state->cabac); 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 // Initialize lambda value(s) to use in search
encoder_state_init_lambda(encoder_state); 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]); encoder_state *sub_state = &(main_state->children[i]);
if (sub_state->tile != main_state->tile) { 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->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->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); 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_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_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_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 // Clear the reference list
encoder_state_clear_refs(main_state); encoder_state_clear_refs(main_state);
main_state->tile->cur_pic->slicetype = SLICE_I; main_state->global->slicetype = SLICE_I;
main_state->tile->cur_pic->type = NAL_IDR_W_RADL; main_state->global->pictype = NAL_IDR_W_RADL;
} else { } else {
main_state->tile->cur_pic->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : SLICE_P; main_state->global->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : SLICE_P;
main_state->tile->cur_pic->type = NAL_TRAIL_R; main_state->global->pictype = NAL_TRAIL_R;
} }
} else { } else {
//Clear the bitstream if it's not the main encoder //Clear the bitstream if it's not the main encoder
bitstream_clear(&main_state->stream); 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) { for (i = 0; main_state->children[i].encoder_control; ++i) {
encoder_state_new_frame(&main_state->children[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; const encoder_control * const encoder = main_state->encoder_control;
bitstream * const stream = &main_state->stream; 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; int i;
/** IDR picture when: period == 0 and frame == 0 if (main_state->global->is_radl_frame) {
* 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;
// Access Unit Delimiter (AUD) // Access Unit Delimiter (AUD)
if (encoder->aud_enable) if (encoder->aud_enable)
write_aud(main_state); write_aud(main_state);
@ -1273,10 +1253,6 @@ static void encoder_state_write_bitstream_main(encoder_state * const main_state)
bitstream_align(stream); bitstream_align(stream);
} }
} else { } 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) // Access Unit Delimiter (AUD)
if (encoder->aud_enable) if (encoder->aud_enable)
write_aud(main_state); 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 // Not quite sure if this is correct, but it seems to have worked so far
// so I tried to not change it's behavior. // 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, 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) { 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) { for (i = 0; main_state->children[i].encoder_control; ++i) {
//Append bitstream to main stream //Append bitstream to main stream
bitstream_append(&main_state->stream, &main_state->children[i].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) void encode_access_unit_delimiter(encoder_state * const encoder_state)
{ {
bitstream * const stream = &encoder_state->stream; bitstream * const stream = &encoder_state->stream;
const picture * const cur_pic = encoder_state->tile->cur_pic; uint8_t pic_type = encoder_state->global->slicetype == SLICE_I ? 0
uint8_t pic_type = cur_pic->slicetype == SLICE_I ? 0 : encoder_state->global->slicetype == SLICE_P ? 1
: cur_pic->slicetype == SLICE_P ? 1
: 2; : 2;
WRITE_U(stream, pic_type, 3, "pic_type"); 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; const encoder_control * const encoder = encoder_state->encoder_control;
bitstream * const stream = &encoder_state->stream; bitstream * const stream = &encoder_state->stream;
const picture * const cur_pic = encoder_state->tile->cur_pic;
#ifdef _DEBUG #ifdef _DEBUG
printf("=========== Slice ===========\n"); 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"); WRITE_U(stream, 1, 1, "first_slice_segment_in_pic_flag");
if (cur_pic->type >= NAL_BLA_W_LP if (encoder_state->global->pictype >= NAL_BLA_W_LP
&& cur_pic->type <= NAL_RSV_IRAP_VCL23) { && encoder_state->global->pictype <= NAL_RSV_IRAP_VCL23) {
WRITE_U(stream, 1, 1, "no_output_of_prior_pics_flag"); 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_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 // 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"); //WRITE_U(stream, 1, 1, "pic_output_flag");
//end if //end if
//if( IdrPicFlag ) <- nal_unit_type == 5 //if( IdrPicFlag ) <- nal_unit_type == 5
if (cur_pic->type != NAL_IDR_W_RADL if (encoder_state->global->pictype != NAL_IDR_W_RADL
&& cur_pic->type != NAL_IDR_N_LP) { && encoder_state->global->pictype != NAL_IDR_N_LP) {
int j; int j;
int ref_negative = encoder_state->global->ref->used_size; int ref_negative = encoder_state->global->ref->used_size;
int ref_positive = 0; int ref_positive = 0;
@ -2045,17 +2017,17 @@ void encode_slice_header(encoder_state * const encoder_state)
//end if //end if
//end if //end if
if (encoder->sao_enable) { if (encoder->sao_enable) {
WRITE_U(stream, cur_pic->slice_sao_luma_flag, 1, "slice_sao_luma_flag"); WRITE_U(stream, 1, 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_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_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, 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"); 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"); 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) color_index color_i)
{ {
cabac_data * const cabac = &encoder_state->cabac; cabac_data * const cabac = &encoder_state->cabac;
const picture * const cur_pic = encoder_state->tile->cur_pic;
sao_eo_cat i; sao_eo_cat i;
// Skip colors with no SAO. // Skip colors with no SAO.
if (color_i == COLOR_Y && !cur_pic->slice_sao_luma_flag) return; //FIXME: for now, we always have SAO for all channels
if (color_i != COLOR_Y && !cur_pic->slice_sao_chroma_flag) return; 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_luma: TR, cMax = 2, cRiceParam = 0, bins = {0, bypass}
/// sao_type_idx_chroma: 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 // Encode skip flag
if (cur_pic->slicetype != SLICE_I) { if (encoder_state->global->slicetype != SLICE_I) {
int8_t ctx_skip = 0; // uiCtxSkip = aboveskipped + leftskipped; int8_t ctx_skip = 0; // uiCtxSkip = aboveskipped + leftskipped;
int ui; int ui;
int16_t num_cand = MRG_MAX_NUM_CANDS; int16_t num_cand = MRG_MAX_NUM_CANDS;
@ -2253,7 +2225,7 @@ void encode_coding_tree(encoder_state * const encoder_state,
// ENDIF SKIP // ENDIF SKIP
// Prediction mode // Prediction mode
if (cur_pic->slicetype != SLICE_I) { if (encoder_state->global->slicetype != SLICE_I) {
cabac->ctx = &(cabac->ctx_cu_pred_mode_model); cabac->ctx = &(cabac->ctx_cu_pred_mode_model);
CABAC_BIN(cabac, (cur_cu->type == CU_INTRA), "PredMode"); CABAC_BIN(cabac, (cur_cu->type == CU_INTRA), "PredMode");
} }

View file

@ -152,6 +152,10 @@ typedef struct {
int8_t ref_list; int8_t ref_list;
//int8_t ref_idx_num[2]; //int8_t ref_idx_num[2];
int is_radl_frame;
uint8_t pictype;
uint8_t slicetype;
} encoder_state_config_global; } encoder_state_config_global;
typedef struct { typedef struct {

View file

@ -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->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_luma = MALLOC(sao_info, width_in_lcu * height_in_lcu);
pic->sao_chroma = MALLOC(sao_info, width_in_lcu * height_in_lcu); pic->sao_chroma = MALLOC(sao_info, width_in_lcu * height_in_lcu);

View file

@ -126,10 +126,6 @@ typedef struct picture_struct
uint8_t referenced; //!< \brief Whether this picture is referenced. uint8_t referenced; //!< \brief Whether this picture is referenced.
int32_t refcount; //!< \brief Number of references in reflist to the picture int32_t refcount; //!< \brief Number of references in reflist to the picture
cu_info* cu_array; //!< \brief Info for each CU at each depth. 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_luma; //!< \brief Array of sao parameters for every LCU.
struct sao_info_struct *sao_chroma; //!< \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 int32_t poc; //!< \brief Picture order count

View file

@ -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) 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 >= MIN_INTER_SEARCH_DEPTH &&
depth <= MAX_INTER_SEARCH_DEPTH) depth <= MAX_INTER_SEARCH_DEPTH)
{ {

View file

@ -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 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 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; int32_t q_bits8 = q_bits - 8;
for (n = 0; n < width * height; n++) { for (n = 0; n < width * height; n++) {