/* * * Copyright 2021 Rockchip Electronics Co. LTD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define MODULE_TAG "avs2d_ps" #include #include #include "mpp_mem.h" #include "mpp_log.h" #include "mpp_debug.h" #include "mpp_packet_impl.h" #include "hal_task.h" #include "avs2d_api.h" #include "avs2d_ps.h" static const RK_U32 wq_param_default[2][6] = { { 67, 71, 71, 80, 80, 106}, { 64, 49, 53, 58, 58, 64 } }; static const RK_U32 g_WqMDefault4x4[16] = { 64, 64, 64, 68, 64, 64, 68, 72, 64, 68, 76, 80, 72, 76, 84, 96 }; static const RK_U32 g_WqMDefault8x8[64] = { 64, 64, 64, 64, 68, 68, 72, 76, 64, 64, 64, 68, 72, 76, 84, 92, 64, 64, 68, 72, 76, 80, 88, 100, 64, 68, 72, 80, 84, 92, 100, 28, 68, 72, 80, 84, 92, 104, 112, 128, 76, 80, 84, 92, 104, 116, 132, 152, 96, 100, 104, 116, 124, 140, 164, 188, 104, 108, 116, 128, 152, 172, 192, 216 }; static const RK_U8 WeightQuantModel[4][64] = { // l a b c d h // 0 1 2 3 4 5 { // Mode 0 0, 0, 0, 4, 4, 4, 5, 5, 0, 0, 3, 3, 3, 3, 5, 5, 0, 3, 2, 2, 1, 1, 5, 5, 4, 3, 2, 2, 1, 5, 5, 5, 4, 3, 1, 1, 5, 5, 5, 5, 4, 3, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }, { // Mode 1 0, 0, 0, 4, 4, 4, 5, 5, 0, 0, 4, 4, 4, 4, 5, 5, 0, 3, 2, 2, 2, 1, 5, 5, 3, 3, 2, 2, 1, 5, 5, 5, 3, 3, 2, 1, 5, 5, 5, 5, 3, 3, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }, { // Mode 2 0, 0, 0, 4, 4, 3, 5, 5, 0, 0, 4, 4, 3, 2, 5, 5, 0, 4, 4, 3, 2, 1, 5, 5, 4, 4, 3, 2, 1, 5, 5, 5, 4, 3, 2, 1, 5, 5, 5, 5, 3, 2, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }, { // Mode 3 0, 0, 0, 3, 2, 1, 5, 5, 0, 0, 4, 3, 2, 1, 5, 5, 0, 4, 4, 3, 2, 1, 5, 5, 3, 3, 3, 3, 2, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, 5, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } }; static const RK_U8 WeightQuantModel4x4[4][16] = { // l a b c d h // 0 1 2 3 4 5 { // Mode 0 0, 4, 3, 5, 4, 2, 1, 5, 3, 1, 1, 5, 5, 5, 5, 5 }, { // Mode 1 0, 4, 4, 5, 3, 2, 2, 5, 3, 2, 1, 5, 5, 5, 5, 5 }, { // Mode 2 0, 4, 3, 5, 4, 3, 2, 5, 3, 2, 1, 5, 5, 5, 5, 5 }, { // Mode 3 0, 3, 1, 5, 3, 4, 2, 5, 1, 2, 2, 5, 5, 5, 5, 5 } }; static const RK_U32 *wq_get_default_matrix(RK_U32 sizeId) { return (sizeId == 0) ? g_WqMDefault4x4 : g_WqMDefault8x8; } static void wq_init_frame_quant_param(Avs2dCtx_t *p_dec) { RK_U32 i, j, k; Avs2dPicHeader_t *ph = &p_dec->ph; if (!p_dec->enable_wq || ph->pic_wq_data_index != 1) { return; } //wq_param_index == 0) { for (i = 0; i < WQP_SIZE; i++) { ph->pic_wq_param[i] = wq_param_default[DETAILED][i]; } } else if (ph->wq_param_index == 1) { for (i = 0; i < WQP_SIZE; i++) { ph->pic_wq_param[i] = ph->wq_param_delta1[i] + wq_param_default[UNDETAILED][i]; } } else if (ph->wq_param_index == 2) { for (i = 0; i < WQP_SIZE; i++) { ph->pic_wq_param[i] = ph->wq_param_delta2[i] + wq_param_default[DETAILED][i]; } } //!< reconstruct the weighting matrix for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { k = WeightQuantModel[ph->wq_model][j * 8 + i]; ph->pic_wq_matrix[1][j * 8 + i] = ph->pic_wq_param[k]; } } for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { k = WeightQuantModel4x4[ph->wq_model][j * 4 + i]; ph->pic_wq_matrix[0][j * 4 + i] = ph->pic_wq_param[k]; } } } static void wq_update_frame_matrix(Avs2dCtx_t *p_dec) { RK_U32 i, j; RK_U32 size_id, wqm_size; RK_U32 (*frm_wqm)[64]; Avs2dSeqHeader_t *vsh = &p_dec->vsh; Avs2dPicHeader_t *ph = &p_dec->ph; RK_U32 (*cur_wqm)[64] = p_dec->cur_wq_matrix; mpp_assert(ph->pic_wq_data_index <= 2); if (!p_dec->enable_wq) { for (size_id = 0; size_id < 2; size_id++) { for (i = 0; i < 64; i++) { cur_wqm[size_id][i] = 64; } } } else { if (ph->pic_wq_data_index == 0) { frm_wqm = vsh->seq_wq_matrix; } else { frm_wqm = ph->pic_wq_matrix; } for (size_id = 0; size_id < 2; size_id++) { wqm_size = MPP_MIN(1 << (size_id + 2), 8); for (i = 0; i < wqm_size; i++) { for (j = 0; j < wqm_size; j++) { cur_wqm[size_id][i * wqm_size + j] = frm_wqm[size_id][i * wqm_size + j]; } } } } } static MPP_RET parse_sequence_wqm(BitReadCtx_t *bitctx, Avs2dSeqHeader_t *vsh) { MPP_RET ret = MPP_OK; RK_U8 load_seq_wquant_data_flag; RK_U32 i, j, size_id, wqm_size; const RK_U32 *seq_wqm; READ_ONEBIT(bitctx, &load_seq_wquant_data_flag); for (size_id = 0; size_id < 2; size_id++) { wqm_size = MPP_MIN(1 << (size_id + 2), 8); if (load_seq_wquant_data_flag == 1) { for (j = 0; j < wqm_size; j++) { for (i = 0; i < wqm_size; i++) { READ_UE(bitctx, &vsh->seq_wq_matrix[size_id][j * wqm_size + i]); } } } else if (load_seq_wquant_data_flag == 0) { seq_wqm = wq_get_default_matrix(size_id); for (i = 0; i < (wqm_size * wqm_size); i++) { vsh->seq_wq_matrix[size_id][i] = seq_wqm[i]; } } } return ret; __BITREAD_ERR: return ret = bitctx->ret; } static MPP_RET parse_one_rps(BitReadCtx_t *bitctx, Avs2dRps_t *rps) { MPP_RET ret = MPP_OK; RK_U32 j; AVS2D_PARSE_TRACE("In"); READ_ONEBIT(bitctx, &rps->refered_by_others); READ_BITS(bitctx, 3, &rps->num_of_ref); AVS2D_PARSE_TRACE("refered_by_others_flag %d, num_Of_ref %d", rps->refered_by_others, rps->num_of_ref); if (rps->num_of_ref > AVS2_MAX_REFS) { ret = MPP_NOK; mpp_err_f("invalid ref num(%d).\n", rps->num_of_ref); goto __FAILED; } for (j = 0; j < rps->num_of_ref; j++) { READ_BITS(bitctx, 6, &rps->ref_pic[j]); AVS2D_PARSE_TRACE("delta_doi_of_ref_pic[%d]=%d", j, rps->ref_pic[j]); } READ_BITS(bitctx, 3, &rps->num_to_remove); for (j = 0; j < rps->num_to_remove; j++) { READ_BITS(bitctx, 6, &rps->remove_pic[j]); AVS2D_PARSE_TRACE("num_of_removed_pic[%d]=%d", j, rps->remove_pic[j]); } READ_MARKER_BIT(bitctx); AVS2D_PARSE_TRACE("Out ret %d\n", ret); return ret; __BITREAD_ERR: AVS2D_PARSE_TRACE("Out Bit read Err\n"); return ret = bitctx->ret; __FAILED: AVS2D_PARSE_TRACE("Out Failed\n"); return ret; } MPP_RET avs2d_parse_sequence_header(Avs2dCtx_t *p_dec) { MPP_RET ret = MPP_OK; RK_U32 i; RK_U32 val_temp = 0; Avs2dRps_t *rps = NULL; BitReadCtx_t *bitctx = &p_dec->bitctx; Avs2dSeqHeader_t *vsh = &p_dec->vsh; AVS2D_PARSE_TRACE("Bitread buf %p, data %p, buf_len %d, left %d\n", bitctx->buf, bitctx->data_, bitctx->buf_len, bitctx->bytes_left_); memset(vsh, 0, sizeof(Avs2dSeqHeader_t)); READ_BITS(bitctx, 8, &vsh->profile_id); //!< check profile_id if (vsh->profile_id != 0x12 && vsh->profile_id != 0x20 && vsh->profile_id != 0x22) { ret = MPP_NOK; mpp_err_f("profile_id 0x%02x is not supported.\n", vsh->profile_id); goto __FAILED; } READ_BITS(bitctx, 8, &vsh->level_id); if (vsh->level_id > 0x6A) { ret = MPP_NOK; mpp_err_f("level_id 0x%02x is not supported.\n", vsh->level_id); goto __FAILED; } READ_ONEBIT(bitctx, &vsh->progressive_sequence); READ_ONEBIT(bitctx, &vsh->field_coded_sequence); READ_BITS(bitctx, 14, &vsh->horizontal_size); READ_BITS(bitctx, 14, &vsh->vertical_size); if (vsh->horizontal_size < 16 || vsh->vertical_size < 16) { ret = MPP_NOK; mpp_err_f("invalid sequence width(%d), height(%d).\n", vsh->horizontal_size, vsh->vertical_size); goto __FAILED; } READ_BITS(bitctx, 2, &vsh->chroma_format); if (vsh->chroma_format != CHROMA_420) { ret = MPP_NOK; mpp_err_f("chroma_format 0x%02x is not supported.\n", vsh->chroma_format); goto __FAILED; } READ_BITS(bitctx, 3, &vsh->sample_precision); if (vsh->profile_id == MAIN10_PROFILE) { READ_BITS(bitctx, 3, &vsh->encoding_precision); } else { vsh->encoding_precision = 1; } vsh->bit_depth = 6 + (vsh->encoding_precision << 1); if (vsh->sample_precision < 1 || vsh->sample_precision > 2) { ret = MPP_NOK; mpp_err_f("sample_precision 0x%02x is not supported.\n", vsh->sample_precision); goto __FAILED; } if (vsh->encoding_precision < 1 || vsh->encoding_precision > 2) { ret = MPP_NOK; mpp_err_f("encoding_precision 0x%02x is not supported.\n", vsh->encoding_precision); goto __FAILED; } READ_BITS(bitctx, 4, &vsh->aspect_ratio); READ_BITS(bitctx, 4, &vsh->frame_rate_code); READ_BITS(bitctx, 18, &val_temp); //!< bit_rate_lower_18 vsh->bit_rate = val_temp << 12; READ_MARKER_BIT(bitctx); READ_BITS(bitctx, 12, &val_temp); //!< bit_rate_upper_12 vsh->bit_rate += val_temp; READ_ONEBIT(bitctx, &vsh->low_delay); READ_MARKER_BIT(bitctx); READ_ONEBIT(bitctx, &vsh->enable_temporal_id); READ_BITS(bitctx, 18, &vsh->bbv_buffer_size); READ_BITS(bitctx, 3, &vsh->lcu_size); if (vsh->lcu_size < 4 || vsh->lcu_size > 6) { ret = MPP_NOK; mpp_err_f("invalid lcu size: %d\n", vsh->lcu_size); goto __FAILED; } READ_ONEBIT(bitctx, &vsh->enable_weighted_quant); if (vsh->enable_weighted_quant) { parse_sequence_wqm(bitctx, vsh); } READ_ONEBIT(bitctx, &val_temp); vsh->enable_background_picture = val_temp ^ 0x01; READ_ONEBIT(bitctx, &vsh->enable_mhp_skip); READ_ONEBIT(bitctx, &vsh->enable_dhp); READ_ONEBIT(bitctx, &vsh->enable_wsm); READ_ONEBIT(bitctx, &vsh->enable_amp); READ_ONEBIT(bitctx, &vsh->enable_nsqt); READ_ONEBIT(bitctx, &vsh->enable_nsip); READ_ONEBIT(bitctx, &vsh->enable_2nd_transform); READ_ONEBIT(bitctx, &vsh->enable_sao); READ_ONEBIT(bitctx, &vsh->enable_alf); READ_ONEBIT(bitctx, &vsh->enable_pmvr); READ_MARKER_BIT(bitctx); //!< parse rps READ_BITS(bitctx, 6, &vsh->num_of_rps); for (i = 0; i < vsh->num_of_rps; i++) { rps = &vsh->seq_rps[i]; AVS2D_PARSE_TRACE("--------rcs[%d]--------", i); FUN_CHECK(ret = parse_one_rps(bitctx, rps)); } if (vsh->low_delay == 0) { READ_BITS(bitctx, 5, &vsh->picture_reorder_delay); } else { vsh->picture_reorder_delay = 0; } READ_ONEBIT(bitctx, &vsh->enable_clf); READ_BITS(bitctx, 2, &val_temp); //!< reserved 2bits 00 if (val_temp) { AVS2D_DBG(AVS2D_DBG_WARNNING, "reserver bits error.\n"); } return ret; __BITREAD_ERR: return ret = bitctx->ret; __FAILED: return ret; } static MPP_RET read_pic_alf_coeff(BitReadCtx_t *bitctx, RK_S32 *alf_coeff) { MPP_RET ret = MPP_OK; RK_U32 j; RK_S32 alf_sum = 0; for (j = 0; j < ALF_MAX_COEFS; j++) { READ_SE(bitctx, &alf_coeff[j]); if ((j <= 7 && (alf_coeff[j] < -64 || alf_coeff[j] > 63)) || (j == 8 && (alf_coeff[j] < -1088 || alf_coeff[j] > 1071))) { ret = MPP_NOK; mpp_err_f("invalid alf coeff(%d).\n", alf_coeff[j]); goto __FAILED; } if (j <= 7) { alf_sum += (2 * alf_coeff[j]); //!< avs2 9.12.2 } } alf_coeff[8] += (64 - alf_sum); __BITREAD_ERR: return ret = bitctx->ret; __FAILED: return ret; } static MPP_RET parse_pic_alf_params(BitReadCtx_t *bitctx, Avs2dPicHeader_t *ph) { MPP_RET ret = MPP_OK; RK_U32 i; READ_ONEBIT(bitctx, &ph->enable_pic_alf_y); READ_ONEBIT(bitctx, &ph->enable_pic_alf_cb); READ_ONEBIT(bitctx, &ph->enable_pic_alf_cr); if (ph->enable_pic_alf_y) { RK_U32 pre_symbole = 0; RK_U32 symbol = 0; READ_UE(bitctx, &ph->alf_filter_num); ph->alf_filter_num += 1; if (ph->alf_filter_num > ALF_MAX_FILTERS) { ret = MPP_NOK; mpp_err_f("invalid alf filter num(%d).\n", ph->alf_filter_num); goto __FAILED; } for (i = 0; i < ph->alf_filter_num; i++) { if (i > 0) { if (ph->alf_filter_num != 16) { READ_UE(bitctx, &symbol); } else { symbol = 1; } ph->alf_filter_pattern[symbol + pre_symbole] = 1; pre_symbole += symbol; } FUN_CHECK(ret = read_pic_alf_coeff(bitctx, ph->alf_coeff_y[i])); } if (pre_symbole > 15) { ret = MPP_NOK; mpp_err_f("invalid alf region distance.\n"); goto __FAILED; } //!< @see avs2 9.12.2 eg: 0000111222223333 ph->alf_coeff_idx_tab[0] = 0; for (i = 1; i < ALF_MAX_FILTERS; i++) { ph->alf_coeff_idx_tab[i] = (ph->alf_filter_pattern[i]) ? (ph->alf_coeff_idx_tab[i - 1] + 1) : ph->alf_coeff_idx_tab[i - 1]; } } if (ph->enable_pic_alf_cb) { FUN_CHECK(ret = read_pic_alf_coeff(bitctx, ph->alf_coeff_cb)); } if (ph->enable_pic_alf_cr) { FUN_CHECK(ret = read_pic_alf_coeff(bitctx, ph->alf_coeff_cr)); } __BITREAD_ERR: return ret = bitctx->ret; __FAILED: return ret; } static MPP_RET parse_picture_header_comm(Avs2dCtx_t *p_dec) { MPP_RET ret = MPP_OK; RK_U32 i, j; RK_U32 val_temp = 0; BitReadCtx_t *bitctx = &p_dec->bitctx; Avs2dSeqHeader_t *vsh = &p_dec->vsh; Avs2dPicHeader_t *ph = &p_dec->ph; AVS2D_PARSE_TRACE("In"); READ_ONEBIT(bitctx, &val_temp); ph->enable_loop_filter = val_temp ^ 0x01; if (ph->enable_loop_filter) { READ_ONEBIT(bitctx, &ph->loop_filter_parameter_flag); if (ph->loop_filter_parameter_flag) { READ_SE(bitctx, &ph->alpha_c_offset); READ_SE(bitctx, &ph->beta_offset); if (ph->alpha_c_offset < -8 || ph->alpha_c_offset > 8 || ph->beta_offset < -8 || ph->beta_offset > 8) { ret = MPP_NOK; mpp_err_f("invalid alpha_c_offset/beta_offset.\n"); goto __FAILED; } } else { ph->alpha_c_offset = 0; ph->beta_offset = 0; } } READ_ONEBIT(bitctx, &val_temp); ph->enable_chroma_quant_param = val_temp ^ 0x01; if (ph->enable_chroma_quant_param) { READ_SE(bitctx, &ph->chroma_quant_param_delta_cb); READ_SE(bitctx, &ph->chroma_quant_param_delta_cr); } else { ph->chroma_quant_param_delta_cb = 0; ph->chroma_quant_param_delta_cr = 0; } if (ph->chroma_quant_param_delta_cb < -16 || ph->chroma_quant_param_delta_cb > 16 || ph->chroma_quant_param_delta_cr < -16 || ph->chroma_quant_param_delta_cr > 16) { ret = MPP_NOK; mpp_err_f("invalid chrome quant param delta.\n"); goto __FAILED; } p_dec->enable_wq = 0; if (vsh->enable_weighted_quant) { READ_ONEBIT(bitctx, &ph->enable_pic_weight_quant); if (ph->enable_pic_weight_quant) { p_dec->enable_wq = 1; READ_BITS(bitctx, 2, &ph->pic_wq_data_index); if (ph->pic_wq_data_index == 1) { SKIP_BITS(bitctx, 1); READ_BITS(bitctx, 2, &ph->wq_param_index); READ_BITS(bitctx, 2, &ph->wq_model); if (ph->wq_param_index == 1) { for (i = 0; i < 6; i++) { READ_SE(bitctx, &ph->wq_param_delta1[i]); } } else if (ph->wq_param_index == 2) { for (i = 0; i < 6; i++) { READ_SE(bitctx, &ph->wq_param_delta2[i]); } } } else if (ph->pic_wq_data_index == 2) { RK_U32 size_id, wqm_size; for (size_id = 0; size_id < 2; size_id++) { wqm_size = MPP_MIN(1 << (size_id + 2), 8); for (j = 0; j < wqm_size; j++) { for (i = 0; i < wqm_size; i++) { READ_UE(bitctx, &ph->pic_wq_matrix[size_id][j * wqm_size + i]); } } } } } } if (vsh->enable_alf) { FUN_CHECK(ret = parse_pic_alf_params(bitctx, ph)); } AVS2D_PARSE_TRACE("Out, ret %d\n", ret); return ret; __BITREAD_ERR: AVS2D_PARSE_TRACE("Out, Bit read Err"); return ret = bitctx->ret; __FAILED: AVS2D_PARSE_TRACE("Out, Failed"); return ret; } static MPP_RET parse_picture_header_intra(Avs2dCtx_t *p_dec) { MPP_RET ret = MPP_OK; RK_U32 predict = 0; BitReadCtx_t *bitctx = &p_dec->bitctx; Avs2dSeqHeader_t *vsh = &p_dec->vsh; Avs2dPicHeader_t *ph = &p_dec->ph; RK_U32 last_pic_out_delay = ph->picture_output_delay; AVS2D_PARSE_TRACE("In."); memset(ph, 0, sizeof(Avs2dPicHeader_t)); ph->picture_type = I_PICTURE; AVS2D_PARSE_TRACE("Bitread buf %p, data %p, buf_len %d, left %d\n", bitctx->buf, bitctx->data_, bitctx->buf_len, bitctx->bytes_left_); READ_BITS_LONG(bitctx, 32, &ph->bbv_delay); AVS2D_PARSE_TRACE("bbv_delay %d\n", ph->bbv_delay); READ_ONEBIT(bitctx, &ph->time_code_flag); AVS2D_PARSE_TRACE("time_code_flag %d\n", ph->time_code_flag); if (ph->time_code_flag) { READ_BITS(bitctx, 24, &ph->time_code); AVS2D_PARSE_TRACE("time_code %d\n", ph->time_code); } if (vsh->enable_background_picture) { READ_ONEBIT(bitctx, &ph->background_picture_flag); AVS2D_PARSE_TRACE("background_picture_flag %d\n", ph->background_picture_flag); if (ph->background_picture_flag) { READ_ONEBIT(bitctx, &ph->background_picture_output_flag); AVS2D_PARSE_TRACE("background_picture_output_flag %d\n", ph->background_picture_output_flag); if (ph->background_picture_output_flag) { ph->picture_type = G_PICTURE; } else { ph->picture_type = GB_PICTURE; } } } READ_BITS(bitctx, 8, &ph->doi); AVS2D_PARSE_TRACE("Picture type %d doi %d\n", ph->picture_type, ph->doi); if (vsh->enable_temporal_id) { READ_BITS(bitctx, 3, &ph->temporal_id); AVS2D_PARSE_TRACE("temporal_id %d\n", ph->temporal_id); } if (vsh->low_delay == 0 && !(ph->background_picture_flag && !ph->background_picture_output_flag)) { READ_UE(bitctx, &ph->picture_output_delay); AVS2D_PARSE_TRACE("picture_output_delay %d\n", ph->picture_output_delay); if (ph->picture_output_delay >= 64) { ret = MPP_NOK; mpp_err_f("invalid picture output delay(%d) intra.\n", ph->picture_output_delay); goto __FAILED; } } else { ph->picture_output_delay = last_pic_out_delay; } READ_ONEBIT(bitctx, &predict); AVS2D_PARSE_TRACE("predict %d\n", predict); if (predict) { RK_U8 rcs_index = 0; READ_BITS(bitctx, 5, &rcs_index); AVS2D_PARSE_TRACE("rcs_index %d\n", rcs_index); p_dec->frm_mgr.cur_rps = vsh->seq_rps[rcs_index]; } else { FUN_CHECK(ret = parse_one_rps(bitctx, &p_dec->frm_mgr.cur_rps)); } AVS2D_PARSE_TRACE("num_of_remove %d", p_dec->frm_mgr.cur_rps.num_to_remove); if (vsh->low_delay) { READ_UE(bitctx, &ph->bbv_check_times); AVS2D_PARSE_TRACE("bbv_check_time %d\n", ph->bbv_check_times); } READ_ONEBIT(bitctx, &ph->progressive_frame); AVS2D_PARSE_TRACE("progressive_frame %d\n", ph->progressive_frame); if (!ph->progressive_frame) { READ_ONEBIT(bitctx, &ph->picture_structure); AVS2D_PARSE_TRACE("picture_structure %d\n", ph->picture_structure); } else { ph->picture_structure = 1; //!< frame picture } READ_ONEBIT(bitctx, &ph->top_field_first); AVS2D_PARSE_TRACE("top_field_first %d\n", ph->top_field_first); READ_ONEBIT(bitctx, &ph->repeat_first_field); AVS2D_PARSE_TRACE("repeat_first_field %d\n", ph->repeat_first_field); if (vsh->field_coded_sequence == 1) { //!< field picture READ_ONEBIT(bitctx, &ph->is_top_field); AVS2D_PARSE_TRACE("is_top_field %d\n", ph->is_top_field); SKIP_BITS(bitctx, 1); AVS2D_PARSE_TRACE("skip bits\n"); } READ_ONEBIT(bitctx, &ph->fixed_picture_qp); AVS2D_PARSE_TRACE("fixed_picture_qp %d\n", ph->fixed_picture_qp); READ_BITS(bitctx, 7, &ph->picture_qp); AVS2D_PARSE_TRACE("picture_qp %d\n", ph->picture_qp); if (ph->picture_qp > (63 + 8 * (vsh->bit_depth - 8))) { ret = MPP_NOK; mpp_err_f("invalid picture qp(%d).\n", ph->picture_qp); goto __FAILED; } FUN_CHECK(ret = parse_picture_header_comm(p_dec)); AVS2D_PARSE_TRACE("Out. ret %d", ret); return ret; __BITREAD_ERR: AVS2D_PARSE_TRACE("Out. Bit read ERR"); return ret = bitctx->ret; __FAILED: AVS2D_PARSE_TRACE("Out. Failed"); return ret; } static MPP_RET parse_picture_header_inter(Avs2dCtx_t *p_dec) { MPP_RET ret = MPP_OK; RK_U32 predict = 0; BitReadCtx_t *bitctx = &p_dec->bitctx; Avs2dSeqHeader_t *vsh = &p_dec->vsh; Avs2dPicHeader_t *ph = &p_dec->ph; memset(ph, 0, sizeof(Avs2dPicHeader_t)); READ_BITS_LONG(bitctx, 32, &ph->bbv_delay); READ_BITS(bitctx, 2, &ph->picture_coding_type); if (vsh->enable_background_picture) { if (ph->picture_coding_type == 1) { READ_ONEBIT(bitctx, &ph->background_pred_flag); } if (ph->picture_coding_type != 2 && !ph->background_pred_flag) { READ_ONEBIT(bitctx, &ph->background_reference_flag); //!< P/F ref G/GB } } if (ph->picture_coding_type == 1) { ph->picture_type = ph->background_pred_flag ? S_PICTURE : P_PICTURE; } else if (ph->picture_coding_type == 2) { ph->picture_type = B_PICTURE; } else if (ph->picture_coding_type == 3) { ph->picture_type = F_PICTURE; } else { ret = MPP_NOK; mpp_err_f("invalid picture coding type(0).\n"); goto __FAILED; } READ_BITS(bitctx, 8, &ph->doi); AVS2D_PARSE_TRACE("Picture type %d doi %d\n", ph->picture_type, ph->doi); if (vsh->enable_temporal_id) { READ_BITS(bitctx, 3, &ph->temporal_id); } if (vsh->low_delay == 0) { READ_UE(bitctx, &ph->picture_output_delay); AVS2D_PARSE_TRACE("picture_output_delay %d\n", ph->picture_output_delay); if (ph->picture_output_delay >= 64) { ret = MPP_NOK; mpp_err_f("invalid picture output delay(%d) intra.\n", ph->picture_output_delay); goto __FAILED; } } else { ph->picture_output_delay = 0; } READ_ONEBIT(bitctx, &predict); AVS2D_PARSE_TRACE("predict %d\n", predict); if (predict) { RK_U8 rcs_index = 0; READ_BITS(bitctx, 5, &rcs_index); p_dec->frm_mgr.cur_rps = vsh->seq_rps[rcs_index]; } else { FUN_CHECK(ret = parse_one_rps(bitctx, &p_dec->frm_mgr.cur_rps)); } AVS2D_PARSE_TRACE("num_of_remove %d", p_dec->frm_mgr.cur_rps.num_to_remove); if (vsh->low_delay) { READ_UE(bitctx, &ph->bbv_check_times); } READ_ONEBIT(bitctx, &ph->progressive_frame); if (!ph->progressive_frame) { READ_ONEBIT(bitctx, &ph->picture_structure); } else { ph->picture_structure = 1; //!< frame picture } READ_ONEBIT(bitctx, &ph->top_field_first); READ_ONEBIT(bitctx, &ph->repeat_first_field); if (vsh->field_coded_sequence == 1) { //!< field picture READ_ONEBIT(bitctx, &ph->is_top_field); SKIP_BITS(bitctx, 1); } READ_ONEBIT(bitctx, &ph->fixed_picture_qp); READ_BITS(bitctx, 7, &ph->picture_qp); if (ph->picture_qp > (63 + 8 * (vsh->bit_depth - 8))) { ret = MPP_NOK; mpp_err_f("invalid picture qp(%d).\n", ph->picture_qp); goto __FAILED; } if (ph->picture_coding_type != 2 || ph->picture_structure == 0) { SKIP_BITS(bitctx, 1); } READ_ONEBIT(bitctx, &ph->enable_random_decodable); FUN_CHECK(ret = parse_picture_header_comm(p_dec)); return ret; __BITREAD_ERR: return ret = bitctx->ret; __FAILED: return ret; } MPP_RET avs2d_parse_picture_header(Avs2dCtx_t *p_dec, RK_U32 startcode) { MPP_RET ret = MPP_OK; AVS2D_PARSE_TRACE("In."); switch (startcode) { case AVS2_I_PICTURE_START_CODE: ret = parse_picture_header_intra(p_dec); break; case AVS2_PB_PICTURE_START_CODE: ret = parse_picture_header_inter(p_dec); break; default: ret = MPP_NOK; mpp_err_f("invalid picture startcode(%d).\n", startcode); return ret; } wq_init_frame_quant_param(p_dec); wq_update_frame_matrix(p_dec); AVS2D_PARSE_TRACE("Out."); return ret; }