/* * Copyright 2015 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 "m2vd_parser" #include #include "mpp_env.h" #include "mpp_debug.h" #include "mpp_packet_impl.h" #include "m2vd_parser.h" #include "m2vd_codec.h" #define VPU_BITSTREAM_START_CODE (0x42564b52) /* RKVB, rockchip video bitstream */ RK_U32 m2vd_debug = 0x0; static RK_U8 scanOrder[2][64] = { { /* zig-zag */ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }, { /* Alternate */ 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63 } }; static RK_U8 intraDefaultQMatrix[64] = { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 }; static int frame_period_Table[16] = { 1, 11142, 10667, 10240, 8542, 8533, 5120, 4271, 4267, 1, 1, 1, 1, 1, 1, 1 }; static const MppFrameRational mpeg2_aspect[16] = { {0, 1}, {1, 1}, {4, 3}, {16, 9}, {221, 100}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, }; static inline RK_S32 m2vd_get_readbits(BitReadCtx_t *bx) { return bx->used_bits; } static inline RK_S32 m2vd_get_leftbits(BitReadCtx_t *bx) { return (bx->bytes_left_ * 8 + bx->num_remaining_bits_in_curr_byte_); } static RK_S32 m2vd_read_bits(BitReadCtx_t *bx, RK_U32 bits) { RK_S32 ret = 0; if (bits < 32) mpp_read_bits(bx, bits, &ret); else mpp_read_longbits(bx, bits, (RK_U32 *)&ret); return ret; } static RK_S32 m2vd_show_bits(BitReadCtx_t *bx, RK_U32 bits) { RK_S32 ret = 0; mpp_show_bits(bx, bits, &ret); return ret; } static MPP_RET m2vd_parser_init_ctx(M2VDParserContext *ctx, ParserCfg *cfg) { MPP_RET ret = MPP_OK; RK_S32 i = 0; m2vd_dbg_func("FUN_I"); M2VD_CHK_I(ctx); memset(ctx, 0, sizeof(*ctx)); ctx->dxva_ctx = mpp_calloc(M2VDDxvaParam, 1); ctx->bitread_ctx = mpp_calloc(BitReadCtx_t, 1); ctx->packet_slots = cfg->packet_slots; ctx->frame_slots = cfg->frame_slots; mpp_buf_slot_setup(ctx->frame_slots, 16); ctx->initFlag = 0; /* copy from mpeg2decoder::mpeg2decoder */ memset(&ctx->Framehead, 0, 3 * sizeof(M2VDFrameHead)); ctx->frame_ref0 = &ctx->Framehead[0]; ctx->frame_ref1 = &ctx->Framehead[1]; ctx->frame_cur = &ctx->Framehead[2]; for (i = 0; i < 3; i++) { mpp_frame_init(&ctx->Framehead[i].f); if (!ctx->Framehead[i].f) { mpp_err("Failed to allocate frame buffer %d\n", i); return MPP_ERR_NOMEM; } ctx->Framehead[i].picCodingType = 0xffffffff; ctx->Framehead[i].slot_index = 0xff; } #if M2VD_SKIP_ERROR_FRAME_EN ctx->mHwDecStatus = MPP_OK; #endif ctx->resetFlag = 0; ctx->flush_dpb_eos = 0; ctx->pic_head.pre_temporal_reference = 0; ctx->pic_head.pre_picture_coding_type = 0; ctx->pic_head.picture_coding_type = 0; /* copy form mpeg2decoder::decoder_init */ //---------------------------------------------------- ctx->bitstream_sw_buf = mpp_calloc(RK_U8, M2VD_BUF_SIZE_BITMEM); mpp_packet_init(&ctx->input_packet, ctx->bitstream_sw_buf, M2VD_BUF_SIZE_BITMEM); ctx->qp_tab_sw_buf = mpp_calloc(RK_U8, M2VD_BUF_SIZE_QPTAB); ctx->seq_head.pIntra_table = ctx->qp_tab_sw_buf; ctx->seq_head.pInter_table = ctx->seq_head.pIntra_table + 64; ctx->MPEG2_Flag = 0; ctx->seq_ext_head.progressive_sequence = 1; ctx->pic_code_ext_head.progressive_frame = 1; ctx->pic_code_ext_head.picture_structure = M2VD_PIC_STRUCT_FRAME; ctx->pic_head.pre_picture_coding_type = M2VD_CODING_TYPE_D; ctx->top_first_cnt = 0; ctx->bottom_first_cnt = 0; ctx->pic_code_ext_head.frame_pred_frame_dct = 1; ctx->seq_ext_head.chroma_format = 1; ctx->seq_disp_ext_head.matrix_coefficients = 5; ctx->PreGetFrameTime = 0; ctx->maxFrame_inGOP = 0; ctx->preframe_period = 0; ctx->mHeaderDecFlag = 0; ctx->mExtraHeaderDecFlag = 0; ctx->max_stream_size = M2VD_BUF_SIZE_BITMEM; ctx->ref_frame_cnt = 0; ctx->need_split = cfg->cfg->base.split_parse; ctx->left_length = 0; ctx->vop_header_found = 0; if (M2VD_DBG_DUMP_REG & m2vd_debug) { RK_S32 k = 0; for (k = 0; k < M2VD_DBG_FILE_NUM; k++) ctx->fp_dbg_file[k] = NULL; ctx->fp_dbg_file[0] = fopen("/sdcard/m2vd_dbg_stream.txt", "wb"); if (!ctx->fp_dbg_file[0]) mpp_log("open file failed: %s", "/sdcard/m2vd_dbg_stream.txt"); ctx->fp_dbg_yuv = fopen("/sdcard/m2vd_dbg_yuv_out.txt", "wb"); if (!ctx->fp_dbg_yuv) mpp_log("open file failed: %s", "/sdcard/m2vd_dbg_yuv_out.txt"); } else { RK_S32 k = 0; for (k = 0; k < M2VD_DBG_FILE_NUM; k++) ctx->fp_dbg_file[k] = NULL; } m2vd_dbg_func("FUN_O"); __FAILED: return ret; } MPP_RET m2vd_parser_init(void *ctx, ParserCfg *parser_cfg) { MPP_RET ret = MPP_OK; M2VDContext *c = (M2VDContext *)ctx; M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; m2vd_dbg_func("FUN_I"); if (p == NULL) { M2VD_CHK_M(p = (M2VDParserContext*)mpp_calloc(M2VDParserContext, 1)); c->parse_ctx = p; } M2VD_CHK_F(m2vd_parser_init_ctx(p, parser_cfg)); mpp_env_get_u32("m2vd_debug", &m2vd_debug, 0); m2vd_dbg_func("FUN_O"); __FAILED: return ret; } MPP_RET m2vd_parser_deinit(void *ctx) { RK_U32 k = 0; MPP_RET ret = MPP_OK; M2VDContext *c = (M2VDContext *)ctx; M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; m2vd_dbg_func("FUN_I"); for (k = 0; k < M2VD_DBG_FILE_NUM; k++) { M2VD_FCLOSE(p->fp_dbg_file[k]); } M2VD_FCLOSE(p->fp_dbg_yuv); if (p->bitstream_sw_buf) { mpp_free(p->bitstream_sw_buf); p->bitstream_sw_buf = NULL; } if (p->qp_tab_sw_buf) { mpp_free(p->qp_tab_sw_buf); p->qp_tab_sw_buf = NULL; } if (p->input_packet) { mpp_packet_deinit(&p->input_packet); } if (p->dxva_ctx) { mpp_free(p->dxva_ctx); p->dxva_ctx = NULL; } if (p->bitread_ctx) { mpp_free(p->bitread_ctx); p->bitread_ctx = NULL; } for (k = 0; k < 3; k++) { mpp_frame_deinit(&p->Framehead[k].f); } if (p) { mpp_free(p); } m2vd_dbg_func("FUN_O"); return ret; } /*! *********************************************************************** * \brief * reset *********************************************************************** */ MPP_RET m2vd_parser_reset(void *ctx) { MPP_RET ret = MPP_OK; M2VDContext *c = (M2VDContext *)ctx; M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; m2vd_dbg_func("FUN_I"); if (p->frame_cur->slot_index != 0xff) mpp_buf_slot_clr_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_CODEC_USE); if (p->frame_ref0->slot_index != 0xff) { if (p->frame_ref0->flags) { mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); p->frame_ref0->flags = 0; } mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_CODEC_USE); } if (p->frame_ref1->slot_index != 0xff) mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_CODEC_USE); if (p->input_packet) { mpp_packet_clr_eos(p->input_packet); } p->frame_cur->slot_index = 0xff; p->frame_ref0->slot_index = 0xff; p->frame_ref1->slot_index = 0xff; p->ref_frame_cnt = 0; p->resetFlag = 1; p->eos = 0; p->left_length = 0; p->vop_header_found = 0; m2vd_dbg_func("FUN_O"); return ret; } /*! *********************************************************************** * \brief * flush *********************************************************************** */ MPP_RET m2vd_parser_flush(void *ctx) { MPP_RET ret = MPP_OK; M2VDContext *c = (M2VDContext *)ctx; M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; m2vd_dbg_func("FUN_I"); if ((p->frame_ref0->slot_index != 0xff) && p->frame_ref0->flags) { mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); p->frame_ref0->flags = 0; } m2vd_dbg_func("FUN_O"); return ret; } /*! *********************************************************************** * \brief * control/perform *********************************************************************** */ MPP_RET m2vd_parser_control(void *ctx, MpiCmd cmd_type, void *param) { MPP_RET ret = MPP_OK; m2vd_dbg_func("FUN_I"); (void)ctx; (void)cmd_type; (void)param; m2vd_dbg_func("FUN_O"); return ret; } /*! *********************************************************************** * \brief * prepare *********************************************************************** */ MPP_RET mpp_m2vd_parser_split(M2VDParserContext *ctx, MppPacket dst, MppPacket src) { MPP_RET ret = MPP_NOK; M2VDParserContext *p = ctx; RK_U8 *src_buf = (RK_U8 *)mpp_packet_get_pos(src); RK_U32 src_len = (RK_U32)mpp_packet_get_length(src); RK_U32 src_eos = mpp_packet_get_eos(src); RK_U8 *dst_buf = (RK_U8 *)mpp_packet_get_data(dst); RK_U32 dst_len = (RK_U32)mpp_packet_get_length(dst); RK_U32 src_pos = 0; if (!p->vop_header_found) { if ((dst_len < sizeof(p->state)) && ((p->state & 0x00FFFFFF) == 0x000001)) { dst_buf[0] = 0; dst_buf[1] = 0; dst_buf[2] = 1; dst_len = 3; } while (src_pos < src_len) { p->state = (p->state << 8) | src_buf[src_pos]; dst_buf[dst_len++] = src_buf[src_pos++]; /* * 0x1b3 : sequence header * 0x100 : frame header * we see all 0x1b3 and 0x100 as boundary */ if (p->state == SEQUENCE_HEADER_CODE || p->state == PICTURE_START_CODE) { p->pts = mpp_packet_get_pts(src); p->vop_header_found = 1; break; } } } if (p->vop_header_found) { while (src_pos < src_len) { p->state = (p->state << 8) | src_buf[src_pos]; dst_buf[dst_len++] = src_buf[src_pos++]; if (((p->state & 0x00FFFFFF) == 0x000001) && (src_pos < src_len) && (src_buf[src_pos] == (SEQUENCE_HEADER_CODE & 0xFF) || src_buf[src_pos] == (PICTURE_START_CODE & 0xFF))) { dst_len -= 3; p->vop_header_found = 0; ret = MPP_OK; break; } } } if (src_eos && src_pos >= src_len) { mpp_packet_set_eos(dst); ret = MPP_OK; } mpp_packet_set_length(dst, dst_len); mpp_packet_set_pos(src, src_buf + src_pos); return ret; } MPP_RET m2vd_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task) { M2VDContext *c = (M2VDContext *)ctx; M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; RK_U8 *pos = NULL; size_t length = 0; RK_U32 eos = 0; if (ctx == NULL || pkt == NULL || task == NULL) { mpp_err_f("found NULL input ctx %p pkt %p task %p\n", ctx, pkt, task); return MPP_ERR_NULL_PTR; } pos = mpp_packet_get_pos(pkt); length = mpp_packet_get_length(pkt); eos = mpp_packet_get_eos(pkt); if (eos && !length && !p->left_length) { task->valid = 0; task->flags.eos = 1; m2vd_parser_flush(ctx); return MPP_OK; } if (p->bitstream_sw_buf == NULL) { mpp_err("failed to malloc task buffer for hardware with size %d\n", length); return MPP_ERR_UNKNOW; } mpp_packet_set_length(p->input_packet, p->left_length); size_t total_length = MPP_ALIGN(p->left_length + length, 16) + 64; if (total_length > p->max_stream_size) { RK_U8 *dst = NULL; do { p->max_stream_size <<= 1; } while (total_length > p->max_stream_size); dst = mpp_malloc_size(RK_U8, p->max_stream_size); mpp_assert(dst); if (p->left_length > 0) { memcpy(dst, p->bitstream_sw_buf, p->left_length); } mpp_free(p->bitstream_sw_buf); p->bitstream_sw_buf = dst; mpp_packet_set_data(p->input_packet, p->bitstream_sw_buf); mpp_packet_set_size(p->input_packet, p->max_stream_size); } if (!p->need_split) { RK_U32 *val = (RK_U32 *)mpp_packet_get_pos(pkt); /* if input data is rk format styl skip those 32 byte */ RK_S32 offset = (VPU_BITSTREAM_START_CODE == val[0]) ? 32 : 0; memcpy(p->bitstream_sw_buf, pos + offset, length - offset); mpp_packet_set_length(p->input_packet, length - offset); mpp_packet_set_data(p->input_packet, p->bitstream_sw_buf); mpp_packet_set_size(p->input_packet, p->max_stream_size); if (mpp_packet_get_eos(pkt)) mpp_packet_set_eos(p->input_packet); p->pts = mpp_packet_get_pts(pkt); task->valid = 1; mpp_packet_set_length(pkt, 0); } else { if (MPP_OK == mpp_m2vd_parser_split(p, p->input_packet, pkt)) { p->left_length = 0; task->valid = 1; } else { task->valid = 0; p->left_length = mpp_packet_get_length(p->input_packet); } } if (mpp_packet_get_flag(pkt) & MPP_PACKET_FLAG_EXTRA_DATA) { mpp_packet_set_extra_data(p->input_packet); } p->eos = mpp_packet_get_eos(p->input_packet); mpp_packet_set_pts(p->input_packet, p->pts); task->input_packet = p->input_packet; task->flags.eos = p->eos; return MPP_OK; } /*! *********************************************************************** * \brief * parser *********************************************************************** */ static RK_U32 m2vd_search_header(BitReadCtx_t *bx) { mpp_align_get_bits(bx); while (m2vd_show_bits(bx, 24) != 0x01) { mpp_skip_bits(bx, 8); if (m2vd_get_leftbits(bx) < 32) { if (M2VD_DBG_SEC_HEADER & m2vd_debug) { mpp_log("[m2v]: seach_header: str.leftbit()[%d] < 32", m2vd_get_leftbits(bx)); } return NO_MORE_STREAM; } } return m2vd_show_bits(bx, 32); } static int m2vd_decode_seq_ext_header(M2VDParserContext *ctx) { BitReadCtx_t *bx = ctx->bitread_ctx; m2vd_dbg_func("FUN_I"); ctx->MPEG2_Flag = 1; ctx->seq_ext_head.profile_and_level_indication = m2vd_read_bits(bx, 8); ctx->seq_ext_head.progressive_sequence = m2vd_read_bits(bx, 1); ctx->seq_ext_head.chroma_format = m2vd_read_bits(bx, 2); if (ctx->seq_ext_head.chroma_format != 1) return M2VD_DEC_UNSURPORT; ctx->seq_ext_head.horizontal_size_extension = m2vd_read_bits(bx, 2); ctx->seq_ext_head.vertical_size_extension = m2vd_read_bits(bx, 2); ctx->seq_ext_head.bit_rate_extension = m2vd_read_bits(bx, 12); mpp_skip_bits(bx, 1); ctx->seq_ext_head.vbv_buffer_size_extension = m2vd_read_bits(bx, 8); ctx->seq_ext_head.low_delay = m2vd_read_bits(bx, 1); ctx->seq_ext_head.frame_rate_extension_n = m2vd_read_bits(bx, 2); ctx->seq_ext_head.frame_rate_extension_d = m2vd_read_bits(bx, 5); ctx->seq_head.bit_rate_value |= (ctx->seq_ext_head.bit_rate_extension << 18); ctx->seq_head.vbv_buffer_size += (ctx->seq_ext_head.vbv_buffer_size_extension << 10); m2vd_dbg_func("FUN_O"); return M2VD_DEC_OK; } static int m2vd_decode_seqdisp_ext_header(M2VDParserContext *ctx) { BitReadCtx_t *bx = ctx->bitread_ctx; ctx->seq_disp_ext_head.video_format = m2vd_read_bits(bx, 3); ctx->seq_disp_ext_head.color_description = m2vd_read_bits(bx, 1); if (ctx->seq_disp_ext_head.color_description) { ctx->seq_disp_ext_head.color_primaries = m2vd_read_bits(bx, 8); ctx->seq_disp_ext_head.transfer_characteristics = m2vd_read_bits(bx, 8); ctx->seq_disp_ext_head.matrix_coefficients = m2vd_read_bits(bx, 8); } m2vd_read_bits(bx, 14); mpp_skip_bits(bx, 1); m2vd_read_bits(bx, 14); return M2VD_DEC_OK; } static int m2vd_decode_matrix_ext_header(M2VDParserContext *ctx) { RK_U32 load_intra_quantizer_matrix; RK_U32 load_non_intra_quantizer_matrix; RK_U32 load_chroma_intra_quantizer_matrix; RK_U32 load_chroma_non_intra_quantizer_matrix; RK_U32 i; BitReadCtx_t *bx = ctx->bitread_ctx; load_intra_quantizer_matrix = m2vd_read_bits(bx, 1); if (load_intra_quantizer_matrix) { for (i = 0; i < 64; i++) ctx->seq_head.pIntra_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); } load_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); if (load_non_intra_quantizer_matrix) { for (i = 0; i < 64; i++) ctx->seq_head.pInter_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); } load_chroma_intra_quantizer_matrix = m2vd_read_bits(bx, 1); if (load_chroma_intra_quantizer_matrix) { return M2VD_DEC_UNSURPORT; } load_chroma_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); if (load_chroma_non_intra_quantizer_matrix) { return M2VD_DEC_UNSURPORT; } return M2VD_DEC_OK; } static int m2vd_decode_scalable_ext_header(M2VDParserContext *ctx) { /* ISO/IEC 13818-2 section 6.2.2.5: sequence_scalable_extension() header */ int layer_id; int lower_layer_prediction_horizontal_size; int lower_layer_prediction_vertical_size; int horizontal_subsampling_factor_m; int horizontal_subsampling_factor_n; int vertical_subsampling_factor_m; int vertical_subsampling_factor_n; int scalable_mode; BitReadCtx_t *bx = ctx->bitread_ctx; /* scalable_mode */ #define SC_NONE 0 #define SC_DP 1 #define SC_SPAT 2 #define SC_SNR 3 #define SC_TEMP 4 scalable_mode = m2vd_read_bits(bx, 2) + 1; /* add 1 to make SC_DP != SC_NONE */ layer_id = m2vd_read_bits(bx, 4); if (scalable_mode == SC_SPAT) { lower_layer_prediction_horizontal_size = m2vd_read_bits(bx, 14); mpp_skip_bits(bx, 1); lower_layer_prediction_vertical_size = m2vd_read_bits(bx, 14); horizontal_subsampling_factor_m = m2vd_read_bits(bx, 5); horizontal_subsampling_factor_n = m2vd_read_bits(bx, 5); vertical_subsampling_factor_m = m2vd_read_bits(bx, 5); vertical_subsampling_factor_n = m2vd_read_bits(bx, 5); } (void)layer_id; (void)lower_layer_prediction_horizontal_size; (void)lower_layer_prediction_vertical_size; (void)horizontal_subsampling_factor_m; (void)horizontal_subsampling_factor_n; (void)vertical_subsampling_factor_m; (void)vertical_subsampling_factor_n; if (scalable_mode == SC_TEMP) return M2VD_DEC_UNSURPORT; else return M2VD_DEC_OK; } static int m2vd_decode_picdisp_ext_header(M2VDParserContext *ctx) { int i; int number_of_frame_center_offsets; BitReadCtx_t *bx = ctx->bitread_ctx; /* based on ISO/IEC 13818-2 section 6.3.12 (November 1994) Picture display extensions */ /* derive number_of_frame_center_offsets */ if (ctx->seq_ext_head.progressive_sequence) { if (ctx->pic_code_ext_head.repeat_first_field) { if (ctx->pic_code_ext_head.top_field_first) number_of_frame_center_offsets = 3; else number_of_frame_center_offsets = 2; } else { number_of_frame_center_offsets = 1; } } else { if (ctx->pic_code_ext_head.picture_structure != M2VD_PIC_STRUCT_FRAME) { number_of_frame_center_offsets = 1; } else { if (ctx->pic_code_ext_head.repeat_first_field) number_of_frame_center_offsets = 3; else number_of_frame_center_offsets = 2; } } /* now parse */ for (i = 0; i < number_of_frame_center_offsets; i++) { ctx->pic_disp_ext_head.frame_center_horizontal_offset[i] = m2vd_read_bits(bx, 16); mpp_skip_bits(bx, 1); ctx->pic_disp_ext_head.frame_center_vertical_offset[i] = m2vd_read_bits(bx, 16); mpp_skip_bits(bx, 1); } return M2VD_DEC_OK; } static int m2vd_decode_spatial_ext_header(M2VDParserContext *ctx) { /* ISO/IEC 13818-2 section 6.2.3.5: picture_spatial_scalable_extension() header */ int lower_layer_temporal_reference; int lower_layer_horizontal_offset; int lower_layer_vertical_offset; int spatial_temporal_weight_code_table_index; int lower_layer_progressive_frame; int lower_layer_deinterlaced_field_select; BitReadCtx_t *bx = ctx->bitread_ctx; lower_layer_temporal_reference = m2vd_read_bits(bx, 10); mpp_skip_bits(bx, 1); lower_layer_horizontal_offset = m2vd_read_bits(bx, 15); if (lower_layer_horizontal_offset >= 16384) lower_layer_horizontal_offset -= 32768; mpp_skip_bits(bx, 1); lower_layer_vertical_offset = m2vd_read_bits(bx, 15); if (lower_layer_vertical_offset >= 16384) lower_layer_vertical_offset -= 32768; spatial_temporal_weight_code_table_index = m2vd_read_bits(bx, 2); lower_layer_progressive_frame = m2vd_read_bits(bx, 1); lower_layer_deinterlaced_field_select = m2vd_read_bits(bx, 1); (void)lower_layer_temporal_reference; (void)lower_layer_vertical_offset; (void)spatial_temporal_weight_code_table_index; (void)lower_layer_progressive_frame; (void)lower_layer_deinterlaced_field_select; return M2VD_DEC_OK; } static int m2vd_decode_pic_ext_header(M2VDParserContext *ctx) { BitReadCtx_t *bx = ctx->bitread_ctx; ctx->pic_code_ext_head.f_code[0][0] = m2vd_read_bits(bx, 4); ctx->pic_code_ext_head.f_code[0][1] = m2vd_read_bits(bx, 4); ctx->pic_code_ext_head.f_code[1][0] = m2vd_read_bits(bx, 4); ctx->pic_code_ext_head.f_code[1][1] = m2vd_read_bits(bx, 4); if (ctx->MPEG2_Flag) { ctx->pic_head.full_pel_forward_vector = ctx->pic_code_ext_head.f_code[0][0]; ctx->pic_head.forward_f_code = ctx->pic_code_ext_head.f_code[0][1]; ctx->pic_head.full_pel_backward_vector = ctx->pic_code_ext_head.f_code[1][0]; ctx->pic_head.backward_f_code = ctx->pic_code_ext_head.f_code[1][1]; } ctx->pic_code_ext_head.intra_dc_precision = m2vd_read_bits(bx, 2); ctx->pic_code_ext_head.picture_structure = m2vd_read_bits(bx, 2); if (ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) ctx->pic_code_ext_head.top_field_first = m2vd_read_bits(bx, 1); else { m2vd_read_bits(bx, 1); if ((ctx->pic_head.pre_picture_coding_type != ctx->pic_head.picture_coding_type) && (ctx->pic_head.pre_picture_coding_type != M2VD_CODING_TYPE_I)) { if (ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) ctx->top_first_cnt++; else ctx->bottom_first_cnt++; } if (ctx->top_first_cnt >= ctx->bottom_first_cnt) ctx->pic_code_ext_head.top_field_first = 1; else ctx->pic_code_ext_head.top_field_first = 0; } ctx->pic_code_ext_head.frame_pred_frame_dct = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.concealment_motion_vectors = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.q_scale_type = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.intra_vlc_format = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.alternate_scan = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.repeat_first_field = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.chroma_420_type = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.progressive_frame = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.composite_display_flag = m2vd_read_bits(bx, 1); if (ctx->pic_code_ext_head.composite_display_flag) { ctx->pic_code_ext_head.v_axis = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.field_sequence = m2vd_read_bits(bx, 3); ctx->pic_code_ext_head.sub_carrier = m2vd_read_bits(bx, 1); ctx->pic_code_ext_head.burst_amplitude = m2vd_read_bits(bx, 7); ctx->pic_code_ext_head.sub_carrier_phase = m2vd_read_bits(bx, 8); } return M2VD_DEC_OK; } static inline int m2vd_decode_temp_ext_header(void) { return M2VD_DEC_UNSURPORT; } static int m2vd_decode_copyright_ext_header(M2VDParserContext *ctx) { int copyright_flag; int copyright_identifier; int original_or_copy; int copyright_number_1; int copyright_number_2; int copyright_number_3; int reserved_data; BitReadCtx_t *bx = ctx->bitread_ctx; copyright_flag = m2vd_read_bits(bx, 1); copyright_identifier = m2vd_read_bits(bx, 8); original_or_copy = m2vd_read_bits(bx, 1); /* reserved */ reserved_data = m2vd_read_bits(bx, 7); mpp_skip_bits(bx, 1); copyright_number_1 = m2vd_read_bits(bx, 20); mpp_skip_bits(bx, 1); copyright_number_2 = m2vd_read_bits(bx, 22); mpp_skip_bits(bx, 1); copyright_number_3 = m2vd_read_bits(bx, 22); (void)copyright_flag; (void)copyright_identifier; (void)original_or_copy; (void)copyright_number_1; (void)copyright_number_2; (void)copyright_number_3; (void)reserved_data; return M2VD_DEC_OK; } static int m2vd_decode_ext_header(M2VDParserContext *ctx) { RK_U32 code; RK_U32 ext_ID; int result; BitReadCtx_t *bx = ctx->bitread_ctx; code = m2vd_search_header(bx); if (M2VD_DBG_SEC_HEADER & m2vd_debug) { mpp_log("[m2v]: decoder_ext_header : seach_header return code: %#03x", code); } while (code == EXTENSION_START_CODE || code == USER_DATA_START_CODE) { if (code == EXTENSION_START_CODE) { mpp_skip_bits(bx, 32); ext_ID = m2vd_read_bits(bx, 4); if (M2VD_DBG_SEC_HEADER & m2vd_debug) { mpp_log("[m2v]: decoder_ext_header : ext_ID: %d", ext_ID); } switch (ext_ID) { case SEQUENCE_EXTENSION_ID: result = m2vd_decode_seq_ext_header(ctx); break; case SEQUENCE_DISPLAY_EXTENSION_ID: result = m2vd_decode_seqdisp_ext_header(ctx); break; case QUANT_MATRIX_EXTENSION_ID: result = m2vd_decode_matrix_ext_header(ctx); break; case SEQUENCE_SCALABLE_EXTENSION_ID: result = m2vd_decode_scalable_ext_header(ctx); break; case PICTURE_DISPLAY_EXTENSION_ID: result = m2vd_decode_picdisp_ext_header(ctx); break; case PICTURE_CODING_EXTENSION_ID: result = m2vd_decode_pic_ext_header(ctx); break; case PICTURE_SPATIAL_SCALABLE_EXTENSION_ID: result = m2vd_decode_spatial_ext_header(ctx); break; case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID: result = m2vd_decode_temp_ext_header(); break; case COPYRIGHT_EXTENSION_ID: result = m2vd_decode_copyright_ext_header(ctx); break; case NO_MORE_STREAM: break; default: break; } if (M2VD_DBG_SEC_HEADER & m2vd_debug) { mpp_log("[m2v]: decoder_ext_header result: %d", result); } if (result) return result; } else { mpp_skip_bits(bx, 32); } code = m2vd_search_header(bx); } return MPP_OK; } static int m2vd_decode_gop_header(M2VDParserContext *ctx) { BitReadCtx_t *bx = ctx->bitread_ctx; ctx->gop_head.drop_flag = m2vd_read_bits(bx, 1); ctx->gop_head.hour = m2vd_read_bits(bx, 5); ctx->gop_head.minute = m2vd_read_bits(bx, 6); mpp_skip_bits(bx, 1); ctx->gop_head.sec = m2vd_read_bits(bx, 6); ctx->gop_head.frame = m2vd_read_bits(bx, 6); ctx->gop_head.closed_gop = m2vd_read_bits(bx, 1); ctx->gop_head.broken_link = m2vd_read_bits(bx, 1); return m2vd_decode_ext_header(ctx); } static int m2vd_decode_seq_header(M2VDParserContext *ctx) { RK_U32 i; BitReadCtx_t *bx = ctx->bitread_ctx; ctx->seq_head.decode_width = m2vd_read_bits(bx, 12); ctx->seq_head.decode_height = m2vd_read_bits(bx, 12); ctx->display_width = ctx->seq_head.decode_width; ctx->display_height = ctx->seq_head.decode_height; ctx->seq_head.aspect_ratio_information = m2vd_read_bits(bx, 4); ctx->seq_head.frame_rate_code = m2vd_read_bits(bx, 4); if (!ctx->frame_period) ctx->frame_period = frame_period_Table[ctx->seq_head.frame_rate_code]; ctx->seq_head.bit_rate_value = m2vd_read_bits(bx, 18); mpp_skip_bits(bx, 1); ctx->seq_head.vbv_buffer_size = m2vd_read_bits(bx, 10); ctx->seq_head.constrained_parameters_flag = m2vd_read_bits(bx, 1); ctx->seq_head.load_intra_quantizer_matrix = m2vd_read_bits(bx, 1); if (ctx->seq_head.load_intra_quantizer_matrix) { for (i = 0; i < 64; i++) ctx->seq_head.pIntra_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); } else { for (i = 0; i < 64; i++) ctx->seq_head.pIntra_table[i] = intraDefaultQMatrix[i]; } ctx->seq_head.load_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); if (ctx->seq_head.load_non_intra_quantizer_matrix) { for (i = 0; i < 64; i++) ctx->seq_head.pInter_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); } else { for (i = 0; i < 64; i++) ctx->seq_head.pInter_table[i] = 16; } return m2vd_decode_ext_header(ctx); } static int m2vd_extra_bit_information(M2VDParserContext *ctx) { BitReadCtx_t *bx = ctx->bitread_ctx; while (m2vd_read_bits(bx, 1)) { mpp_skip_bits(bx, 8); } return M2VD_DEC_OK; } static int m2vd_decode_pic_header(M2VDParserContext *ctx) { BitReadCtx_t *bx = ctx->bitread_ctx; ctx->pic_head.temporal_reference = m2vd_read_bits(bx, 10); ctx->pic_head.picture_coding_type = m2vd_read_bits(bx, 3); ctx->pic_head.vbv_delay = m2vd_read_bits(bx, 16); if (ctx->pic_head.temporal_reference > 50) { ctx->pic_head.temporal_reference = ctx->pretemporal_reference; } //if ((maxFrame_inGOP < temporal_reference)&&(temporal_reference<60)) // maxFrame_inGOP = temporal_reference; if (((RK_S32)ctx->maxFrame_inGOP < ctx->pic_head.temporal_reference) && (ctx->pic_head.temporal_reference < 60)) ctx->maxFrame_inGOP = ctx->pic_head.temporal_reference; if (ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_P || ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { ctx->pic_head.full_pel_forward_vector = m2vd_read_bits(bx, 1); ctx->pic_head.forward_f_code = m2vd_read_bits(bx, 3); } if (ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { ctx->pic_head.full_pel_backward_vector = m2vd_read_bits(bx, 1); ctx->pic_head.backward_f_code = m2vd_read_bits(bx, 3); } m2vd_extra_bit_information(ctx); return m2vd_decode_ext_header(ctx); } static MPP_RET m2vd_decode_head(M2VDParserContext *ctx) { RK_U32 code; int ret = 0; BitReadCtx_t *bx = ctx->bitread_ctx; m2vd_dbg_func("FUN_I"); while (1) { code = m2vd_search_header(bx); if (M2VD_DBG_SEC_HEADER & m2vd_debug) { mpp_log("[m2v]: decoder_header : seach_header return code: 0x%3x", code); } if (code == NO_MORE_STREAM) return M2VD_DEC_FILE_END; code = m2vd_read_bits(bx, 32); switch (code) { case SEQUENCE_HEADER_CODE: ret = m2vd_decode_seq_header(ctx); if (!ret) { MppPacket pkt = ctx->input_packet; if (mpp_packet_get_flag(pkt) & MPP_PACKET_FLAG_EXTRA_DATA) { ctx->mExtraHeaderDecFlag = 1; } else { ctx->mHeaderDecFlag = 1; } } break; case GROUP_START_CODE: ret = m2vd_decode_gop_header(ctx); break; case PICTURE_START_CODE: ret = m2vd_decode_pic_header(ctx); ret = M2VD_DEC_PICHEAD_OK; break; case SEQUENCE_END_CODE: ret = M2VD_DEC_STREAM_END; break; default: if (M2VD_DBG_SEC_HEADER & m2vd_debug) { mpp_log("code=%x,leftbit=%d", code, m2vd_get_leftbits(bx)); } break; } if (ret) break; } m2vd_dbg_func("FUN_O"); return ret; } static MPP_RET m2vd_alloc_frame(M2VDParserContext *ctx) { RK_U64 pts = ctx->pts; if (ctx->resetFlag && ctx->pic_head.picture_coding_type != M2VD_CODING_TYPE_I) { mpp_log("[m2v]: resetFlag[%d] && picture_coding_type[%d] != I_TYPE", ctx->resetFlag, ctx->pic_head.picture_coding_type); return MPP_NOK; } else { ctx->resetFlag = 0; } if ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME ) || ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && ctx->pic_code_ext_head.top_field_first) || ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && (!ctx->pic_code_ext_head.top_field_first)) || (ctx->frame_cur->slot_index == 0xff)) { RK_S64 Time = 0; if (ctx->PreGetFrameTime != pts) { RK_S64 tmp_frame_period; if (ctx->GroupFrameCnt) { ctx->GroupFrameCnt = ctx->GroupFrameCnt + ctx->pic_head.temporal_reference; } else if (ctx->pic_head.temporal_reference == (RK_S32)ctx->PreChangeTime_index) ctx->GroupFrameCnt = ctx->max_temporal_reference + 1; else if (ctx->pic_head.temporal_reference) ctx->GroupFrameCnt = ctx->pic_head.temporal_reference - ctx->PreChangeTime_index; else ctx->GroupFrameCnt = ctx->max_temporal_reference - ctx->PreChangeTime_index + 1; tmp_frame_period = pts - ctx->PreGetFrameTime; if ((pts > ctx->PreGetFrameTime) && (ctx->pic_head.temporal_reference > (RK_S32)ctx->PreChangeTime_index)) { RK_S32 theshold_frame_period = tmp_frame_period * 2 ; RK_S32 last_frame_period = ctx->preframe_period ? ctx->preframe_period : ctx->frame_period; RK_S32 predict_frame_period = (ctx->pic_head.temporal_reference - ctx->PreChangeTime_index) * last_frame_period / 256; if (theshold_frame_period < predict_frame_period) { pts = ctx->PreGetFrameTime + predict_frame_period; tmp_frame_period = predict_frame_period; } } if ((pts > ctx->PreGetFrameTime) && (ctx->GroupFrameCnt > 0)) { tmp_frame_period = (tmp_frame_period * 256) / ctx->GroupFrameCnt; if ((tmp_frame_period > 4200) && (tmp_frame_period < 11200) && (llabs(ctx->frame_period - tmp_frame_period) > 128)) { if (llabs(ctx->preframe_period - tmp_frame_period) > 128) ctx->preframe_period = tmp_frame_period; else ctx->frame_period = tmp_frame_period; } } ctx->Group_start_Time = pts - (ctx->pic_head.temporal_reference * ctx->frame_period / 256); if (ctx->Group_start_Time < 0) ctx->Group_start_Time = 0; ctx->PreGetFrameTime = pts; ctx->PreChangeTime_index = ctx->pic_head.temporal_reference; ctx->GroupFrameCnt = 0; } else if ((RK_S32)ctx->pretemporal_reference > ctx->pic_head.temporal_reference + 5) { ctx->Group_start_Time += ((ctx->max_temporal_reference + 1) * ctx->frame_period / 256); ctx->GroupFrameCnt = ctx->max_temporal_reference - ctx->PreChangeTime_index + 1; ctx->max_temporal_reference = 0; } if ((RK_S32)ctx->pretemporal_reference > ctx->pic_head.temporal_reference + 5) ctx->max_temporal_reference = 0; if (ctx->pic_head.temporal_reference > (RK_S32)ctx->max_temporal_reference) ctx->max_temporal_reference = ctx->pic_head.temporal_reference; ctx->pretemporal_reference = ctx->pic_head.temporal_reference; /*if(picture_coding_type == I_TYPE) { if (Video_Bitsream.Slice_Time.low_part >= (RK_U32)(frame_period/128)) Group_start_Time = Video_Bitsream.Slice_Time.low_part - (RK_U32)(frame_period/128); else Group_start_Time = Video_Bitsream.Slice_Time.low_part; }*/ Time = ctx->Group_start_Time; Time += ((ctx->pic_head.temporal_reference * ctx->frame_period) / 256); if (Time < 0) { Time = 0; } //base.Current_frame->ShowTime = Time;//Video_Bitsream.Slice_Time.low_part; //!< mark current slot error if (ctx->pic_head.picture_coding_type != M2VD_CODING_TYPE_I && ctx->pic_head.pre_picture_coding_type == ctx->pic_head.picture_coding_type) { if ((ctx->pic_head.temporal_reference - ctx->pic_head.pre_temporal_reference > 3) || (ctx->pic_head.temporal_reference - ctx->pic_head.pre_temporal_reference < -3)) { mpp_frame_set_errinfo(ctx->frame_cur->f, 1); } else { mpp_frame_set_errinfo(ctx->frame_cur->f, 0); } } ctx->pic_head.pre_temporal_reference = ctx->pic_head.temporal_reference; ctx->pic_head.pre_picture_coding_type = ctx->pic_head.picture_coding_type; ctx->frame_cur->picCodingType = ctx->pic_head.picture_coding_type; ctx->seq_head.decode_height = (ctx->seq_head.decode_height + 15) & (~15); ctx->seq_head.decode_width = (ctx->seq_head.decode_width + 15) & (~15); if ((ctx->ref_frame_cnt < 2) && (ctx->frame_cur->picCodingType == M2VD_CODING_TYPE_B)) { // not enough refs on B-type need cal pts and parser ctx but not need to decode mpp_log("[m2v]: (ref_frame_cnt[%d] < 2) && (frame_cur->picCodingType[%d] == B_TYPE)", ctx->ref_frame_cnt, ctx->frame_cur->picCodingType); return MPP_NOK; } if (ctx->frame_cur->slot_index == 0xff) { RK_U32 frametype = 0; mpp_frame_set_width(ctx->frame_cur->f, ctx->display_width); mpp_frame_set_height(ctx->frame_cur->f, ctx->display_height); mpp_frame_set_hor_stride(ctx->frame_cur->f, ctx->display_width); mpp_frame_set_ver_stride(ctx->frame_cur->f, ctx->display_height); mpp_frame_set_errinfo(ctx->frame_cur->f, 0); mpp_frame_set_pts(ctx->frame_cur->f, Time); ctx->frame_cur->flags = M2V_OUT_FLAG; if (ctx->seq_ext_head.progressive_sequence) { frametype = MPP_FRAME_FLAG_FRAME; } else { frametype = MPP_FRAME_FLAG_PAIRED_FIELD; if (ctx->pic_code_ext_head.top_field_first) frametype |= MPP_FRAME_FLAG_TOP_FIRST; else frametype |= MPP_FRAME_FLAG_BOT_FIRST; } mpp_frame_set_mode(ctx->frame_cur->f, frametype); if (ctx->seq_head.aspect_ratio_information >= 0 && ctx->seq_head.aspect_ratio_information < 16) mpp_frame_set_sar(ctx->frame_cur->f, mpeg2_aspect[ctx->seq_head.aspect_ratio_information]); mpp_buf_slot_get_unused(ctx->frame_slots, &ctx->frame_cur->slot_index); mpp_buf_slot_set_prop(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_FRAME, ctx->frame_cur->f); mpp_buf_slot_set_flag(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_CODEC_USE); mpp_buf_slot_set_flag(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_HAL_OUTPUT); } } //alloc frame space if ((ctx->ref_frame_cnt < 2) && (ctx->frame_cur->picCodingType == M2VD_CODING_TYPE_B)) { mpp_log("[m2v]: (ref_frame_cnt[%d] < 2) && (frame_cur->picCodingType[%d] == B_TYPE)", ctx->ref_frame_cnt, ctx->frame_cur->picCodingType); return MPP_NOK; } return MPP_OK; } static MPP_RET m2v_update_ref_frame(M2VDParserContext *p) { MPP_RET ret = MPP_OK; m2vd_dbg_func("FUN_I"); //push frame if ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) || ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && p->pic_code_ext_head.top_field_first ) || ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && (!p->pic_code_ext_head.top_field_first))) { if (p->frame_cur->picCodingType == M2VD_CODING_TYPE_B) { mpp_buf_slot_set_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_QUEUE_USE); mpp_buf_slot_enqueue(p->frame_slots, p->frame_cur->slot_index, QUEUE_DISPLAY); mpp_buf_slot_clr_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_CODEC_USE); p->frame_cur->slot_index = 0xFF; } else if (p->frame_cur->picCodingType != 0xffffffff) { M2VDFrameHead *tmpHD = NULL; p->ref_frame_cnt++; if (p->frame_ref0->slot_index < 0x7f) { if (p->frame_ref0->flags) { mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); p->frame_ref0->flags = 0; } } if (p->frame_ref1->slot_index < 0x7f) { mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_CODEC_USE); p->frame_ref1->slot_index = 0xff; } tmpHD = p->frame_ref1; p->frame_ref1 = p->frame_ref0; p->frame_ref0 = p->frame_cur; p->frame_cur = tmpHD; } } return ret; } static MPP_RET m2vd_convert_to_dxva(M2VDParserContext *p) { MPP_RET ret = MPP_OK; m2vd_dbg_func("FUN_I"); M2VDDxvaParam *dst = p->dxva_ctx; M2VDFrameHead *pfw = p->frame_ref1; M2VDFrameHead *pbw = p->frame_ref0; BitReadCtx_t *bx = p->bitread_ctx; RK_U32 i = 0; RK_U32 error_info = 0; RK_S32 readbits = m2vd_get_readbits(bx); dst->seq.decode_width = p->seq_head.decode_width; dst->seq.decode_height = p->seq_head.decode_height; dst->seq.aspect_ratio_information = p->seq_head.aspect_ratio_information; dst->seq.frame_rate_code = p->seq_head.frame_rate_code; dst->seq.bit_rate_value = p->seq_head.bit_rate_value; dst->seq.vbv_buffer_size = p->seq_head.vbv_buffer_size; dst->seq.constrained_parameters_flag = p->seq_head.constrained_parameters_flag; dst->seq.load_intra_quantizer_matrix = p->seq_head.load_intra_quantizer_matrix; dst->seq.load_non_intra_quantizer_matrix = p->seq_head.load_non_intra_quantizer_matrix; dst->seq_ext.profile_and_level_indication = p->seq_ext_head.profile_and_level_indication; dst->seq_ext.progressive_sequence = p->seq_ext_head.progressive_sequence; dst->seq_ext.chroma_format = p->seq_ext_head.chroma_format; dst->seq_ext.low_delay = p->seq_ext_head.low_delay; dst->seq_ext.frame_rate_extension_n = p->seq_ext_head.frame_rate_extension_n; dst->seq_ext.frame_rate_extension_d = p->seq_ext_head.frame_rate_extension_d; dst->gop.drop_flag = p->gop_head.drop_flag; dst->gop.hour = p->gop_head.hour; dst->gop.minute = p->gop_head.minute; dst->gop.sec = p->gop_head.sec; dst->gop.frame = p->gop_head.frame; dst->gop.closed_gop = p->gop_head.closed_gop; dst->gop.broken_link = p->gop_head.broken_link; dst->pic.temporal_reference = p->pic_head.temporal_reference; dst->pic.picture_coding_type = p->pic_head.picture_coding_type; dst->pic.pre_picture_coding_type = p->pic_head.pre_picture_coding_type; dst->pic.vbv_delay = p->pic_head.vbv_delay; dst->pic.full_pel_forward_vector = p->pic_head.full_pel_forward_vector; dst->pic.forward_f_code = p->pic_head.forward_f_code; dst->pic.full_pel_backward_vector = p->pic_head.full_pel_backward_vector; dst->pic.backward_f_code = p->pic_head.backward_f_code; dst->pic.pre_temporal_reference = p->pic_head.pre_temporal_reference; dst->seq_disp_ext.video_format = p->seq_disp_ext_head.video_format; dst->seq_disp_ext.color_description = p->seq_disp_ext_head.color_description; dst->seq_disp_ext.color_primaries = p->seq_disp_ext_head.color_primaries; dst->seq_disp_ext.transfer_characteristics = p->seq_disp_ext_head.transfer_characteristics; dst->seq_disp_ext.matrix_coefficients = p->seq_disp_ext_head.matrix_coefficients; memcpy(dst->pic_code_ext.f_code, p->pic_code_ext_head.f_code, 2 * 2 * sizeof(RK_S32)); dst->pic_code_ext.intra_dc_precision = p->pic_code_ext_head.intra_dc_precision; dst->pic_code_ext.picture_structure = p->pic_code_ext_head.picture_structure; dst->pic_code_ext.top_field_first = p->pic_code_ext_head.top_field_first; dst->pic_code_ext.frame_pred_frame_dct = p->pic_code_ext_head.frame_pred_frame_dct; dst->pic_code_ext.concealment_motion_vectors = p->pic_code_ext_head.concealment_motion_vectors; dst->pic_code_ext.q_scale_type = p->pic_code_ext_head.q_scale_type; dst->pic_code_ext.intra_vlc_format = p->pic_code_ext_head.intra_vlc_format; dst->pic_code_ext.alternate_scan = p->pic_code_ext_head.alternate_scan; dst->pic_code_ext.repeat_first_field = p->pic_code_ext_head.repeat_first_field; dst->pic_code_ext.chroma_420_type = p->pic_code_ext_head.chroma_420_type; dst->pic_code_ext.progressive_frame = p->pic_code_ext_head.progressive_frame; dst->pic_code_ext.composite_display_flag = p->pic_code_ext_head.composite_display_flag; dst->pic_code_ext.v_axis = p->pic_code_ext_head.v_axis; dst->pic_code_ext.field_sequence = p->pic_code_ext_head.field_sequence; dst->pic_code_ext.sub_carrier = p->pic_code_ext_head.sub_carrier; dst->pic_code_ext.burst_amplitude = p->pic_code_ext_head.burst_amplitude; dst->pic_code_ext.sub_carrier_phase = p->pic_code_ext_head.sub_carrier_phase; memcpy(dst->pic_disp_ext.frame_center_horizontal_offset, p->pic_disp_ext_head.frame_center_horizontal_offset, 3 * sizeof(RK_S32)); memcpy(dst->pic_disp_ext.frame_center_vertical_offset, p->pic_disp_ext_head.frame_center_vertical_offset, 3 * sizeof(RK_S32)); dst->bitstream_length = p->frame_size - ((readbits >> 3) & (~7)); dst->bitstream_offset = ((readbits >> 3) & (~7)); dst->bitstream_start_bit = readbits & 0x3f; dst->qp_tab = p->qp_tab_sw_buf; dst->CurrPic.Index7Bits = p->frame_cur->slot_index; p->cur_slot_index = p->frame_cur->slot_index; if (p->frame_ref0->slot_index == 0xff) { pbw = p->frame_cur; } if (p->frame_ref1->slot_index == 0xff) { pfw = pbw; } for (i = 0; i < 4; i++) { dst->frame_refs[i].bPicEntry = 0xff; } if (p->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { MppFrame frame0 = NULL; MppFrame frame1 = NULL; dst->frame_refs[0].Index7Bits = pfw->slot_index; dst->frame_refs[1].Index7Bits = pfw->slot_index; dst->frame_refs[2].Index7Bits = pbw->slot_index; dst->frame_refs[3].Index7Bits = pbw->slot_index; mpp_buf_slot_get_prop(p->frame_slots, pfw->slot_index, SLOT_FRAME_PTR, &frame0); mpp_buf_slot_get_prop(p->frame_slots, pbw->slot_index, SLOT_FRAME_PTR, &frame1); error_info = mpp_frame_get_errinfo(frame0) | mpp_frame_get_errinfo(frame1); } else { MppFrame frame = NULL; if ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) || ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && p->pic_code_ext_head.top_field_first) || ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && (!p->pic_code_ext_head.top_field_first))) { dst->frame_refs[0].Index7Bits = pbw->slot_index; dst->frame_refs[1].Index7Bits = pbw->slot_index; } else if (p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) { dst->frame_refs[0].Index7Bits = pbw->slot_index; dst->frame_refs[1].Index7Bits = p->frame_cur->slot_index; } else if (p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) { dst->frame_refs[0].Index7Bits = p->frame_cur->slot_index; dst->frame_refs[1].Index7Bits = pbw->slot_index; } dst->frame_refs[2].Index7Bits = p->frame_cur->slot_index; dst->frame_refs[3].Index7Bits = p->frame_cur->slot_index; mpp_buf_slot_get_prop(p->frame_slots, pbw->slot_index, SLOT_FRAME_PTR, &frame); error_info = mpp_frame_get_errinfo(frame); } if (p->frame_cur->picCodingType == M2VD_CODING_TYPE_I) { error_info = 0; } dst->seq_ext_head_dec_flag = p->MPEG2_Flag; { MppFrame frame = NULL; mpp_buf_slot_get_prop(p->frame_slots, p->cur_slot_index, SLOT_FRAME_PTR, &frame); mpp_frame_set_errinfo(frame, error_info); } m2vd_dbg_func("FUN_O"); return ret; } MPP_RET m2vd_parser_parse(void *ctx, HalDecTask *in_task) { MPP_RET ret = MPP_OK; int rev = 0; M2VDContext *c = (M2VDContext *)ctx; M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; m2vd_dbg_func("FUN_I"); M2VD_CHK_I(in_task->valid); in_task->valid = 0; p->flush_dpb_eos = 0; p->frame_size = (RK_U32)mpp_packet_get_length(in_task->input_packet); mpp_set_bitread_ctx(p->bitread_ctx, p->bitstream_sw_buf, p->frame_size); rev = m2vd_decode_head(p); if (!p->mHeaderDecFlag) { if (p->mExtraHeaderDecFlag && p->pic_head.picture_coding_type == M2VD_CODING_TYPE_I) { p->mHeaderDecFlag = 1; if (M2VD_DBG_SEC_HEADER & m2vd_debug) mpp_log("[m2v]: use extra data sequence header"); } else { if (M2VD_DBG_SEC_HEADER & m2vd_debug) mpp_log("[m2v]: !mHeaderDecFlag"); goto __FAILED; } } p->mb_width = (p->seq_head.decode_width + 15) >> 4; p->mb_height = (p->seq_head.decode_height + 15) >> 4; if (rev < M2VD_DEC_OK) { if (M2VD_DBG_SEC_HEADER & m2vd_debug) { mpp_log("decoder_header error rev %d", rev); } goto __FAILED; } if (rev == M2VD_DEC_PICHEAD_OK) { if (MPP_OK != m2vd_alloc_frame(p)) { mpp_err("m2vd_alloc_frame not OK"); goto __FAILED; } m2vd_convert_to_dxva(p); in_task->syntax.data = (void *)p->dxva_ctx; in_task->syntax.number = sizeof(M2VDDxvaParam); in_task->output = p->frame_cur->slot_index; p->pic_head.pre_picture_coding_type = p->pic_head.picture_coding_type; if (p->frame_ref0->slot_index < 0x7f && (p->frame_ref0->slot_index != p->frame_cur->slot_index)) { mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_HAL_INPUT); in_task->refer[0] = p->frame_ref0->slot_index; } if (p->frame_ref1->slot_index < 0x7f && (p->frame_ref1->slot_index != p->frame_cur->slot_index)) { mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_HAL_INPUT); in_task->refer[1] = p->frame_ref1->slot_index; } MppFrame frame = NULL; mpp_buf_slot_get_prop(p->frame_slots, p->cur_slot_index, SLOT_FRAME_PTR, &frame); mpp_frame_set_poc(frame, p->pic_head.temporal_reference); if (p->dxva_ctx->seq_disp_ext.color_description) { mpp_frame_set_color_primaries(frame, p->dxva_ctx->seq_disp_ext.color_primaries); mpp_frame_set_color_trc(frame, p->dxva_ctx->seq_disp_ext.transfer_characteristics); mpp_frame_set_colorspace(frame, p->dxva_ctx->seq_disp_ext.matrix_coefficients); } else { mpp_frame_set_color_primaries(frame, MPP_FRAME_PRI_UNSPECIFIED); mpp_frame_set_color_trc(frame, MPP_FRAME_TRC_UNSPECIFIED); mpp_frame_set_colorspace(frame, MPP_FRAME_SPC_UNSPECIFIED); } in_task->valid = 1; m2v_update_ref_frame(p); } __FAILED: if (p->eos) { m2vd_parser_flush(ctx); } m2vd_dbg_func("FUN_O"); return ret; } MPP_RET m2vd_parser_callback(void *ctx, void *errinfo) { MPP_RET ret = MPP_OK; M2VDContext *c = (M2VDContext *)ctx; M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; MppFrame frame = NULL; (void)errinfo; m2vd_dbg_func("FUN_I"); mpp_buf_slot_get_prop(p->frame_slots, p->cur_slot_index, SLOT_FRAME_PTR, &frame); mpp_frame_set_errinfo(frame, 1); m2vd_dbg_func("FUN_O"); return ret; }