diff --git a/inc/vpu.h b/inc/vpu.h index 9335b3b3..5ba35795 100644 --- a/inc/vpu.h +++ b/inc/vpu.h @@ -47,7 +47,7 @@ typedef enum { VPU_DEC_HEVC = 0x4, VPU_DEC_RKV = 0x5, VPU_ENC_RKV = 0x6, - VPU_DEC_AVS = 0x7, + VPU_DEC_AVSPLUS = 0x7, VPU_ENC_VEPU22 = 0x8, VPU_TYPE_BUTT , } VPU_CLIENT_TYPE; diff --git a/inc/vpu_api.h b/inc/vpu_api.h index 3b4f159e..fc9c9417 100644 --- a/inc/vpu_api.h +++ b/inc/vpu_api.h @@ -240,7 +240,8 @@ typedef enum OMX_RK_VIDEO_CODINGTYPE { OMX_RK_VIDEO_CodingDIVX3, /**< DIVX3 */ OMX_RK_VIDEO_CodingVP6, OMX_RK_VIDEO_CodingHEVC, /**< H.265/HEVC */ - OMX_RK_VIDEO_CodingAVS, /**< AVS+ */ + OMX_RK_VIDEO_CodingAVSPLUS, /**< AVS+ profile 0x48 */ + OMX_RK_VIDEO_CodingAVS, /**< AVS profile 0x20 */ OMX_RK_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ OMX_RK_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ OMX_RK_VIDEO_CodingMax = 0x7FFFFFFF diff --git a/mpp/codec/dec/avs/avsd_api.c b/mpp/codec/dec/avs/avsd_api.c index ec4be288..b087265e 100644 --- a/mpp/codec/dec/avs/avsd_api.c +++ b/mpp/codec/dec/avs/avsd_api.c @@ -1,19 +1,18 @@ /* -* -* 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. -*/ + * 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 "avsd_api" @@ -49,8 +48,7 @@ MPP_RET avsd_deinit(void *decoder) AVSD_PARSE_TRACE("In."); mpp_packet_deinit(&p_dec->task_pkt); - MPP_FREE(p_dec->p_stream->pbuf); - MPP_FREE(p_dec->p_header->pbuf); + MPP_FREE(p_dec->streambuf); MPP_FREE(p_dec->mem); __RETURN: @@ -85,24 +83,25 @@ MPP_RET avsd_init(void *decoder, ParserCfg *init) mpp_buf_slot_setup(p_dec->frame_slots, 12); p_dec->mem = mpp_calloc(AvsdMemory_t, 1); MEM_CHECK(ret, p_dec->mem); - p_dec->p_header = &p_dec->mem->headerbuf; - p_dec->p_header->size = MAX_HEADER_SIZE; - p_dec->p_header->pbuf = mpp_malloc(RK_U8, p_dec->p_header->size); - MEM_CHECK(ret, p_dec->p_header->pbuf); p_dec->syn = &p_dec->mem->syntax; - p_dec->p_stream = &p_dec->mem->streambuf; - p_dec->p_stream->size = MAX_STREAM_SIZE; - p_dec->p_stream->pbuf = mpp_malloc(RK_U8, p_dec->p_stream->size); - MEM_CHECK(ret, p_dec->p_stream->pbuf); - mpp_packet_init(&p_dec->task_pkt, p_dec->p_stream->pbuf, p_dec->p_stream->size); + p_dec->stream_size = MAX_STREAM_SIZE; + p_dec->streambuf = mpp_malloc(RK_U8, p_dec->stream_size); + MEM_CHECK(ret, p_dec->streambuf); + mpp_packet_init(&p_dec->task_pkt, p_dec->streambuf, p_dec->stream_size); mpp_packet_set_length(p_dec->task_pkt, 0); MEM_CHECK(ret, p_dec->task_pkt); for (i = 0; i < 3; i++) { - memset(&p_dec->mem->save[i], 0, sizeof(AvsdFrame_t)); - p_dec->mem->save[i].slot_idx = -1; + AvsdFrame_t *frm = &p_dec->mem->save[i]; + + memset(frm, 0, sizeof(*frm)); + frm->idx = i; + frm->slot_idx = -1; } + p_dec->bx = &p_dec->mem->bitctx; + p_dec->need_split = 1; + __RETURN: AVSD_PARSE_TRACE("Out."); return ret = MPP_OK; @@ -125,12 +124,20 @@ MPP_RET avsd_reset(void *decoder) AVSD_PARSE_TRACE("In."); avsd_reset_parameters(p_dec); + p_dec->got_vsh = 0; + p_dec->got_ph = 0; p_dec->got_keyframe = 0; p_dec->vec_flag = 0; + p_dec->got_eos = 0; + p_dec->left_length = 0; + p_dec->state = 0xFFFFFFFF; + p_dec->vop_header_found = 0; + + mpp_packet_set_length(p_dec->task_pkt, 0); + mpp_packet_set_flag(p_dec->task_pkt, 0); AVSD_PARSE_TRACE("Out."); - (void)p_dec; - (void)decoder; + return ret = MPP_OK; } @@ -149,6 +156,10 @@ MPP_RET avsd_flush(void *decoder) avsd_reset_parameters(p_dec); p_dec->got_keyframe = 0; p_dec->vec_flag = 0; + p_dec->got_eos = 0; + p_dec->left_length = 0; + p_dec->state = 0xFFFFFFFF; + p_dec->vop_header_found = 0; AVSD_PARSE_TRACE("Out."); (void)p_dec; @@ -165,13 +176,18 @@ MPP_RET avsd_flush(void *decoder) MPP_RET avsd_control(void *decoder, MpiCmd cmd_type, void *param) { MPP_RET ret = MPP_ERR_UNKNOW; + AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder; AVSD_PARSE_TRACE("In."); + switch (cmd_type) { + case MPP_DEC_SET_DISABLE_ERROR: { + p_dec->disable_error = *((RK_U32 *)param); + } break; + default : { + } break; + } - (void)decoder; - (void)cmd_type; - (void)param; AVSD_PARSE_TRACE("Out."); return ret = MPP_OK; } @@ -186,77 +202,95 @@ MPP_RET avsd_control(void *decoder, MpiCmd cmd_type, void *param) MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task) { MPP_RET ret = MPP_ERR_UNKNOW; - AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder; AVSD_PARSE_TRACE("In."); INP_CHECK(ret, !decoder && !pkt && !task); - if (p_dec->has_get_eos - || (mpp_packet_get_flag(pkt) & MPP_PACKET_FLAG_EXTRA_DATA)) { + AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder; + RK_U8 *pos = mpp_packet_get_pos(pkt); + size_t length = mpp_packet_get_length(pkt); + RK_U32 eos = mpp_packet_get_eos(pkt); + + task->valid = 0; + if (p_dec->got_eos) { + AVSD_DBG(AVSD_DBG_INPUT, "got eos packet.\n"); mpp_packet_set_length(pkt, 0); goto __RETURN; } - AVSD_DBG(AVSD_DBG_INPUT, "[pkt_in_timeUs] in_pts=%lld, pkt_eos=%d, len=%d, pkt_no=%d\n", - mpp_packet_get_pts(pkt), (RK_U32)mpp_packet_get_eos(pkt), (RK_U32)mpp_packet_get_length(pkt), (RK_U32)p_dec->pkt_no); + AVSD_DBG(AVSD_DBG_INPUT, "[pkt_in] pts=%lld, eos=%d, len=%d, pkt_no=%d\n", + mpp_packet_get_pts(pkt), eos, (RK_U32)length, (RK_U32)p_dec->pkt_no); p_dec->pkt_no++; if (mpp_packet_get_eos(pkt)) { if (mpp_packet_get_length(pkt) < 4) { avsd_flush(decoder); } - p_dec->has_get_eos = 1; - task->flags.eos = p_dec->has_get_eos; + p_dec->got_eos = 1; + task->flags.eos = p_dec->got_eos; goto __RETURN; } if (mpp_packet_get_length(pkt) > MAX_STREAM_SIZE) { AVSD_DBG(AVSD_DBG_ERROR, "[pkt_in_timeUs] input error, stream too large"); mpp_packet_set_length(pkt, 0); ret = MPP_NOK; - goto __FAILED; + goto __RETURN; } - task->valid = 0; - do { - (ret = avsd_parse_prepare(p_dec, pkt, task)); + mpp_packet_set_length(p_dec->task_pkt, p_dec->left_length); - } while (mpp_packet_get_length(pkt) && !task->valid); + RK_U32 total_length = MPP_ALIGN(p_dec->left_length + length, 16) + 64; + if (total_length > p_dec->stream_size) { + do { + p_dec->stream_size <<= 1; + } while (total_length > p_dec->stream_size); - if (task->valid) { - //!< bit stream - RK_U32 align_len = MPP_ALIGN(p_dec->p_stream->len + 32, 16); + RK_U8 *dst = mpp_malloc_size(RK_U8, p_dec->stream_size); + mpp_assert(dst); - mpp_assert(p_dec->p_stream->size > align_len); - memset(p_dec->p_stream->pbuf + p_dec->p_stream->len, - 0, align_len - p_dec->p_stream->len); + if (p_dec->left_length > 0) { + memcpy(dst, p_dec->streambuf, p_dec->left_length); + } + mpp_free(p_dec->streambuf); + p_dec->streambuf = dst; - p_dec->syn->bitstream_size = align_len; - p_dec->syn->bitstream = p_dec->p_stream->pbuf; - - mpp_packet_set_data(p_dec->task_pkt, p_dec->syn->bitstream); - mpp_packet_set_length(p_dec->task_pkt, p_dec->syn->bitstream_size); - mpp_packet_set_size(p_dec->task_pkt, p_dec->p_stream->size); + mpp_packet_set_data(p_dec->task_pkt, p_dec->streambuf); + mpp_packet_set_size(p_dec->task_pkt, p_dec->stream_size); + } + if (!p_dec->need_split) { + p_dec->got_eos = eos; + // empty eos packet + if (eos && (length < 4)) { + avsd_flush(decoder); + goto __RETURN; + } + // copy packet direct + memcpy(p_dec->streambuf, pos, length); + mpp_packet_set_data(p_dec->task_pkt, p_dec->streambuf); + mpp_packet_set_length(p_dec->task_pkt, length); mpp_packet_set_pts(p_dec->task_pkt, mpp_packet_get_pts(pkt)); - mpp_packet_set_dts(p_dec->task_pkt, mpp_packet_get_dts(pkt)); - task->input_packet = p_dec->task_pkt; - - p_dec->p_stream->len = 0; - p_dec->p_header->len = 0; + // set input packet length to 0 here + mpp_packet_set_length(pkt, 0); + /* this step will enable the task and goto parse stage */ + task->valid = 1; } else { - task->input_packet = NULL; + /* Split packet mode */ + if (MPP_OK == avsd_parser_split(p_dec, p_dec->task_pkt, pkt)) { + p_dec->left_length = 0; + task->valid = 1; + } else { + task->valid = 0; + p_dec->left_length = mpp_packet_get_length(p_dec->task_pkt); + } + p_dec->got_eos = mpp_packet_get_eos(p_dec->task_pkt); } + task->input_packet = p_dec->task_pkt; + task->flags.eos = p_dec->got_eos; __RETURN: - (void)decoder; - (void)pkt; - (void)task; AVSD_PARSE_TRACE("Out."); return ret = MPP_OK; -__FAILED: - return ret; } - - /*! *********************************************************************** * \brief @@ -280,7 +314,10 @@ MPP_RET avsd_parse(void *decoder, HalDecTask *task) avsd_commit_syntaxs(p_dec->syn, task); avsd_update_dpb(p_dec); } - + if (p_dec->disable_error) { + task->flags.ref_err = 0; + task->flags.parse_err = 0; + } AVSD_PARSE_TRACE("Out."); return ret = MPP_OK; @@ -298,11 +335,9 @@ MPP_RET avsd_callback(void *decoder, void *info) DecCbHalDone *ctx = (DecCbHalDone *)info; AVSD_PARSE_TRACE("In."); - { + if (!p_dec->disable_error) { MppFrame mframe = NULL; HalDecTask *task_dec = (HalDecTask *)ctx->task; - AVSD_DBG(AVSD_DBG_CALLBACK, "reg[1]=%08x, ref=%d, dpberr=%d, harderr-%d\n", - ctx->regs[1], task_dec->flags.used_for_ref, task_dec->flags.ref_err, ctx->hard_err); mpp_buf_slot_get_prop(p_dec->frame_slots, task_dec->output, SLOT_FRAME_PTR, &mframe); if (mframe) { @@ -316,8 +351,7 @@ MPP_RET avsd_callback(void *decoder, void *info) } } AVSD_PARSE_TRACE("Out."); - (void)p_dec; - (void)ctx; + return ret = MPP_OK; } /*! @@ -327,6 +361,21 @@ MPP_RET avsd_callback(void *decoder, void *info) *********************************************************************** */ const ParserApi api_avsd_parser = { + .name = "avsd_parse", + .coding = MPP_VIDEO_CodingAVS, + .ctx_size = sizeof(AvsdCtx_t), + .flag = 0, + .init = avsd_init, + .deinit = avsd_deinit, + .prepare = avsd_prepare, + .parse = avsd_parse, + .reset = avsd_reset, + .flush = avsd_flush, + .control = avsd_control, + .callback = avsd_callback, +}; + +const ParserApi api_avsd_plus_parser = { .name = "avsd_parse", .coding = MPP_VIDEO_CodingAVSPLUS, .ctx_size = sizeof(AvsdCtx_t), @@ -340,4 +389,3 @@ const ParserApi api_avsd_parser = { .control = avsd_control, .callback = avsd_callback, }; - diff --git a/mpp/codec/dec/avs/avsd_parse.c b/mpp/codec/dec/avs/avsd_parse.c index 22fae998..2ec9d638 100644 --- a/mpp/codec/dec/avs/avsd_parse.c +++ b/mpp/codec/dec/avs/avsd_parse.c @@ -1,19 +1,18 @@ /* -* -* 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. -*/ + * 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 "avsd_parse" @@ -27,57 +26,6 @@ #include "avsd_api.h" #include "avsd_parse.h" - -static MPP_RET add_nalu_header(AvsdCtx_t *p_dec, RK_U32 header) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AvsdStreamBuf_t *p_buf = p_dec->p_header; - RK_U32 add_size = sizeof(AvsdNalu_t); - - if ((p_buf->len + add_size) > p_buf->size) { - mpp_err_f("buffer is larger than %d", p_buf->size); - goto __FAILED; - } - p_dec->nal = (AvsdNalu_t *)&p_buf->pbuf[p_buf->len]; - p_dec->nal->eof = 0; - p_dec->nal->header = header; - p_dec->nal->pdata = NULL; - p_dec->nal->length = 0; - p_dec->nal->start_pos = 4; - p_buf->len += add_size; - - return ret = MPP_OK; -__FAILED: - return ret; -} - -static MPP_RET store_cur_nalu(AvsdCtx_t *p_dec, RK_U8 *p_start, RK_U32 nalu_len) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - AvsdStreamBuf_t *p_buf = NULL; - AvsdNalu_t *p_nalu = p_dec->nal; - - if (p_nalu->header >= SLICE_MIN_START_CODE - && p_nalu->header <= SLICE_MAX_START_CODE) { - p_buf = p_dec->p_stream; - } else { - p_buf = p_dec->p_header; - } - if ((p_buf->len + nalu_len) > p_buf->size) { - mpp_err_f("buffer is larger than %d", p_buf->size); - goto __FAILED; - } - p_nalu->length += nalu_len; - p_nalu->pdata = &p_buf->pbuf[p_buf->len]; - memcpy(p_nalu->pdata, p_start, nalu_len); - p_buf->len += nalu_len; - - return ret = MPP_OK; -__FAILED: - return ret; -} - static MPP_RET get_sequence_header(BitReadCtx_t *bitctx, AvsdSeqHeader_t *vsh) { MPP_RET ret = MPP_ERR_UNKNOW; @@ -277,26 +225,45 @@ static MPP_RET get_i_picture_header(BitReadCtx_t *bitctx, AvsdSeqHeader_t *vsh, if (ph->time_code_flag) { READ_BITS(bitctx, 24, &ph->time_code); } - SKIP_BITS(bitctx, 1); - READ_BITS(bitctx, 8, &ph->picture_distance); + + vsh->version = 0; + /* check stream version */ 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); + vsh->version = 1; } else { - ph->picture_structure = 1; //!< frame picture + SHOW_BITS(bitctx, 9, &val_temp); + if (!(val_temp & 1)) { + vsh->version = 1; + } else { + SHOW_BITS(bitctx, 11, &val_temp); + if (val_temp & 3) + vsh->version = 1; + } } + + if (vsh->version > 0) + SKIP_BITS(bitctx, 1); // marker bit + + READ_BITS(bitctx, 8, &ph->picture_distance); + + if (vsh->low_delay) + READ_UE(bitctx, &ph->bbv_check_times); + + READ_ONEBIT(bitctx, &ph->progressive_frame); + + ph->picture_structure = 1; // default frame + if (!ph->progressive_frame) + READ_ONEBIT(bitctx, &ph->picture_structure); + READ_ONEBIT(bitctx, &ph->top_field_first); READ_ONEBIT(bitctx, &ph->repeat_first_field); READ_ONEBIT(bitctx, &ph->fixed_picture_qp); READ_BITS(bitctx, 6, &ph->picture_qp); - if (!ph->progressive_frame && !ph->picture_structure) { + + ph->skip_mode_flag = 0; + if (!ph->progressive_frame && !ph->picture_structure) READ_ONEBIT(bitctx, &ph->skip_mode_flag); - } else { - ph->skip_mode_flag = 0; - } + READ_BITS(bitctx, 4, &val_temp); //!< reserve 4 bits if (val_temp) { AVSD_DBG(AVSD_DBG_WARNNING, "reserve bits not equal to zeros.\n"); @@ -374,7 +341,10 @@ __FAILED: static void reset_one_save(AvsdFrame_t *p) { if (p) { + RK_U32 idx = p->idx; + memset(p, 0, sizeof(AvsdFrame_t)); + p->idx = idx; p->slot_idx = -1; } } @@ -392,7 +362,7 @@ static AvsdFrame_t *get_one_save(AvsdCtx_t *p_dec, HalDecTask *task) } } if (!p_cur) { - AVSD_DBG(AVSD_DBG_WARNNING, "error, mem_save dpb has not get.\n"); + mpp_err("mem_save dpb %d slots has not get\n", MPP_ARRAY_ELEMS(p_dec->mem->save)); goto __FAILED; } (void)task; @@ -409,8 +379,7 @@ static MPP_RET set_frame_unref(AvsdCtx_t *pdec, AvsdFrame_t *p) if (p && p->slot_idx >= 0) { mpp_buf_slot_clr_flag(pdec->frame_slots, p->slot_idx, SLOT_CODEC_USE); - memset(p, 0, sizeof(AvsdFrame_t)); - p->slot_idx = -1; + reset_one_save(p); } return ret = MPP_OK; @@ -450,11 +419,13 @@ MPP_RET avsd_reset_parameters(AvsdCtx_t *p_dec) p_dec->cur = NULL; p_dec->dpb[0] = NULL; p_dec->dpb[1] = NULL; - p_dec->has_get_eos = 0; for (i = 0; i < MPP_ARRAY_ELEMS(p_dec->mem->save); i++) { - memset(&p_dec->mem->save[i], 0, sizeof(AvsdFrame_t)); - p_dec->mem->save[i].slot_idx = -1; + AvsdFrame_t *frm = &p_dec->mem->save[i]; + + memset(frm, 0, sizeof(*frm)); + frm->idx = i; + frm->slot_idx = -1; } return MPP_OK; @@ -676,6 +647,10 @@ MPP_RET avsd_fill_parameters(AvsdCtx_t *p_dec, AvsdSyntax_t *syn) pp->noForwardReferenceFlag = p_dec->ph.no_forward_reference_flag; pp->pbFieldEnhancedFlag = p_dec->ph.pb_field_enhanced_flag; + //!< set stream offset + syn->bitstream_size = p_dec->cur->stream_len; + syn->bitstream_offset = p_dec->cur->stream_offset; + return MPP_OK; } /*! @@ -684,73 +659,71 @@ MPP_RET avsd_fill_parameters(AvsdCtx_t *p_dec, AvsdSyntax_t *syn) * prepare function for parser *********************************************************************** */ -MPP_RET avsd_parse_prepare(AvsdCtx_t *p_dec, MppPacket *pkt, HalDecTask *task) +MPP_RET avsd_parser_split(AvsdCtx_t *p, MppPacket *dst, MppPacket *src) { - MPP_RET ret = MPP_ERR_UNKNOW; - RK_U8 *p_curdata = NULL; - RK_U8 *p_start = NULL; //!< store nalu start - RK_U32 nalu_len = 0; - RK_U8 got_frame_flag = 0; - RK_U8 got_nalu_flag = 0; - RK_U32 pkt_length = 0; + MPP_RET ret = MPP_NOK; + AVSD_PARSE_TRACE("In.\n"); - RK_U32 prefix = 0xFFFFFFFF; + 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_S64 src_pts = mpp_packet_get_pts(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; - AVSD_PARSE_TRACE("In."); - //!< check input - if (mpp_packet_get_length(pkt) < 4) { - AVSD_DBG(AVSD_DBG_WARNNING, "input have no stream."); - mpp_packet_set_length(pkt, 0); - goto __RETURN; - } - - pkt_length = (RK_U32)mpp_packet_get_length(pkt); - p_curdata = p_start = (RK_U8 *)mpp_packet_get_pos(pkt); - - while (pkt_length > 0) { - //!< found next nalu start code - if ((prefix & 0xFFFFFF00) == 0x00000100) { - if (got_nalu_flag) { - nalu_len = (RK_U32)(p_curdata - p_start) - 4; - FUN_CHECK(ret = store_cur_nalu(p_dec, p_start, nalu_len)); - } - FUN_CHECK(ret = add_nalu_header(p_dec, prefix)); - p_start = p_curdata - 4; - got_nalu_flag = 1; + // find the began of the vop + if (!p->vop_header_found) { + // add last startcode to the new frame data + 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; } - //!< found next picture start code - if (prefix == I_PICUTRE_START_CODE || prefix == PB_PICUTRE_START_CODE) { - task->valid = 1; - if (got_frame_flag) { - p_dec->nal->eof = 1; - pkt_length += 4; + 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 == I_PICUTRE_START_CODE || + p->state == PB_PICUTRE_START_CODE) { + p->vop_header_found = 1; + mpp_packet_set_pts(dst, src_pts); break; } - got_frame_flag = 1; - } - - prefix = (prefix << 8) | (*p_curdata); - p_curdata++; - pkt_length--; - } - //!< reach the packet end - if (!pkt_length) { - nalu_len = (RK_U32)(p_curdata - p_start); - FUN_CHECK(ret = store_cur_nalu(p_dec, p_start, nalu_len)); - if (task->valid) { - FUN_CHECK(ret = add_nalu_header(p_dec, 0)); - p_dec->nal->eof = 1; } } - //!< reset position - pkt_length = (RK_U32)mpp_packet_get_length(pkt) - pkt_length; - mpp_packet_set_pos(pkt, (RK_U8 *)mpp_packet_get_pos(pkt) + pkt_length); -__RETURN: - AVSD_PARSE_TRACE("Out."); + // find the end of the vop + 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) { + if (src_buf[src_pos] > (SLICE_MAX_START_CODE & 0xFF) && + src_buf[src_pos] != (USER_DATA_CODE & 0xFF)) { + dst_len -= 3; + p->vop_header_found = 0; + ret = MPP_OK; // split complete + break; + } + } + } + } + // the last packet + if (src_eos && src_pos >= src_len) { + mpp_packet_set_eos(dst); + ret = MPP_OK; + } + + AVSD_DBG(AVSD_DBG_INPUT, "[pkt_in] vop_header_found= %d, dst_len=%d, src_pos=%d\n", + p->vop_header_found, dst_len, src_pos); + // reset the src and dst + mpp_packet_set_length(dst, dst_len); + mpp_packet_set_pos(src, src_buf + src_pos); + + AVSD_PARSE_TRACE("out.\n"); - return ret = MPP_OK; -__FAILED: return ret; } /*! @@ -762,32 +735,38 @@ __FAILED: MPP_RET avsd_parse_stream(AvsdCtx_t *p_dec, HalDecTask *task) { MPP_RET ret = MPP_ERR_UNKNOW; + RK_U32 startcode = 0xFF; + RK_U32 pic_type = 0; + RK_U32 got_slice = 0; - RK_U8 pic_type = 0; - AvsdNalu_t *p_nalu = (AvsdNalu_t *)p_dec->p_header->pbuf; + RK_U8 *data = (RK_U8 *)mpp_packet_get_data(task->input_packet); + RK_S32 length = (RK_S32)mpp_packet_get_length(task->input_packet); - task->valid = 0; - while (!p_nalu->eof) { - RK_U32 startcode = p_nalu->header; + mpp_set_bitread_ctx(p_dec->bx, data, length); + AVSD_DBG(AVSD_DBG_SYNTAX, "bytes_left_=%d\n", p_dec->bx->bytes_left_); + while (p_dec->bx->bytes_left_ && !got_slice) { + RK_S32 tmp = 0; + mpp_align_get_bits(p_dec->bx); + mpp_read_bits(p_dec->bx, 8, &tmp); + startcode = (startcode << 8) | tmp; + if ((startcode & 0xFFFFFF00) != 0x100) + continue; + AVSD_DBG(AVSD_DBG_SYNTAX, "startcode=%08x\n", startcode); - if (startcode >= SLICE_MIN_START_CODE && startcode <= SLICE_MAX_START_CODE) { - p_nalu++; - } else { - memset(&p_dec->bitctx, 0, sizeof(BitReadCtx_t)); - mpp_set_bitread_ctx(&p_dec->bitctx, p_nalu->pdata + p_nalu->start_pos, p_nalu->length); - p_nalu = (AvsdNalu_t *)(p_nalu->pdata + p_nalu->length); - } - - if (startcode != VIDEO_SEQUENCE_START_CODE && !p_dec->got_vsh) { - // when has not got sequence header, then do nothing + // when has not got sequence header, then do nothing + if (!p_dec->got_vsh && + startcode != VIDEO_SEQUENCE_START_CODE) { + AVSD_DBG(AVSD_DBG_WARNNING, "when has not got sequence header, then do nothing\n"); continue; } + //continue; switch (startcode) { case VIDEO_SEQUENCE_START_CODE: - ret = get_sequence_header(&p_dec->bitctx, &p_dec->vsh); + ret = get_sequence_header(p_dec->bx, &p_dec->vsh); if (ret == MPP_OK) { p_dec->got_vsh = 1; } + AVSD_DBG(AVSD_DBG_WARNNING, "got vsh %d\n", p_dec->got_vsh); break; case VIDEO_SEQUENCE_END_CODE: break; @@ -797,59 +776,66 @@ MPP_RET avsd_parse_stream(AvsdCtx_t *p_dec, HalDecTask *task) p_dec->vec_flag = 0; break; case I_PICUTRE_START_CODE: + AVSD_DBG(AVSD_DBG_WARNNING, "got I picture start code\n"); if (!p_dec->got_keyframe) { avsd_reset_parameters(p_dec); p_dec->got_keyframe = 1; } - ret = get_i_picture_header(&p_dec->bitctx, &p_dec->vsh, &p_dec->ph); + ret = get_i_picture_header(p_dec->bx, &p_dec->vsh, &p_dec->ph); if (ret == MPP_OK) { p_dec->cur = get_one_save(p_dec, task); + p_dec->got_ph = 1; } p_dec->cur->pic_type = pic_type = I_PICTURE; p_dec->vec_flag++; break; case EXTENSION_START_CODE: - ret = get_extension_header(&p_dec->bitctx, &p_dec->ext); + ret = get_extension_header(p_dec->bx, &p_dec->ext); break; case PB_PICUTRE_START_CODE: + AVSD_DBG(AVSD_DBG_WARNNING, "got PB picture start code\n"); if (!p_dec->got_keyframe) { avsd_reset_parameters(p_dec); break; } - ret = get_pb_picture_header(&p_dec->bitctx, &p_dec->vsh, &p_dec->ph); + ret = get_pb_picture_header(p_dec->bx, &p_dec->vsh, &p_dec->ph); if (ret == MPP_OK) { p_dec->cur = get_one_save(p_dec, task); + p_dec->got_ph = 1; } p_dec->cur->pic_type = pic_type = p_dec->ph.picture_coding_type; p_dec->vec_flag += (p_dec->vec_flag == 1 && pic_type == P_PICTURE); break; default: - if (!p_dec->cur - || (pic_type == P_PICTURE && !p_dec->dpb[0]) - || (pic_type == B_PICTURE && !p_dec->dpb[0]) - || (pic_type == B_PICTURE && !p_dec->dpb[1] && !p_dec->vsh.low_delay) - || (pic_type == P_PICTURE && p_dec->vec_flag < 1) - || (pic_type == B_PICTURE && p_dec->vec_flag < 2)) { - mpp_err_f("missing refer frame.\n"); - ret = MPP_NOK; - goto __FAILED; - } - if (startcode >= SLICE_MIN_START_CODE + if (p_dec->cur + && startcode >= SLICE_MIN_START_CODE && startcode <= SLICE_MAX_START_CODE) { - task->valid = 1; + got_slice = 1; + p_dec->cur->stream_len = length; + p_dec->cur->stream_offset = p_dec->bx->used_bits / 8 - 4; + task->valid = p_dec->got_vsh && p_dec->got_ph; + AVSD_DBG(AVSD_DBG_SYNTAX, "offset=%d,got_vsh=%d, got_ph=%d, task->valid=%d\n", + p_dec->cur->stream_offset, p_dec->got_vsh, p_dec->got_ph, task->valid); + } + if ((pic_type == P_PICTURE && !p_dec->dpb[0]) || + (pic_type == B_PICTURE && !p_dec->dpb[0]) || + (pic_type == B_PICTURE && !p_dec->dpb[1] && !p_dec->vsh.low_delay) || + (pic_type == P_PICTURE && p_dec->vec_flag < 1) || + (pic_type == B_PICTURE && p_dec->vec_flag < 2)) { + AVSD_DBG(AVSD_DBG_REF, "missing refer frame.\n"); + if (!p_dec->disable_error) + goto __FAILED; } - break; } } - return ret = MPP_OK; + if (!task->valid) + goto __FAILED; + + return MPP_OK; __FAILED: + task->valid = 0; reset_one_save(p_dec->cur); - - return ret; + return MPP_NOK; } - - - - diff --git a/mpp/codec/dec/avs/avsd_parse.h b/mpp/codec/dec/avs/avsd_parse.h index c999a0b2..d269e2f5 100644 --- a/mpp/codec/dec/avs/avsd_parse.h +++ b/mpp/codec/dec/avs/avsd_parse.h @@ -32,6 +32,8 @@ #define AVSD_DBG_INPUT (0x00000010) //!< input packet #define AVSD_DBG_TIME (0x00000020) //!< input packet +#define AVSD_DBG_SYNTAX (0x00000040) +#define AVSD_DBG_REF (0x00000080) #define AVSD_DBG_CALLBACK (0x00008000) @@ -76,7 +78,6 @@ if ((val) < 0) {\ goto __FAILED; \ }} while (0) -#define MAX_HEADER_SIZE (2*1024) #define MAX_STREAM_SIZE (2*1024*1024) //!< NALU type @@ -96,7 +97,6 @@ if ((val) < 0) {\ #define VIDEO_TIME_CODE 0x000001E0 - #define EDGE_SIZE 16 #define MB_SIZE 16 #define YUV420 0 @@ -108,20 +108,11 @@ enum avsd_picture_type_e { B_PICTURE = 2 }; -typedef struct avsd_nalu_t { - RK_U32 header; - RK_U32 size; - RK_U32 length; - RK_U8 *pdata; - RK_U8 start_pos; - RK_U8 eof; //!< end of frame stream -} AvsdNalu_t; - - typedef struct avsd_sequence_header_t { RK_U8 profile_id; RK_U8 level_id; RK_U8 progressive_sequence; + RK_U8 version; RK_U32 horizontal_size; RK_U32 vertical_size; @@ -153,7 +144,7 @@ typedef struct avsd_picture_header { RK_U8 picture_coding_type; RK_U8 time_code_flag; RK_U32 time_code; - RK_U8 picture_distance; + RK_U8 picture_distance; // poc RK_U32 bbv_check_times; RK_U8 progressive_frame; RK_U8 picture_structure; @@ -187,71 +178,66 @@ typedef struct avsd_picture_header { typedef struct avsd_frame_t { RK_U32 valid; + RK_U32 idx; RK_U32 pic_type; - RK_U32 frame_mode; //!< set mpp frame flag - RK_U32 width; RK_U32 height; RK_U32 ver_stride; RK_U32 hor_stride; - RK_S64 pts; RK_S64 dts; + RK_S32 stream_len; + RK_S32 stream_offset; RK_U32 had_display; RK_S32 slot_idx; } AvsdFrame_t; - - -typedef struct avsd_stream_buf_t { - RK_U8 *pbuf; - RK_U32 size; - RK_U32 len; -} AvsdStreamBuf_t; - typedef struct avsd_memory_t { - struct avsd_stream_buf_t headerbuf; - struct avsd_stream_buf_t streambuf; struct avsd_syntax_t syntax; struct avsd_frame_t save[3]; + BitReadCtx_t bitctx; } AvsdMemory_t; - //!< decoder parameters typedef struct avs_dec_ctx_t { - MppBufSlots frame_slots; - MppBufSlots packet_slots; + MppBufSlots frame_slots; + MppBufSlots packet_slots; + + MppPacket task_pkt; + RK_U32 frame_no; + ParserCfg init; + RK_U8 got_eos; + RK_U32 pkt_no; + + struct avsd_memory_t *mem; + RK_U8 *streambuf; + RK_U32 stream_len; + RK_U32 stream_size; + + BitReadCtx_t *bx; + RK_U32 left_length; - MppPacket task_pkt; - struct avsd_memory_t *mem; //!< resotre slice data to decoder - struct avsd_stream_buf_t *p_stream; - struct avsd_stream_buf_t *p_header; - //-------- input --------------- - RK_U32 frame_no; - ParserCfg init; - RK_U8 has_get_eos; - RK_U64 pkt_no; - //-------- current -------------- - struct avsd_nalu_t *nal; //!< current nalu - //-------- video -------------- - struct bitread_ctx_t bitctx; AvsdSeqHeader_t vsh; AvsdSeqExtHeader_t ext; - AvsdPicHeader_t ph; AvsdSyntax_t *syn; + AvsdFrame_t *dpb[2]; //!< 2 refer frames or 4 refer field + AvsdFrame_t *cur; //!< for decoder field - AvsdFrame_t *dpb[2]; //!< 2 refer frames or 4 refer field - AvsdFrame_t *cur; //!< for decoder field - //!<------------------------------------ + RK_U32 need_split; + RK_U32 state; + RK_U32 vop_header_found; RK_U32 got_vsh; + RK_U32 got_ph; RK_U32 got_keyframe; RK_U32 mb_width; RK_U32 mb_height; RK_U32 vec_flag; //!< video_edit_code_flag + + RK_U32 disable_error; } AvsdCtx_t; @@ -269,7 +255,7 @@ MPP_RET avsd_fill_parameters(AvsdCtx_t *p_dec, AvsdSyntax_t *syn); MPP_RET avsd_update_dpb(AvsdCtx_t *p_dec); -MPP_RET avsd_parse_prepare(AvsdCtx_t *p_dec, MppPacket *pkt, HalDecTask *task); +MPP_RET avsd_parser_split(AvsdCtx_t *ctx, MppPacket *dst, MppPacket *src); MPP_RET avsd_parse_stream(AvsdCtx_t *p_dec, HalDecTask *task); #ifdef __cplusplus diff --git a/mpp/codec/inc/avsd_api.h b/mpp/codec/inc/avsd_api.h index d3063fb2..3d6a5f0b 100644 --- a/mpp/codec/inc/avsd_api.h +++ b/mpp/codec/inc/avsd_api.h @@ -23,6 +23,7 @@ extern "C" { #endif extern const ParserApi api_avsd_parser; +extern const ParserApi api_avsd_plus_parser; MPP_RET avsd_init (void *decoder, ParserCfg *cfg); MPP_RET avsd_deinit (void *decoder); diff --git a/mpp/codec/mpp_parser.cpp b/mpp/codec/mpp_parser.cpp index 4825156c..720d4ee0 100644 --- a/mpp/codec/mpp_parser.cpp +++ b/mpp/codec/mpp_parser.cpp @@ -45,6 +45,7 @@ static const ParserApi *parsers[] = { #if HAVE_AVSD &api_avsd_parser, + &api_avsd_plus_parser, #endif #if HAVE_AVS2D &api_avs2d_parser, diff --git a/mpp/common/avsd_syntax.h b/mpp/common/avsd_syntax.h index 07a44d64..ee97a25b 100644 --- a/mpp/common/avsd_syntax.h +++ b/mpp/common/avsd_syntax.h @@ -1,20 +1,18 @@ /* -* -* 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. -*/ - + * 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. + */ #ifndef __AVSD_SYNTAX_H__ #define __AVSD_SYNTAX_H__ @@ -92,6 +90,7 @@ typedef struct _PicParams_Avsd { typedef struct avsd_syntax_t { PicParams_Avsd pp; RK_U8 *bitstream; + RK_U32 bitstream_offset; RK_U32 bitstream_size; } AvsdSyntax_t; diff --git a/mpp/hal/inc/hal_avsd_api.h b/mpp/hal/inc/hal_avsd_api.h index df9ab275..34f51a13 100644 --- a/mpp/hal/inc/hal_avsd_api.h +++ b/mpp/hal/inc/hal_avsd_api.h @@ -1,20 +1,18 @@ /* -* -* 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. -*/ - + * 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. + */ #ifndef __HAL_AVSD_API_H__ #define __HAL_AVSD_API_H__ @@ -26,6 +24,7 @@ extern "C" { #endif extern const MppHalApi hal_api_avsd; +extern const MppHalApi hal_api_avsd_plus; #ifdef __cplusplus } diff --git a/mpp/hal/mpp_hal.cpp b/mpp/hal/mpp_hal.cpp index cda9024a..5283d797 100644 --- a/mpp/hal/mpp_hal.cpp +++ b/mpp/hal/mpp_hal.cpp @@ -46,6 +46,7 @@ static const MppHalApi *hw_apis[] = { #if HAVE_AVSD &hal_api_avsd, + &hal_api_avsd_plus, #endif #if HAVE_AVS2D &hal_api_avs2d, diff --git a/mpp/hal/rkdec/avsd/CMakeLists.txt b/mpp/hal/rkdec/avsd/CMakeLists.txt index c96ccfc1..fe2e0743 100644 --- a/mpp/hal/rkdec/avsd/CMakeLists.txt +++ b/mpp/hal/rkdec/avsd/CMakeLists.txt @@ -6,13 +6,22 @@ set(HAL_AVSD_API # hal avs header set(HAL_AVSD_HDR - hal_avsd_reg.h + hal_avsd_base.h + hal_avsd_vdpu1.h + hal_avsd_vdpu2.h + hal_avsd_plus.h + hal_avsd_vdpu1_reg.h + hal_avsd_vdpu2_reg.h + hal_avsd_plus_reg.h ) # hal avs decoder sourse set(HAL_AVSD_SRC - hal_avsd_reg.c hal_avsd_api.c + hal_avsd_base.c + hal_avsd_vdpu1.c + hal_avsd_vdpu2.c + hal_avsd_plus.c ) add_library(hal_avsd STATIC diff --git a/mpp/hal/rkdec/avsd/hal_avsd_api.c b/mpp/hal/rkdec/avsd/hal_avsd_api.c index 3fbe9eae..6ea1077a 100644 --- a/mpp/hal/rkdec/avsd/hal_avsd_api.c +++ b/mpp/hal/rkdec/avsd/hal_avsd_api.c @@ -1,20 +1,18 @@ /* -* -* 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. -*/ - + * 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 "hal_avsd_api" @@ -22,141 +20,97 @@ #include #include +#include "rk_mpi_cmd.h" +#include "mpp_debug.h" #include "mpp_mem.h" #include "mpp_env.h" #include "mpp_common.h" +#include "mpp_platform.h" +#include "mpp_device.h" -#include "hal_avsd_api.h" -#include "hal_avsd_reg.h" #include "mpp_dec_cb_param.h" +#include "hal_avsd_api.h" +#include "hal_avsd_base.h" +#include "hal_avsd_vdpu1.h" +#include "hal_avsd_vdpu2.h" +#include "hal_avsd_plus.h" -RK_U32 avsd_hal_debug = 0; - -MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task); -MPP_RET hal_avsd_wait(void *decoder, HalTaskInfo *task); - -static RK_U32 avsd_ver_align(RK_U32 val) +static MPP_RET init_hard_platform(AvsdHalCtx_t *p_hal, MppCodingType coding) { - return MPP_ALIGN(val, 16); -} - -static RK_U32 avsd_hor_align(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static RK_U32 avsd_len_align(RK_U32 val) -{ - return (2 * MPP_ALIGN(val, 16)); -} - -static void explain_input_buffer(AvsdHalCtx_t *p_hal, HalDecTask *task) -{ - memcpy(&p_hal->syn, task->syntax.data, sizeof(AvsdSyntax_t)); -} - -static MPP_RET repeat_other_field(AvsdHalCtx_t *p_hal, HalTaskInfo *task) -{ - RK_U8 i = 0; - RK_U8 *pdata = NULL; - MppBuffer mbuffer = NULL; + MppHalApi *p_api = &p_hal->hal_api; + RK_U32 vcodec_type = mpp_get_vcodec_type(); + MppClientType client_type = VPU_CLIENT_BUTT; MPP_RET ret = MPP_ERR_UNKNOW; - AvsdRegs_t *p_regs = (AvsdRegs_t *)p_hal->p_regs; - //!< re-find start code and calculate offset - p_hal->data_offset = p_regs->sw12.rlc_vlc_base >> 10; - mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &mbuffer); - pdata = (RK_U8 *)mpp_buffer_get_ptr(mbuffer) + p_hal->data_offset; - while (i < 8) { - if (pdata[i] == 0 && pdata[i + 1] == 0 && pdata[i + 2] == 1) { - p_hal->data_offset += i; - p_hal->syn.bitstream_size -= i; - break; - } - i++; + if (coding == MPP_VIDEO_CodingAVSPLUS) { + if (!(vcodec_type & HAVE_AVSDEC)) + mpp_err("coding %x vcodec_type %x do not found avs hw %x\n", + coding, vcodec_type, HAVE_AVSDEC); + } else { + RK_U32 hw_flag = HAVE_VDPU1 | HAVE_VDPU2 | HAVE_VDPU1_PP | HAVE_VDPU2_PP; + + if (!(vcodec_type & hw_flag )) + mpp_err("coding %x vcodec_type %x do not found avs hw %x\n", + coding, vcodec_type, hw_flag); } - AVSD_HAL_DBG(AVSD_HAL_DBG_OFFSET, "frame_no=%d, offset=%d\n", p_hal->frame_no, p_hal->data_offset); - //!< re-generate register - memset(p_hal->p_regs, 0, sizeof(AvsdRegs_t)); - FUN_CHECK(ret = set_defalut_parameters(p_hal)); - FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); - hal_avsd_start((void *)p_hal, task); - hal_avsd_wait((void *)p_hal, task); - return ret = MPP_OK; -__FAILED: - return ret; + if ((coding == MPP_VIDEO_CodingAVSPLUS) && + (vcodec_type & HAVE_AVSDEC)) { + p_api->init = hal_avsd_plus_init; + p_api->deinit = hal_avsd_plus_deinit; + p_api->reg_gen = hal_avsd_plus_gen_regs; + p_api->start = hal_avsd_plus_start; + p_api->wait = hal_avsd_plus_wait; + p_api->reset = hal_avsd_plus_reset; + p_api->flush = hal_avsd_plus_flush; + p_api->control = hal_avsd_plus_control; + client_type = VPU_CLIENT_AVSPLUS_DEC; + } else if ((coding == MPP_VIDEO_CodingAVS) && + (vcodec_type & (HAVE_VDPU1 | HAVE_VDPU1_PP))) { + p_api->init = hal_avsd_vdpu1_init; + p_api->deinit = hal_avsd_vdpu1_deinit; + p_api->reg_gen = hal_avsd_vdpu1_gen_regs; + p_api->start = hal_avsd_vdpu1_start; + p_api->wait = hal_avsd_vdpu1_wait; + p_api->reset = hal_avsd_vdpu1_reset; + p_api->flush = hal_avsd_vdpu1_flush; + p_api->control = hal_avsd_vdpu1_control; + client_type = VPU_CLIENT_VDPU1; + } else if ((coding == MPP_VIDEO_CodingAVS) && + (vcodec_type & (HAVE_VDPU2 | HAVE_VDPU2_PP))) { + p_api->init = hal_avsd_vdpu2_init; + p_api->deinit = hal_avsd_vdpu2_deinit; + p_api->reg_gen = hal_avsd_vdpu2_gen_regs; + p_api->start = hal_avsd_vdpu2_start; + p_api->wait = hal_avsd_vdpu2_wait; + p_api->reset = hal_avsd_vdpu2_reset; + p_api->flush = hal_avsd_vdpu2_flush; + p_api->control = hal_avsd_vdpu2_control; + client_type = VPU_CLIENT_VDPU2; + } else { + ret = MPP_NOK; + goto __FAILED; + } + p_hal->coding = coding; + AVSD_HAL_DBG(AVSD_DBG_HARD_MODE, "hw_spt %08x, coding %d\n", vcodec_type, coding); -} -/*! -*********************************************************************** -* \brief -* init -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_init(void *decoder, MppHalCfg *cfg) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - AvsdHalCtx_t *p_hal = NULL; - - AVSD_HAL_TRACE("In."); - INP_CHECK(ret, NULL == decoder); - - mpp_env_get_u32("avsd_debug", &avsd_hal_debug, 0); - - p_hal = (AvsdHalCtx_t *)decoder; - memset(p_hal, 0, sizeof(AvsdHalCtx_t)); - - p_hal->frame_slots = cfg->frame_slots; - p_hal->packet_slots = cfg->packet_slots; - //!< callback function to parser module - p_hal->dec_cb = cfg->dec_cb; - //!< mpp_device_init - - ret = mpp_dev_init(&p_hal->dev, VPU_CLIENT_AVSPLUS_DEC); + ret = mpp_dev_init(&p_hal->dev, client_type); if (ret) { mpp_err("mpp_device_init failed. ret: %d\n", ret); return ret; + } - - //< get buffer group - if (p_hal->buf_group == NULL) { - RK_U32 buf_size = (1920 * 1088) / 16; - - FUN_CHECK(ret = mpp_buffer_group_get_internal(&p_hal->buf_group, MPP_BUFFER_TYPE_ION)); - FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->mv_buf, buf_size)); - } - - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align); - - p_hal->p_regs = mpp_calloc_size(RK_U32 , sizeof(AvsdRegs_t)); - MEM_CHECK(ret, p_hal->p_regs); - - //!< initial for control - p_hal->first_field = 1; - p_hal->prev_pic_structure = 0; //!< field - - memset(p_hal->pic, 0, sizeof(p_hal->pic)); - p_hal->work_out = -1; - p_hal->work0 = -1; - p_hal->work1 = -1; - -__RETURN: - AVSD_HAL_TRACE("Out."); - return ret = MPP_OK; __FAILED: return ret; } + /*! -*********************************************************************** -* \brief -* deinit -*********************************************************************** -*/ + *********************************************************************** + * \brief + * deinit + *********************************************************************** + */ //extern "C" MPP_RET hal_avsd_deinit(void *decoder) { @@ -166,20 +120,17 @@ MPP_RET hal_avsd_deinit(void *decoder) AVSD_HAL_TRACE("In."); INP_CHECK(ret, NULL == decoder); - //!< mpp_device_init + FUN_CHECK(ret = p_hal->hal_api.deinit(decoder)); + //!< mpp_dev_init if (p_hal->dev) { ret = mpp_dev_deinit(p_hal->dev); if (ret) mpp_err("mpp_dev_deinit failed. ret: %d\n", ret); } - if (p_hal->mv_buf) { - FUN_CHECK(ret = mpp_buffer_put(p_hal->mv_buf)); - } + if (p_hal->buf_group) { FUN_CHECK(ret = mpp_buffer_group_put(p_hal->buf_group)); } - MPP_FREE(p_hal->p_regs); - __RETURN: AVSD_HAL_TRACE("Out."); @@ -187,175 +138,151 @@ __RETURN: __FAILED: return ret; } + /*! -*********************************************************************** -* \brief -* generate register -*********************************************************************** -*/ + *********************************************************************** + * \brief + * init + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_init(void *decoder, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + INP_CHECK(ret, NULL == decoder); + + memset(p_hal, 0, sizeof(AvsdHalCtx_t)); + p_hal->frame_slots = cfg->frame_slots; + p_hal->packet_slots = cfg->packet_slots; + + //!< callback function to parser module + p_hal->dec_cb = cfg->dec_cb; + mpp_env_get_u32("avsd_debug", &avsd_hal_debug, 0); + //< get buffer group + FUN_CHECK(ret = mpp_buffer_group_get_internal(&p_hal->buf_group, MPP_BUFFER_TYPE_ION)); + + FUN_CHECK(ret = init_hard_platform(p_hal, cfg->coding)); + + //!< run init funtion + FUN_CHECK(ret = p_hal->hal_api.init(decoder, cfg)); + +__RETURN: + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +__FAILED: + hal_avsd_deinit(decoder); + return ret; +} + +/*! + *********************************************************************** + * \brief + * generate register + *********************************************************************** + */ //extern "C" MPP_RET hal_avsd_gen_regs(void *decoder, HalTaskInfo *task) { MPP_RET ret = MPP_ERR_UNKNOW; - - AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; - AVSD_HAL_TRACE("In."); - INP_CHECK(ret, NULL == decoder); - if (task->dec.flags.parse_err || - task->dec.flags.ref_err) { - goto __RETURN; - } - memset(p_hal->p_regs, 0, sizeof(AvsdRegs_t)); - explain_input_buffer(p_hal, &task->dec); - p_hal->data_offset = 0; - - FUN_CHECK(ret = set_defalut_parameters(p_hal)); - FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); - -__RETURN: - AVSD_HAL_TRACE("Out."); - - return ret = MPP_OK; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief h -* start hard -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; + MppCodingType coding = MPP_VIDEO_CodingUnused; AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; - AVSD_HAL_TRACE("In."); - INP_CHECK(ret, NULL == decoder); + memcpy(&p_hal->syn, task->dec.syntax.data, sizeof(AvsdSyntax_t)); + // check coding + coding = (p_hal->syn.pp.profileId == 0x48) ? MPP_VIDEO_CodingAVSPLUS : MPP_VIDEO_CodingAVS; + if (coding != p_hal->coding) { + if (p_hal->dev) { + ret = mpp_dev_deinit(p_hal->dev); + if (ret) + mpp_err("mpp_dev_deinit failed. ret: %d\n", ret); - if (task->dec.flags.parse_err || task->dec.flags.ref_err) { - goto __RETURN; + p_hal->dev = NULL; + } + ret = init_hard_platform(p_hal, coding); + if (ret) { + mpp_err_f("change paltform %x -> %x error\n", p_hal->coding, coding); + return ret; + } } - do { - MppDevRegWrCfg wr_cfg; - MppDevRegRdCfg rd_cfg; - - wr_cfg.reg = p_hal->p_regs; - wr_cfg.size = AVSD_REGISTERS * sizeof(RK_U32); - wr_cfg.offset = 0; - - ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg); - if (ret) { - mpp_err_f("set register write failed %d\n", ret); - break; - } - - rd_cfg.reg = p_hal->p_regs; - rd_cfg.size = AVSD_REGISTERS * sizeof(RK_U32); - rd_cfg.offset = 0; - - ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg); - if (ret) { - mpp_err_f("set register read failed %d\n", ret); - break; - } - - ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL); - if (ret) { - mpp_err_f("send cmd failed %d\n", ret); - break; - } - } while (0); - p_hal->frame_no++; -__RETURN: - AVSD_HAL_TRACE("Out."); - - return ret; + return p_hal->hal_api.reg_gen(decoder, task); } /*! -*********************************************************************** -* \brief -* wait hard -*********************************************************************** -*/ + *********************************************************************** + * \brief h + * start hard + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task) +{ + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + return p_hal->hal_api.start(decoder, task); +} +/*! + *********************************************************************** + * \brief + * wait hard + *********************************************************************** + */ //extern "C" MPP_RET hal_avsd_wait(void *decoder, HalTaskInfo *task) { - MPP_RET ret = MPP_ERR_UNKNOW; AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; - AvsdRegs_t *p_regs = (AvsdRegs_t *)p_hal->p_regs; - AVSD_HAL_TRACE("In."); - INP_CHECK(ret, NULL == decoder); - - if (task->dec.flags.parse_err || - task->dec.flags.ref_err) { - goto __SKIP_HARD; - } - - ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL); - if (ret) - mpp_err_f("poll cmd failed %d\n", ret); - - update_parameters(p_hal); - if (!p_hal->first_field && p_hal->syn.pp.pictureStructure == FIELDPICTURE) - repeat_other_field(p_hal, task); - -__SKIP_HARD: - if (p_hal->dec_cb) { - DecCbHalDone param; - - param.task = (void *)&task->dec; - param.regs = (RK_U32 *)p_regs; - param.hard_err = !p_regs->sw01.dec_rdy_int; - - mpp_callback(p_hal->dec_cb, ¶m); - } - - memset(&p_regs->sw01, 0, sizeof(p_regs->sw01)); -__RETURN: - AVSD_HAL_TRACE("Out."); - - return ret; + return p_hal->hal_api.wait(decoder, task); } /*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ + *********************************************************************** + * \brief + * reset + *********************************************************************** + */ //extern "C" MPP_RET hal_avsd_reset(void *decoder) { - MPP_RET ret = MPP_ERR_UNKNOW; AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; - AVSD_HAL_TRACE("In."); + return p_hal->hal_api.reset(p_hal); +} +/*! + *********************************************************************** + * \brief + * flush + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_flush(void *decoder) +{ + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; - memset(p_hal->p_regs, 0, sizeof(AvsdRegs_t)); + return p_hal->hal_api.flush(p_hal); +} +/*! + *********************************************************************** + * \brief + * control + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_control(void *decoder, MpiCmd cmd_type, void *param) +{ + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; - p_hal->first_field = 1; - p_hal->prev_pic_structure = 0; //!< field - - memset(p_hal->pic, 0, sizeof(p_hal->pic)); - p_hal->work_out = -1; - p_hal->work0 = -1; - p_hal->work1 = -1; - - - AVSD_HAL_TRACE("Out."); - - return ret = MPP_OK; + return p_hal->hal_api.control(decoder, cmd_type, param); } const MppHalApi hal_api_avsd = { - .name = "avsd_rkdec", + .name = "avsd_vdpu", .type = MPP_CTX_DEC, - .coding = MPP_VIDEO_CodingAVSPLUS, + .coding = MPP_VIDEO_CodingAVS, .ctx_size = sizeof(AvsdHalCtx_t), .flag = 0, .init = hal_avsd_init, @@ -364,6 +291,22 @@ const MppHalApi hal_api_avsd = { .start = hal_avsd_start, .wait = hal_avsd_wait, .reset = hal_avsd_reset, - .flush = NULL, - .control = NULL, + .flush = hal_avsd_flush, + .control = hal_avsd_control, +}; + +const MppHalApi hal_api_avsd_plus = { + .name = "avsd_plus", + .type = MPP_CTX_DEC, + .coding = MPP_VIDEO_CodingAVSPLUS, + .ctx_size = sizeof(AvsdHalCtx_t), + .flag = 0, + .init = hal_avsd_init, + .deinit = hal_avsd_deinit, + .reg_gen = hal_avsd_gen_regs, + .start = hal_avsd_start, + .wait = hal_avsd_wait, + .reset = hal_avsd_reset, + .flush = hal_avsd_flush, + .control = hal_avsd_control, }; diff --git a/mpp/hal/rkdec/avsd/hal_avsd_base.c b/mpp/hal/rkdec/avsd/hal_avsd_base.c new file mode 100644 index 00000000..94ca6ab7 --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_base.c @@ -0,0 +1,80 @@ +/* + * 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 "hal_avsd_base" +#include +#include "mpp_log.h" +#include "mpp_common.h" + +#include "hal_avsd_base.h" + + +RK_U32 avsd_hal_debug = 0; + +RK_U32 avsd_ver_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +RK_U32 avsd_hor_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +RK_U32 avsd_len_align(RK_U32 val) +{ + return (2 * MPP_ALIGN(val, 16)); +} + +RK_S32 get_queue_pic(AvsdHalCtx_t *p_hal) +{ + RK_U32 i = 0; + RK_S32 ret_idx = -1; + + for (i = 0; i < MPP_ARRAY_ELEMS(p_hal->pic); i++) { + if (!p_hal->pic[i].valid) { + ret_idx = i; + p_hal->pic[i].valid = 1; + break; + } + } + + return ret_idx; +} + +RK_S32 get_packet_fd(AvsdHalCtx_t *p_hal, RK_S32 idx) +{ + RK_S32 ret_fd = 0; + MppBuffer mbuffer = NULL; + + mpp_buf_slot_get_prop(p_hal->packet_slots, idx, SLOT_BUFFER, &mbuffer); + assert(mbuffer); + ret_fd = mpp_buffer_get_fd(mbuffer); + + return ret_fd; +} + +RK_S32 get_frame_fd(AvsdHalCtx_t *p_hal, RK_S32 idx) +{ + RK_S32 ret_fd = 0; + MppBuffer mbuffer = NULL; + + mpp_buf_slot_get_prop(p_hal->frame_slots, idx, SLOT_BUFFER, &mbuffer); + assert(mbuffer); + ret_fd = mpp_buffer_get_fd(mbuffer); + + return ret_fd; +} diff --git a/mpp/hal/rkdec/avsd/hal_avsd_base.h b/mpp/hal/rkdec/avsd/hal_avsd_base.h new file mode 100644 index 00000000..cbf330fe --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_base.h @@ -0,0 +1,146 @@ +/* + * 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. + */ + +#ifndef __HAL_AVSD_BASE_H__ +#define __HAL_AVSD_BASE_H__ + +#include "parser_api.h" +#include "hal_avsd_api.h" +#include "avsd_syntax.h" + +#include "mpp_device.h" + +#define AVSD_HAL_DBG_ERROR (0x00000001) +#define AVSD_HAL_DBG_ASSERT (0x00000002) +#define AVSD_HAL_DBG_WARNNING (0x00000004) +#define AVSD_HAL_DBG_TRACE (0x00000008) + +#define AVSD_HAL_DBG_OFFSET (0x00000010) +#define AVSD_HAL_DBG_WAIT (0x00000020) + +#define AVSD_DBG_HARD_MODE (0x00010000) +#define AVSD_DBG_PROFILE_ID (0x00020000) + +extern RK_U32 avsd_hal_debug; + +#define AVSD_HAL_DBG(level, fmt, ...)\ +do {\ + if (level & avsd_hal_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + +#define AVSD_HAL_TRACE(fmt, ...)\ +do {\ + if (AVSD_HAL_DBG_TRACE & avsd_hal_debug)\ + { mpp_log_f(fmt, ## __VA_ARGS__); }\ +} while (0) + + +#define INP_CHECK(ret, val, ...)\ +do{\ + if ((val)) { \ + ret = MPP_ERR_INIT; \ + AVSD_HAL_DBG(AVSD_HAL_DBG_WARNNING, "input empty(%d).\n", __LINE__); \ + goto __RETURN; \ + }\ +} while (0) + + +#define FUN_CHECK(val)\ +do{\ + if ((val) < 0) {\ + AVSD_HAL_DBG(AVSD_HAL_DBG_WARNNING, "Function error(%d).\n", __LINE__); \ + goto __FAILED; \ + }\ +} while (0) + + +//!< memory malloc check +#define MEM_CHECK(ret, val, ...)\ +do{\ + if (!(val)) {\ + ret = MPP_ERR_MALLOC; \ + mpp_err_f("malloc buffer error(%d).\n", __LINE__); \ + goto __FAILED; \ + }\ +} while (0) + + +#define FIELDPICTURE 0 +#define FRAMEPICTURE 1 + +enum { + IFRAME = 0, + PFRAME = 1, + BFRAME = 2 +}; + +typedef struct avsd_hal_picture_t { + RK_U32 valid; + RK_U32 pic_type; + RK_U32 pic_code_type; + RK_U32 picture_distance; + + RK_S32 slot_idx; +} AvsdHalPic_t; + + +typedef struct avsd_hal_ctx_t { + MppHalApi hal_api; + MppBufSlots frame_slots; + MppBufSlots packet_slots; + MppBufferGroup buf_group; + + MppCodingType coding; + MppCbCtx *dec_cb; + MppDev dev; + + AvsdSyntax_t syn; + RK_U32 *p_regs; + RK_U32 regs_num; + MppBuffer mv_buf; + + AvsdHalPic_t pic[3]; + //!< add for control + RK_U32 first_field; + RK_U32 prev_pic_structure; + RK_U32 prev_pic_code_type; + RK_S32 future2prev_past_dist; + RK_S32 work0; + RK_S32 work1; + RK_S32 work_out; + RK_U32 data_offset; + + RK_U32 frame_no; +} AvsdHalCtx_t; + + +#ifdef __cplusplus +extern "C" { +#endif + +RK_U32 avsd_ver_align(RK_U32 val); +RK_U32 avsd_hor_align(RK_U32 val); +RK_U32 avsd_len_align(RK_U32 val); +RK_S32 get_queue_pic(AvsdHalCtx_t *p_hal); +RK_S32 get_packet_fd(AvsdHalCtx_t *p_hal, RK_S32 idx); +RK_S32 get_frame_fd(AvsdHalCtx_t *p_hal, RK_S32 idx); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_AVSD_COMMON_H__*/ diff --git a/mpp/hal/rkdec/avsd/hal_avsd_reg.c b/mpp/hal/rkdec/avsd/hal_avsd_plus.c similarity index 64% rename from mpp/hal/rkdec/avsd/hal_avsd_reg.c rename to mpp/hal/rkdec/avsd/hal_avsd_plus.c index 0e2ca8ed..9c22037f 100644 --- a/mpp/hal/rkdec/avsd/hal_avsd_reg.c +++ b/mpp/hal/rkdec/avsd/hal_avsd_plus.c @@ -1,75 +1,44 @@ /* -* -* 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. -*/ + * 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 "hal_avsd_reg" +#define MODULE_TAG "hal_avsd_plus" + +#include #include "mpp_common.h" +#include "mpp_mem.h" +#include "mpp_device.h" #include "avsd_syntax.h" #include "hal_avsd_api.h" -#include "hal_avsd_reg.h" +#include "hal_avsd_plus_reg.h" +#include "hal_avsd_plus.h" #include "mpp_dec_cb_param.h" +#include "hal_avsd_base.h" -static RK_S32 get_queue_pic(AvsdHalCtx_t *p_hal) -{ - RK_U32 i = 0; - RK_S32 ret_idx = -1; - - for (i = 0; i < MPP_ARRAY_ELEMS(p_hal->pic); i++) { - if (!p_hal->pic[i].valid) { - ret_idx = i; - p_hal->pic[i].valid = 1; - break; - } - } - - return ret_idx; -} - -static RK_S32 get_packet_fd(AvsdHalCtx_t *p_hal, RK_S32 idx) -{ - RK_S32 ret_fd = 0; - MppBuffer mbuffer = NULL; - - mpp_buf_slot_get_prop(p_hal->packet_slots, idx, SLOT_BUFFER, &mbuffer); - ret_fd = mpp_buffer_get_fd(mbuffer); - - return ret_fd; -} -static RK_S32 get_frame_fd(AvsdHalCtx_t *p_hal, RK_S32 idx) -{ - RK_S32 ret_fd = 0; - MppBuffer mbuffer = NULL; - - mpp_buf_slot_get_prop(p_hal->frame_slots, idx, SLOT_BUFFER, &mbuffer); - ret_fd = mpp_buffer_get_fd(mbuffer); - - return ret_fd; -} /*! -*********************************************************************** -* \brief -* init decoder parameters -*********************************************************************** -*/ + *********************************************************************** + * \brief + * init decoder parameters + *********************************************************************** + */ //extern "C" MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal) { - AvsdRegs_t *p_regs = (AvsdRegs_t *)p_hal->p_regs; + AvsdPlusRegs_t *p_regs = (AvsdPlusRegs_t *)p_hal->p_regs; p_regs->sw02.dec_out_endian = 1; p_regs->sw02.dec_in_endian = 0; @@ -107,19 +76,12 @@ MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal) return MPP_OK; } -/*! -*********************************************************************** -* \brief -* generate register parameters -*********************************************************************** -*/ -//extern "C" -MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) +static MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) { MPP_RET ret = MPP_ERR_UNKNOW; AvsdSyntax_t *p_syn = &p_hal->syn; - AvsdRegs_t *p_regs = (AvsdRegs_t *)p_hal->p_regs; + AvsdPlusRegs_t *p_regs = (AvsdPlusRegs_t *)p_hal->p_regs; //!< set wrok_out pic info if (p_hal->work_out < 0) { @@ -138,6 +100,7 @@ MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) p_work_out->picture_distance = p_syn->pp.pictureDistance; } //!< set register + set_defalut_parameters(p_hal); p_regs->sw04.pic_mb_width = (p_syn->pp.horizontalSize + 15) >> 4; p_regs->sw03.dec_mode = 11; //!< DEC_MODE_AVS @@ -156,7 +119,7 @@ MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) } p_regs->sw04.pic_mb_height_p = (p_syn->pp.verticalSize + 15) >> 4; - p_regs->sw07.avs_h264_h_ext = (p_syn->pp.verticalSize + 15) >> 12; + p_regs->sw07.avs_h_ext = (p_syn->pp.verticalSize + 15) >> 12; if (p_syn->pp.picCodingType == BFRAME) { p_regs->sw03.pic_b_e = 1; @@ -169,6 +132,7 @@ MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) p_hal->data_offset = (p_hal->data_offset & ~0x7); p_regs->sw12.rlc_vlc_base = get_packet_fd(p_hal, task->input) | (p_hal->data_offset << 10); p_regs->sw06.stream_len = p_syn->bitstream_size - p_hal->data_offset; + p_regs->sw03.pic_fixed_quant = p_syn->pp.fixedPictureQp; p_regs->sw06.init_qp = p_syn->pp.pictureQp; //!< AVS Plus stuff @@ -492,8 +456,13 @@ MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) (p_syn->pp.picCodingType == BFRAME && p_hal->prev_pic_structure)) { p_regs->sw41.dir_mv_base = mpp_buffer_get_fd(p_hal->mv_buf); } else { - RK_U32 offset = MPP_ALIGN(p_syn->pp.horizontalSize, 16) - * MPP_ALIGN(p_syn->pp.verticalSize, 16) / 32; + RK_U32 frame_width = 0, frame_height = 0, offset = 0; + frame_width = (p_syn->pp.horizontalSize + 15) >> 4; + if (p_syn->pp.progressiveFrame) + frame_height = (p_syn->pp.verticalSize + 15) >> 4; + else + frame_height = 2 * ((p_syn->pp.verticalSize + 31) >> 5); + offset = MPP_ALIGN(frame_width * frame_height / 2, 2) * 16; p_regs->sw41.dir_mv_base = mpp_buffer_get_fd(p_hal->mv_buf) | (offset << 10); } //!< AVS Plus stuff @@ -522,14 +491,7 @@ __FAILED: return ret; } -/*! -*********************************************************************** -* \brief -* init decoder parameters -*********************************************************************** -*/ -//extern "C" -MPP_RET update_parameters(AvsdHalCtx_t *p_hal) +static MPP_RET update_parameters(AvsdHalCtx_t *p_hal) { AvsdSyntax_t *p_syn = &p_hal->syn; @@ -552,3 +514,295 @@ MPP_RET update_parameters(AvsdHalCtx_t *p_hal) return MPP_OK; } + +static MPP_RET repeat_other_field(AvsdHalCtx_t *p_hal, HalTaskInfo *task) +{ + RK_U8 i = 0; + RK_U8 *pdata = NULL; + MppBuffer mbuffer = NULL; + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdPlusRegs_t *p_regs = (AvsdPlusRegs_t *)p_hal->p_regs; + + //!< re-find start code and calculate offset + p_hal->data_offset = p_regs->sw12.rlc_vlc_base >> 10; + p_hal->data_offset += p_hal->syn.bitstream_offset; + p_hal->data_offset -= MPP_MIN(p_hal->data_offset, 8); + + mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &mbuffer); + pdata = (RK_U8 *)mpp_buffer_get_ptr(mbuffer) + p_hal->data_offset; + + while (i < 16) { + if (pdata[i] == 0 && pdata[i + 1] == 0 && pdata[i + 2] == 1) { + p_hal->data_offset += i; + break; + } + i++; + } + AVSD_HAL_DBG(AVSD_HAL_DBG_OFFSET, "frame_no=%d, i=%d, offset=%d\n", + p_hal->frame_no, i, p_hal->data_offset); + //!< re-generate register + FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); + hal_avsd_plus_start((void *)p_hal, task); + hal_avsd_plus_wait((void *)p_hal, task); + + return ret = MPP_OK; +__FAILED: + return ret; +} + +/*! + *********************************************************************** + * \brief + * init + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_init(void *decoder, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + RK_U32 buf_size = 0; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("AVS_plus In."); + + buf_size = (1920 * 1088) * 2; + FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->mv_buf, buf_size)); + + p_hal->p_regs = mpp_calloc_size(RK_U32, sizeof(AvsdPlusRegs_t)); + MEM_CHECK(ret, p_hal->p_regs); + + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align); + + p_hal->regs_num = 60; + //!< initial for control + p_hal->first_field = 1; + p_hal->prev_pic_structure = 0; //!< field + + memset(p_hal->pic, 0, sizeof(p_hal->pic)); + p_hal->work_out = -1; + p_hal->work0 = -1; + p_hal->work1 = -1; + + AVSD_HAL_TRACE("Out."); + (void)cfg; + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! + *********************************************************************** + * \brief + * deinit + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_deinit(void *decoder) +{ + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + if (p_hal->mv_buf) { + mpp_buffer_put(p_hal->mv_buf); + p_hal->mv_buf = NULL; + } + MPP_FREE(p_hal->p_regs); + + AVSD_HAL_TRACE("Out."); + return MPP_OK; +} +/*! + *********************************************************************** + * \brief + * generate register + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_gen_regs(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __RETURN; + } + p_hal->data_offset = p_hal->syn.bitstream_offset; + + FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); +__RETURN: + AVSD_HAL_TRACE("Out."); + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! + *********************************************************************** + * \brief h + * start hard + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_start(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + INP_CHECK(ret, NULL == decoder); + + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __RETURN; + } + + do { + MppDevRegWrCfg wr_cfg; + MppDevRegRdCfg rd_cfg; + + wr_cfg.reg = p_hal->p_regs; + wr_cfg.size = AVSD_REGISTERS * sizeof(RK_U32); + wr_cfg.offset = 0; + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg); + if (ret) { + mpp_err_f("set register write failed %d\n", ret); + break; + } + + rd_cfg.reg = p_hal->p_regs; + rd_cfg.size = AVSD_REGISTERS * sizeof(RK_U32); + rd_cfg.offset = 0; + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg); + if (ret) { + mpp_err_f("set register read failed %d\n", ret); + break; + } + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL); + if (ret) { + mpp_err_f("send cmd failed %d\n", ret); + break; + } + } while (0); + + p_hal->frame_no++; + +__RETURN: + AVSD_HAL_TRACE("Out."); + + return ret; +} +/*! + *********************************************************************** + * \brief + * wait hard + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_wait(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + INP_CHECK(ret, NULL == decoder); + + if (task->dec.flags.parse_err || + task->dec.flags.ref_err) { + goto __SKIP_HARD; + } + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL); + if (ret) + mpp_err_f("poll cmd failed %d\n", ret); + +__SKIP_HARD: + if (p_hal->dec_cb) { + DecCbHalDone param; + + param.task = (void *)&task->dec; + param.regs = (RK_U32 *)p_hal->p_regs; + param.hard_err = (!((AvsdPlusRegs_t *)p_hal->p_regs)->sw01.dec_rdy_int); + + mpp_callback(p_hal->dec_cb, ¶m); + } + update_parameters(p_hal); + memset(&p_hal->p_regs[1], 0, sizeof(RK_U32)); + if (!p_hal->first_field && p_hal->syn.pp.pictureStructure == FIELDPICTURE && + !task->dec.flags.parse_err && !task->dec.flags.ref_err) { + repeat_other_field(p_hal, task); + } + +__RETURN: + AVSD_HAL_TRACE("Out."); + + return ret; +} +/*! + *********************************************************************** + * \brief + * reset + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_reset(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + p_hal->first_field = 1; + p_hal->prev_pic_structure = 0; //!< field + + memset(p_hal->pic, 0, sizeof(p_hal->pic)); + p_hal->work_out = -1; + p_hal->work0 = -1; + p_hal->work1 = -1; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} +/*! + *********************************************************************** + * \brief + * flush + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_flush(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} +/*! + *********************************************************************** + * \brief + * control + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_plus_control(void *decoder, MpiCmd cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + (void)cmd_type; + (void)param; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} diff --git a/mpp/hal/rkdec/avsd/hal_avsd_plus.h b/mpp/hal/rkdec/avsd/hal_avsd_plus.h new file mode 100644 index 00000000..40bdacc5 --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_plus.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#ifndef __HAL_AVSD_PLUS_H__ +#define __HAL_AVSD_PLUS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET hal_avsd_plus_init (void *decoder, MppHalCfg *cfg); +MPP_RET hal_avsd_plus_deinit (void *decoder); +MPP_RET hal_avsd_plus_gen_regs(void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_plus_start (void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_plus_wait (void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_plus_reset (void *decoder); +MPP_RET hal_avsd_plus_flush (void *decoder); +MPP_RET hal_avsd_plus_control (void *decoder, MpiCmd cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_AVSD_PLUS_H__*/ diff --git a/mpp/hal/rkdec/avsd/hal_avsd_reg.h b/mpp/hal/rkdec/avsd/hal_avsd_plus_reg.h similarity index 67% rename from mpp/hal/rkdec/avsd/hal_avsd_reg.h rename to mpp/hal/rkdec/avsd/hal_avsd_plus_reg.h index ebcf33b9..e9bf8a1c 100644 --- a/mpp/hal/rkdec/avsd/hal_avsd_reg.h +++ b/mpp/hal/rkdec/avsd/hal_avsd_plus_reg.h @@ -1,18 +1,18 @@ /* -* 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. -*/ + * 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. + */ #ifndef __HAL_AVSD_REG_H__ #define __HAL_AVSD_REG_H__ @@ -24,96 +24,6 @@ #include "hal_avsd_api.h" #include "avsd_syntax.h" -#define AVSD_HAL_DBG_ERROR (0x00000001) -#define AVSD_HAL_DBG_ASSERT (0x00000002) -#define AVSD_HAL_DBG_WARNNING (0x00000004) -#define AVSD_HAL_DBG_TRACE (0x00000008) - -#define AVSD_HAL_DBG_OFFSET (0x00010000) - -extern RK_U32 avsd_hal_debug; - -#define AVSD_HAL_DBG(level, fmt, ...)\ -do {\ - if (level & avsd_hal_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - -#define AVSD_HAL_TRACE(fmt, ...)\ -do {\ - if (AVSD_HAL_DBG_TRACE & avsd_hal_debug)\ - { mpp_log_f(fmt, ## __VA_ARGS__); }\ -} while (0) - -#define INP_CHECK(ret, val, ...)\ -do{\ - if ((val)) { \ - ret = MPP_ERR_INIT; \ - AVSD_HAL_DBG(AVSD_HAL_DBG_WARNNING, "input empty(%d).\n", __LINE__); \ - goto __RETURN; \ - }\ -} while (0) - -#define FUN_CHECK(val)\ -do{\ - if ((val) < 0) {\ - AVSD_HAL_DBG(AVSD_HAL_DBG_WARNNING, "Function error(%d).\n", __LINE__); \ - goto __FAILED; \ - }\ -} while (0) - -//!< memory malloc check -#define MEM_CHECK(ret, val, ...)\ -do{\ - if (!(val)) {\ - ret = MPP_ERR_MALLOC; \ - mpp_err_f("malloc buffer error(%d).\n", __LINE__); \ - goto __FAILED; \ - }\ -} while (0) - -#define FIELDPICTURE 0 -#define FRAMEPICTURE 1 - -enum { - IFRAME = 0, - PFRAME = 1, - BFRAME = 2 -}; - -typedef struct avsd_hal_picture_t { - RK_U32 valid; - RK_U32 pic_type; - RK_U32 pic_code_type; - RK_U32 picture_distance; - - RK_S32 slot_idx; -} AvsdHalPic_t; - -typedef struct avsd_hal_ctx_t { - MppBufSlots frame_slots; - MppBufSlots packet_slots; - MppBufferGroup buf_group; - MppCbCtx *dec_cb; - MppDev dev; - AvsdSyntax_t syn; - RK_U32 *p_regs; - MppBuffer mv_buf; - - AvsdHalPic_t pic[3]; - //!< add for control - RK_U32 first_field; - RK_U32 prev_pic_structure; - RK_U32 prev_pic_code_type; - RK_S32 future2prev_past_dist; - RK_S32 work0; - RK_S32 work1; - RK_S32 work_out; - RK_U32 data_offset; - - RK_U32 frame_no; -} AvsdHalCtx_t; - #define AVSD_REGISTERS 60 typedef struct { @@ -130,13 +40,13 @@ typedef struct { RK_U32 dec_rdy_int : 1; RK_U32 dec_bus_int : 1; RK_U32 dec_buffer_int : 1; - RK_U32 dec_aso_int : 1; + RK_U32 reserve3 : 1; RK_U32 dec_error_int : 1; - RK_U32 dec_slice_int : 1; + RK_U32 reserve4 : 1; RK_U32 dec_timeout : 1; - RK_U32 reserve3 : 5; + RK_U32 reserve5 : 5; RK_U32 dec_pic_inf : 1; - RK_U32 reserve4 : 7; + RK_U32 reserve6 : 7; } sw01; union { struct { @@ -170,22 +80,21 @@ typedef struct { RK_U32 dec_axi_wr_id : 8; RK_U32 dec_ahb_hlock_e : 1; RK_U32 picord_count_e : 1; - RK_U32 seq_mbaff_e : 1; + RK_U32 reserve0 : 1; RK_U32 reftopfirst_e : 1; RK_U32 write_mvs_e : 1; RK_U32 pic_fixed_quant : 1; RK_U32 filtering_dis : 1; RK_U32 dec_out_dis : 1; RK_U32 ref_topfield_e : 1; - RK_U32 sorenson_e : 1; + RK_U32 reserve1 : 1; RK_U32 fwd_interlace_e : 1; RK_U32 pic_topfiled_e : 1; RK_U32 pic_inter_e : 1; RK_U32 pic_b_e : 1; RK_U32 pic_fieldmode_e : 1; RK_U32 pic_interlace_e : 1; - RK_U32 pjpeg_e : 1; - RK_U32 divx3_e : 1; + RK_U32 reserve2 : 2; RK_U32 skip_mode : 1; RK_U32 rlc_mode_e : 1; RK_U32 dec_mode : 4; @@ -209,7 +118,6 @@ typedef struct { RK_U32 strm_start_bit : 6; }; } sw05; - struct { RK_U32 stream_len : 24; RK_U32 stream_len_ext : 1; @@ -218,7 +126,7 @@ typedef struct { } sw06; struct { RK_U32 reserve0 : 25; - RK_U32 avs_h264_h_ext : 1; + RK_U32 avs_h_ext : 1; RK_U32 reserve1 : 6; } sw07; RK_U32 sw08; @@ -301,7 +209,6 @@ typedef struct { RK_U32 ref_dist_cur_2 : 16; RK_U32 ref_dist_cur_3 : 16; } sw31; - struct { RK_U32 ref_invd_col_0 : 16; RK_U32 ref_invd_col_1 : 16; @@ -399,27 +306,13 @@ typedef struct { struct { RK_U32 refbu_bot_sum : 16; RK_U32 refbu_top_sum : 16; - }; + } sw56; RK_U32 sw57; struct { RK_U32 reserve0 : 31; RK_U32 serv_merge_dis : 1; } sw58; RK_U32 sw59; -} AvsdRegs_t; +} AvsdPlusRegs_t; - - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal); -MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task); -MPP_RET update_parameters(AvsdHalCtx_t *p_hal); -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_AVSD_REG_H__*/ +#endif /*__HAL_AVSD_PLUS_REG_H__*/ diff --git a/mpp/hal/rkdec/avsd/hal_avsd_vdpu1.c b/mpp/hal/rkdec/avsd/hal_avsd_vdpu1.c new file mode 100644 index 00000000..4bf9e4ef --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_vdpu1.c @@ -0,0 +1,728 @@ +/* + * 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 "hal_avsd_vdpu1" + +#include + +#include "mpp_debug.h" +#include "mpp_common.h" +#include "mpp_mem.h" +#include "mpp_device.h" +#include "mpp_dec_cb_param.h" + +#include "hal_avsd_base.h" +#include "hal_avsd_vdpu1.h" +#include "hal_avsd_vdpu1_reg.h" + +static MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal) +{ + AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs; + + p_regs->sw02.dec_out_endian = 1; + p_regs->sw02.dec_in_endian = 0; + p_regs->sw02.dec_strendian_e = 1; + p_regs->sw02.dec_max_burst = 16; + p_regs->sw02.dec_scmd_dis = 0; + + p_regs->sw02.dec_adv_pre_dis = 0; + p_regs->sw55.apf_threshold = 8; + p_regs->sw02.dec_latency = 0; + + p_regs->sw02.dec_data_disc_e = 0; + p_regs->sw02.dec_outswap32_e = 1; + p_regs->sw02.dec_inswap32_e = 1; + p_regs->sw02.dec_strswap32_e = 1; + + p_regs->sw02.dec_timeout_e = 0; + p_regs->sw02.dec_clk_gate_e = 1; + p_regs->sw01.dec_irq_dis = 0; + + p_regs->sw02.dec_axi_rd_id = 0xFF; + p_regs->sw03.dec_axi_wr_id = 0; + + p_regs->sw49.pred_bc_tap_0_0 = 0x3FF; + p_regs->sw49.pred_bc_tap_0_1 = 5; + p_regs->sw49.pred_bc_tap_0_2 = 5; + p_regs->sw34.pred_bc_tap_0_3 = 0x3FF; + p_regs->sw34.pred_bc_tap_1_0 = 1; + p_regs->sw34.pred_bc_tap_1_1 = 7; + p_regs->sw35.pred_bc_tap_1_2 = 7; + p_regs->sw35.pred_bc_tap_1_3 = 1; + + p_regs->sw02.tiled_mode_lsb = 0; + + return MPP_OK; +} + +static MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AvsdSyntax_t *p_syn = &p_hal->syn; + AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs; + + set_defalut_parameters(p_hal); + + p_regs->sw02.dec_timeout_e = 1; + p_regs->sw02.dec_clk_gate_e = 1; + p_regs->sw01.dec_irq_dis = 0; + p_regs->sw03.rlc_mode_e = 0; + + //!< set wrok_out pic info + if (p_hal->work_out < 0) { + p_hal->work_out = get_queue_pic(p_hal); + if (p_hal->work_out < 0) { + ret = MPP_NOK; + mpp_err_f("cannot get a pic_info buffer.\n"); + goto __FAILED; + } + } + { + AvsdHalPic_t *p_work_out = &p_hal->pic[p_hal->work_out]; + + p_work_out->slot_idx = task->output; + p_work_out->pic_code_type = p_syn->pp.picCodingType; + p_work_out->picture_distance = p_syn->pp.pictureDistance; + } + //!< set register + p_regs->sw04.pic_mb_width = (p_syn->pp.horizontalSize + 15) >> 4; + p_regs->sw03.dec_mode = 11; //!< DEC_MODE_AVS + + if (p_syn->pp.pictureStructure == FRAMEPICTURE) { + p_regs->sw03.pic_interlace_e = 0; + p_regs->sw03.pic_fieldmode_e = 0; + p_regs->sw03.pic_topfiled_e = 0; + } else { + p_regs->sw03.pic_interlace_e = 1; + p_regs->sw03.pic_fieldmode_e = 1; + p_regs->sw03.pic_topfiled_e = p_hal->first_field; + } + + p_regs->sw04.pic_mb_height_p = (p_syn->pp.verticalSize + 15) >> 4; + //p_regs->sw07.avs_h_ext = (p_syn->pp.verticalSize + 15) >> 12; + + if (p_syn->pp.picCodingType == BFRAME) { + p_regs->sw03.pic_b_e = 1; + } else { + p_regs->sw03.pic_b_e = 0; + } + p_regs->sw03.pic_inter_e = (p_syn->pp.picCodingType != IFRAME) ? 1 : 0; + + mpp_log("data_offset %x\n", p_hal->data_offset); + p_regs->sw05.strm_start_bit = 8 * (p_hal->data_offset & 0x7); + p_hal->data_offset = (p_hal->data_offset & ~0x7); + p_regs->sw12.rlc_vlc_base = get_packet_fd(p_hal, task->input); + mpp_dev_set_reg_offset(p_hal->dev, 12, p_hal->data_offset); + p_regs->sw06.stream_len = p_syn->bitstream_size - p_hal->data_offset; + p_regs->sw03.pic_fixed_quant = p_syn->pp.fixedPictureQp; + p_regs->sw06.init_qp = p_syn->pp.pictureQp; + + p_regs->sw13.dec_out_base = get_frame_fd(p_hal, task->output); + if (p_syn->pp.pictureStructure == FIELDPICTURE && !p_hal->first_field) { + //!< start of bottom field line + mpp_dev_set_reg_offset(p_hal->dev, 13, p_syn->pp.horizontalSize); + } + { + RK_S32 tmp_fwd = -1; + RK_S32 refer0 = -1; + RK_S32 refer1 = -1; + + tmp_fwd = (p_hal->work1 < 0) ? p_hal->work0 : p_hal->work1; + tmp_fwd = (tmp_fwd < 0) ? p_hal->work_out : tmp_fwd; + + refer0 = (task->refer[0] < 0) ? task->output : task->refer[0]; + refer1 = (task->refer[1] < 0) ? refer0 : task->refer[1]; + if (!p_hal->first_field + && p_syn->pp.pictureStructure == FIELDPICTURE + && p_syn->pp.picCodingType != BFRAME) { + p_regs->sw14.refer0_base = get_frame_fd(p_hal, task->output); + p_regs->sw15.refer1_base = get_frame_fd(p_hal, refer0); + p_regs->sw16.refer2_base = get_frame_fd(p_hal, refer0); + p_regs->sw17.refer3_base = get_frame_fd(p_hal, refer1); + } else { + p_regs->sw14.refer0_base = get_frame_fd(p_hal, refer0); + p_regs->sw15.refer1_base = get_frame_fd(p_hal, refer0); + p_regs->sw16.refer2_base = get_frame_fd(p_hal, refer1); + p_regs->sw17.refer3_base = get_frame_fd(p_hal, refer1); + } + } + //!< block distances + if (p_syn->pp.pictureStructure == FRAMEPICTURE) { + if (p_syn->pp.picCodingType == BFRAME) { + RK_S32 tmp = 0; + //!< current to future anchor + if (p_hal->work0 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_syn->pp.pictureDistance + 512) & 0x1FF; + } + //!< prevent division by zero + if (!tmp) tmp = 2; + p_regs->sw31.ref_dist_cur_2 = tmp; + p_regs->sw31.ref_dist_cur_3 = tmp; + p_regs->sw29.ref_invd_cur_2 = 512 / tmp; + p_regs->sw29.ref_invd_cur_3 = 512 / tmp; + + //!< current to past anchor + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + p_regs->sw30.ref_dist_cur_0 = tmp; + p_regs->sw30.ref_dist_cur_1 = tmp; + p_regs->sw28.ref_invd_cur_0 = 512 / tmp; + p_regs->sw28.ref_invd_cur_1 = 512 / tmp; + //!< future anchor to past anchor + if (p_hal->work0 >= 0 && p_hal->work1 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + tmp = 16384 / tmp; + p_regs->sw32.ref_invd_col_0 = tmp; + p_regs->sw32.ref_invd_col_1 = tmp; + //!< future anchor to previous past anchor + tmp = p_hal->future2prev_past_dist; + tmp = 16384 / tmp; + p_regs->sw33.ref_invd_col_2 = tmp; + p_regs->sw33.ref_invd_col_3 = tmp; + } else { + RK_S32 tmp = 0; + //!< current to past anchor + if (p_hal->work0 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF; + } + if (!tmp) tmp = 2; + p_regs->sw30.ref_dist_cur_0 = tmp; + p_regs->sw30.ref_dist_cur_1 = tmp; + p_regs->sw28.ref_invd_cur_0 = 512 / tmp; + p_regs->sw28.ref_invd_cur_1 = 512 / tmp; + //!< current to previous past anchor + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + //!< this will become "future to previous past" for next B + p_hal->future2prev_past_dist = tmp; + + p_regs->sw31.ref_dist_cur_2 = tmp; + p_regs->sw31.ref_dist_cur_3 = tmp; + p_regs->sw29.ref_invd_cur_2 = 512 / tmp; + p_regs->sw29.ref_invd_cur_3 = 512 / tmp; + + p_regs->sw32.ref_invd_col_0 = 0; + p_regs->sw32.ref_invd_col_1 = 0; + p_regs->sw33.ref_invd_col_2 = 0; + p_regs->sw33.ref_invd_col_3 = 0; + } + } else { + //!< field interlaced + if (p_syn->pp.picCodingType == BFRAME) { + RK_S32 tmp = 0; + //!< block distances + if (p_hal->work0 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_syn->pp.pictureDistance + 512) & 0x1FF; + } + //!< prevent division by zero + if (!tmp) tmp = 2; + + if (p_hal->first_field) { + p_regs->sw31.ref_dist_cur_2 = tmp; + p_regs->sw31.ref_dist_cur_3 = tmp + 1; + p_regs->sw29.ref_invd_cur_2 = 512 / tmp; + p_regs->sw29.ref_invd_cur_3 = 512 / (tmp + 1); + } else { + p_regs->sw31.ref_dist_cur_2 = tmp - 1; + p_regs->sw31.ref_dist_cur_3 = tmp; + p_regs->sw29.ref_invd_cur_2 = 512 / (tmp - 1); + p_regs->sw29.ref_invd_cur_3 = 512 / tmp; + } + + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + if (p_hal->first_field) { + p_regs->sw30.ref_dist_cur_0 = (tmp - 1); + p_regs->sw30.ref_dist_cur_1 = tmp; + p_regs->sw28.ref_invd_cur_0 = 512 / (tmp - 1); + p_regs->sw28.ref_invd_cur_1 = 512 / tmp; + } else { + p_regs->sw30.ref_dist_cur_0 = tmp; + p_regs->sw30.ref_dist_cur_1 = tmp + 1; + p_regs->sw28.ref_invd_cur_0 = 512 / tmp; + p_regs->sw28.ref_invd_cur_1 = 512 / (tmp + 1); + } + + if (p_hal->work0 >= 0 && p_hal->work1 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + + if (p_syn->pp.pbFieldEnhancedFlag && !p_hal->first_field) { + //!< in this case, BlockDistanceRef is different with before, the mvRef points to top field + p_regs->sw32.ref_invd_col_0 = 16384 / (tmp - 1); + p_regs->sw32.ref_invd_col_1 = 16384 / tmp; + + //!< future anchor to previous past anchor + tmp = p_hal->future2prev_past_dist; + + p_regs->sw33.ref_invd_col_2 = 16384 / (tmp - 1); + p_regs->sw33.ref_invd_col_3 = 16384 / tmp; + } else { + if (p_hal->first_field) { + p_regs->sw32.ref_invd_col_0 = 16384 / (tmp - 1); + p_regs->sw32.ref_invd_col_1 = 16384 / tmp; + } else { + p_regs->sw32.ref_invd_col_0 = 16384; + p_regs->sw32.ref_invd_col_1 = 16384 / tmp; + p_regs->sw33.ref_invd_col_2 = 16384 / (tmp + 1); + } + + //!< future anchor to previous past anchor + tmp = p_hal->future2prev_past_dist; + + if (p_hal->first_field) { + p_regs->sw33.ref_invd_col_2 = 16384 / (tmp - 1); + p_regs->sw33.ref_invd_col_3 = 16384 / tmp; + } else { + p_regs->sw33.ref_invd_col_3 = 16384 / tmp; + } + } + } else { + RK_S32 tmp = 0; + if (p_hal->work0 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF; + } + if (!tmp) tmp = 2; + + if (!p_hal->first_field) { + p_regs->sw30.ref_dist_cur_0 = 1; + p_regs->sw31.ref_dist_cur_2 = tmp + 1; + + p_regs->sw28.ref_invd_cur_0 = 512; + p_regs->sw29.ref_invd_cur_2 = 512 / (tmp + 1); + } else { + p_regs->sw30.ref_dist_cur_0 = tmp - 1; + p_regs->sw28.ref_invd_cur_0 = 512 / (tmp - 1); + } + p_regs->sw30.ref_dist_cur_1 = tmp; + p_regs->sw28.ref_invd_cur_1 = 512 / tmp; + + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + //!< this will become "future to previous past" for next B + p_hal->future2prev_past_dist = tmp; + if (p_hal->first_field) { + p_regs->sw31.ref_dist_cur_2 = tmp - 1; + p_regs->sw31.ref_dist_cur_3 = tmp; + + p_regs->sw29.ref_invd_cur_2 = 512 / (tmp - 1); + p_regs->sw29.ref_invd_cur_3 = 512 / tmp; + } else { + p_regs->sw31.ref_dist_cur_3 = tmp; + p_regs->sw29.ref_invd_cur_3 = 512 / tmp; + } + + p_regs->sw32.ref_invd_col_0 = 0; + p_regs->sw32.ref_invd_col_1 = 0; + p_regs->sw33.ref_invd_col_2 = 0; + p_regs->sw33.ref_invd_col_3 = 0; + } + } + + p_regs->sw48.startmb_x = 0; + p_regs->sw48.startmb_y = 0; + + p_regs->sw03.filtering_dis = p_syn->pp.loopFilterDisable; + p_regs->sw05.alpha_offset = p_syn->pp.alphaOffset; + p_regs->sw05.beta_offset = p_syn->pp.betaOffset; + p_regs->sw03.skip_mode = p_syn->pp.skipModeFlag; + p_regs->sw04.pic_refer_flag = p_syn->pp.pictureReferenceFlag; + + if (p_syn->pp.picCodingType == PFRAME + || (p_syn->pp.picCodingType == IFRAME && !p_hal->first_field)) { + p_regs->sw03.write_mvs_e = 1; + } else { + p_regs->sw03.write_mvs_e = 0; + } + //!< set mv base + p_regs->sw41.dir_mv_base = mpp_buffer_get_fd(p_hal->mv_buf); + if (p_hal->first_field || + (p_syn->pp.picCodingType == BFRAME && p_hal->prev_pic_structure)) { + } else { + RK_U32 frame_width = 0, frame_height = 0, offset = 0; + frame_width = (p_syn->pp.horizontalSize + 15) >> 4; + if (p_syn->pp.progressiveFrame) + frame_height = (p_syn->pp.verticalSize + 15) >> 4; + else + frame_height = 2 * ((p_syn->pp.verticalSize + 31) >> 5); + offset = MPP_ALIGN(frame_width * frame_height / 2, 2) * 16; + mpp_dev_set_reg_offset(p_hal->dev, 41, offset); + } + { + RK_U32 pic_type = 0; + RK_U32 prev_anc_type = 0; + if (p_hal->work0 >= 0) { + pic_type = p_hal->pic[p_hal->work0].pic_type; + } + prev_anc_type = !pic_type || (!p_hal->first_field && !p_hal->prev_pic_structure); + p_regs->sw18.prev_anc_type = prev_anc_type; + } + //!< b-picture needs to know if future reference is field or frame coded + // p_regs->sw16.refer2_field_e = (!p_hal->prev_pic_structure) ? 1 : 0; + // p_regs->sw17.refer3_field_e = (!p_hal->prev_pic_structure) ? 1 : 0; + if (!p_hal->prev_pic_structure) { + mpp_dev_set_reg_offset(p_hal->dev, 16, 2); + mpp_dev_set_reg_offset(p_hal->dev, 17, 3); + } + + p_regs->sw03.dec_out_dis = 0; + p_regs->sw01.dec_e = 1; + + return MPP_OK; +__FAILED: + return ret; +} + +static MPP_RET update_parameters(AvsdHalCtx_t *p_hal) +{ + AvsdSyntax_t *p_syn = &p_hal->syn; + + if (p_syn->pp.pictureStructure == FRAMEPICTURE || !p_hal->first_field) { + p_hal->first_field = 1; + if (p_syn->pp.picCodingType != BFRAME) { + RK_S32 temp = p_hal->work1; + + p_hal->work1 = p_hal->work0; + p_hal->work0 = p_hal->work_out; + + p_hal->pic[p_hal->work_out].pic_type = p_syn->pp.picCodingType == IFRAME; + p_hal->work_out = temp; + p_hal->prev_pic_structure = p_syn->pp.pictureStructure; + } + p_hal->prev_pic_code_type = p_syn->pp.picCodingType; + } else { + p_hal->first_field = 0; + } + + return MPP_OK; +} + +static MPP_RET repeat_other_field(AvsdHalCtx_t *p_hal, HalTaskInfo *task) +{ + RK_U8 i = 0; + RK_U8 *pdata = NULL; + MppBuffer mbuffer = NULL; + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs; + + //!< re-find start code and calculate offset + p_hal->data_offset = p_regs->sw12.rlc_vlc_base >> 10; + p_hal->data_offset += p_hal->syn.bitstream_offset; + p_hal->data_offset -= MPP_MIN(p_hal->data_offset, 8); + + mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &mbuffer); + pdata = (RK_U8 *)mpp_buffer_get_ptr(mbuffer) + p_hal->data_offset; + + while (i < 16) { + if (pdata[i] == 0 && pdata[i + 1] == 0 && pdata[i + 2] == 1) { + p_hal->data_offset += i; + break; + } + i++; + } + AVSD_HAL_DBG(AVSD_HAL_DBG_OFFSET, "frame_no=%d, i=%d, offset=%d\n", + p_hal->frame_no, i, p_hal->data_offset); + //!< re-generate register + FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); + hal_avsd_vdpu1_start((void *)p_hal, task); + hal_avsd_vdpu1_wait((void *)p_hal, task); + + return ret = MPP_OK; +__FAILED: + return ret; +} + +/*! +*********************************************************************** +* \brief +* init +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_init(void *decoder, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + RK_U32 buf_size = 0; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("AVS_vdpu1 In."); + + buf_size = (1920 * 1088) * 2; + FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->mv_buf, buf_size)); + + p_hal->p_regs = mpp_calloc_size(RK_U32, sizeof(AvsdVdpu1Regs_t)); + MEM_CHECK(ret, p_hal->p_regs); + + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align); + + p_hal->regs_num = 60; + //!< initial for control + p_hal->first_field = 1; + p_hal->prev_pic_structure = 0; //!< field + + memset(p_hal->pic, 0, sizeof(p_hal->pic)); + p_hal->work_out = -1; + p_hal->work0 = -1; + p_hal->work1 = -1; + + AVSD_HAL_TRACE("Out."); + (void)cfg; + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief +* deinit +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_deinit(void *decoder) +{ + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + if (p_hal->mv_buf) { + mpp_buffer_put(p_hal->mv_buf); + p_hal->mv_buf = NULL; + } + MPP_FREE(p_hal->p_regs); + + AVSD_HAL_TRACE("Out."); + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* generate register +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_gen_regs(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __RETURN; + } + p_hal->data_offset = p_hal->syn.bitstream_offset; + + FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); +__RETURN: + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief h +* start hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_start(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __RETURN; + } + + do { + MppDevRegWrCfg wr_cfg; + MppDevRegRdCfg rd_cfg; + RK_U32 reg_size = 101 * sizeof(RK_U32); + + wr_cfg.reg = p_hal->p_regs; + wr_cfg.size = reg_size; + wr_cfg.offset = 0; + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg); + if (ret) { + mpp_err_f("set register write failed %d\n", ret); + break; + } + + rd_cfg.reg = p_hal->p_regs; + rd_cfg.size = reg_size; + rd_cfg.offset = 0; + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg); + if (ret) { + mpp_err_f("set register read failed %d\n", ret); + break; + } + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL); + if (ret) { + mpp_err_f("send cmd failed %d\n", ret); + break; + } + } while (0); + +__RETURN: + AVSD_HAL_TRACE("Out."); + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* wait hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_wait(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __SKIP_HARD; + } + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL); + if (ret) + mpp_err_f("poll cmd failed %d\n", ret); + +__SKIP_HARD: + if (p_hal->dec_cb) { + DecCbHalDone param; + + param.task = (void *)&task->dec; + param.regs = (RK_U32 *)p_hal->p_regs; + + if (!((AvsdVdpu1Regs_t *)p_hal->p_regs)->sw01.dec_rdy_int) { + param.hard_err = 1; + } else + param.hard_err = 0; + + mpp_callback(p_hal->dec_cb, ¶m); + AVSD_HAL_DBG(AVSD_HAL_DBG_WAIT, "reg[1]=%08x, ref=%d, dpberr=%d, harderr=%d\n", + p_hal->p_regs[1], task->dec.flags.used_for_ref, task->dec.flags.ref_err, param.hard_err); + } + update_parameters(p_hal); + memset(&p_hal->p_regs[1], 0, sizeof(RK_U32)); + if (!p_hal->first_field && p_hal->syn.pp.pictureStructure == FIELDPICTURE && + !task->dec.flags.parse_err && !task->dec.flags.ref_err) { + repeat_other_field(p_hal, task); + } + p_hal->frame_no++; + + AVSD_HAL_TRACE("Out."); + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_reset(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + p_hal->first_field = 1; + p_hal->prev_pic_structure = 0; //!< field + + memset(p_hal->pic, 0, sizeof(p_hal->pic)); + p_hal->work_out = -1; + p_hal->work0 = -1; + p_hal->work1 = -1; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_flush(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* control +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_vdpu1_control(void *decoder, MpiCmd cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + (void)cmd_type; + (void)param; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} diff --git a/mpp/hal/rkdec/avsd/hal_avsd_vdpu1.h b/mpp/hal/rkdec/avsd/hal_avsd_vdpu1.h new file mode 100644 index 00000000..cdc60de7 --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_vdpu1.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#ifndef __HAL_AVSD_VDPU1_H__ +#define __HAL_AVSD_VDPU1_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET hal_avsd_vdpu1_init(void *decoder, MppHalCfg *cfg); +MPP_RET hal_avsd_vdpu1_deinit(void *decoder); +MPP_RET hal_avsd_vdpu1_gen_regs(void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_vdpu1_start(void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_vdpu1_wait(void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_vdpu1_reset(void *decoder); +MPP_RET hal_avsd_vdpu1_flush(void *decoder); +MPP_RET hal_avsd_vdpu1_control(void *decoder, MpiCmd cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_AVSD_VDPU1_H__*/ diff --git a/mpp/hal/rkdec/avsd/hal_avsd_vdpu1_reg.h b/mpp/hal/rkdec/avsd/hal_avsd_vdpu1_reg.h new file mode 100644 index 00000000..4acdee7d --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_vdpu1_reg.h @@ -0,0 +1,247 @@ +/* + * 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. + */ + +#ifndef __HAL_AVSD_VDPU1_REG_H__ +#define __HAL_AVSD_VDPU1_REG_H__ + + +typedef struct { + RK_U32 sw00; + struct { + RK_U32 dec_e : 1; + RK_U32 reserve0 : 3; + RK_U32 dec_irq_dis : 1; + RK_U32 dec_abort_e : 1; + RK_U32 reserve1 : 2; + RK_U32 dec_irq : 1; + RK_U32 reserve2 : 2; + RK_U32 dec_abort_int : 1; + RK_U32 dec_rdy_int : 1; + RK_U32 dec_bus_int : 1; + RK_U32 dec_buffer_int : 1; + RK_U32 reserve3 : 1; + RK_U32 dec_error_int : 1; + RK_U32 reserve4 : 1; + RK_U32 dec_timeout : 1; + RK_U32 reserve5 : 5; + RK_U32 dec_pic_inf : 1; + RK_U32 reserve6 : 7; + } sw01; + union { + struct { + RK_U32 dec_max_burst : 5; + RK_U32 dec_scmd_dis : 1; + RK_U32 dec_adv_pre_dis : 1; + RK_U32 tiled_mode_lsb : 1; + RK_U32 dec_out_endian : 1; + RK_U32 dec_in_endian : 1; + RK_U32 dec_clk_gate_e : 1; + RK_U32 dec_latency : 6; + RK_U32 dec_out_tiled_e : 1; + RK_U32 dec_data_disc_e : 1; + RK_U32 dec_outswap32_e : 1; + RK_U32 dec_inswap32_e : 1; + RK_U32 dec_strendian_e : 1; + RK_U32 dec_strswap32_e : 1; + RK_U32 dec_timeout_e : 1; + RK_U32 dec_axi_rd_id : 8; + }; + struct { + RK_U32 reserve0 : 5; + RK_U32 priority_mode : 3; + RK_U32 reserve1 : 9; + RK_U32 tiled_mode_msb : 1; + RK_U32 dec_2chan_dis : 1; + RK_U32 reserve2 : 13; + }; + } sw02; + struct { + RK_U32 dec_axi_wr_id : 8; + RK_U32 dec_ahb_hlock_e : 1; + RK_U32 picord_count_e : 1; + RK_U32 reserve0 : 1; + RK_U32 reftopfirst_e : 1; + RK_U32 write_mvs_e : 1; + RK_U32 pic_fixed_quant : 1; + RK_U32 filtering_dis : 1; + RK_U32 dec_out_dis : 1; + RK_U32 ref_topfield_e : 1; + RK_U32 reserve1 : 1; + RK_U32 fwd_interlace_e : 1; + RK_U32 pic_topfiled_e : 1; + RK_U32 pic_inter_e : 1; + RK_U32 pic_b_e : 1; + RK_U32 pic_fieldmode_e : 1; + RK_U32 pic_interlace_e : 1; + RK_U32 reserve2 : 2; + RK_U32 skip_mode : 1; + RK_U32 rlc_mode_e : 1; + RK_U32 dec_mode : 4; + } sw03; + struct { + RK_U32 pic_refer_flag : 1; + RK_U32 reverse0 : 10; + RK_U32 pic_mb_height_p : 8; + RK_U32 mb_width_off : 4; + RK_U32 pic_mb_width : 9; + } sw04; + union { + struct { + RK_U32 fieldpic_flag_e : 1; + RK_S32 reserve0 : 31; + }; + struct { + RK_U32 beta_offset : 5; + RK_U32 alpha_offset : 5; + RK_U32 reserve1 : 16; + RK_U32 strm_start_bit : 6; + }; + } sw05; + struct { + RK_U32 stream_len : 24; + RK_U32 stream_len_ext : 1; + RK_U32 init_qp : 6; + RK_U32 start_code_e : 1; + } sw06; + RK_U32 sw07_11[5]; + struct { + RK_U32 rlc_vlc_base : 32; + } sw12; + struct { + RK_U32 dec_out_base : 32; + } sw13; + union { + RK_U32 refer0_base : 32; + struct { //!< left move 10bit + RK_U32 reserve0 : 10; + RK_U32 refer0_topc_e : 1; + RK_U32 refer0_field_e : 1; + RK_U32 reserve1 : 20; + }; + } sw14; + union { + struct { + RK_U32 refer1_base : 32; + }; + struct { //!< left move 10bit + RK_U32 reserve0 : 10; + RK_U32 refer1_topc_e : 1; + RK_U32 refer1_field_e : 1; + RK_U32 reserve1 : 20; + }; + } sw15; + union { + struct { + RK_U32 refer2_base : 32; + }; + struct { //!< left move 10bit + RK_U32 reserve0 : 10; + RK_U32 refer2_topc_e : 1; + RK_U32 refer2_field_e : 1; + RK_U32 reserve1 : 20; + }; + } sw16; + union { + struct { + RK_U32 refer3_base : 32; + }; + struct { //!< left move 10bit + RK_U32 reserve0 : 10; + RK_U32 refer3_topc_e : 1; + RK_U32 refer3_field_e : 1; + RK_U32 reserve1 : 20; + }; + } sw17; + struct { + RK_U32 prev_anc_type : 1; + RK_U32 reverse0 : 31; + } sw18; + RK_U32 sw19_27[9]; + struct { + RK_U32 ref_invd_cur_0 : 16; + RK_U32 ref_invd_cur_1 : 16; + } sw28; + struct { + RK_U32 ref_invd_cur_2 : 16; + RK_U32 ref_invd_cur_3 : 16; + } sw29; + struct { + RK_U32 ref_dist_cur_0 : 16; + RK_U32 ref_dist_cur_1 : 16; + } sw30; + struct { + RK_U32 ref_dist_cur_2 : 16; + RK_U32 ref_dist_cur_3 : 16; + } sw31; + struct { + RK_U32 ref_invd_col_0 : 16; + RK_U32 ref_invd_col_1 : 16; + } sw32; + struct { + RK_U32 ref_invd_col_2 : 16; + RK_U32 ref_invd_col_3 : 16; + } sw33; + struct { + RK_U32 reserve0 : 2; + RK_U32 pred_bc_tap_1_1 : 10; + RK_U32 pred_bc_tap_1_0 : 10; + RK_U32 pred_bc_tap_0_3 : 10; + } sw34; + struct { + RK_U32 reserve0 : 12; + RK_U32 pred_bc_tap_1_3 : 10; + RK_U32 pred_bc_tap_1_2 : 10; + } sw35; + RK_U32 sw36_40[5]; + struct { + RK_U32 dir_mv_base : 32; + } sw41; + RK_U32 sw42_47[6]; + struct { + RK_U32 reserve0 : 14; + RK_U32 startmb_y : 9; + RK_U32 startmb_x : 9; + } sw48; + struct { + RK_U32 reserve0 : 2; + RK_U32 pred_bc_tap_0_2 : 10; + RK_U32 pred_bc_tap_0_1 : 10; + RK_U32 pred_bc_tap_0_0 : 10; + } sw49; + RK_U32 sw50_54[5]; + struct { + RK_U32 apf_threshold : 14; + RK_U32 refbu2_picid : 5; + RK_U32 refbu2_thr : 12; + RK_U32 refbu2_buf_e : 1; + } sw55; + RK_U32 sw56; + struct { + RK_U32 stream_len_ext : 1; + RK_U32 inter_dblspeed : 1; + RK_U32 intra_dblspeed : 1; + RK_U32 intra_dbl3t : 1; + RK_U32 bus_pos_sel : 1; + RK_U32 axi_sel : 1; + RK_U32 pref_sigchan : 1; + RK_U32 cache_en : 1; + RK_U32 reserve : 24; + } sw57; + RK_U32 sw58_59[2]; + RK_U32 resever[40]; +} AvsdVdpu1Regs_t; + +#endif /*__HAL_AVSD_VDPU1_REG_H__*/ diff --git a/mpp/hal/rkdec/avsd/hal_avsd_vdpu2.c b/mpp/hal/rkdec/avsd/hal_avsd_vdpu2.c new file mode 100644 index 00000000..521343c5 --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_vdpu2.c @@ -0,0 +1,727 @@ +/* + * 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 "hal_avsd_vdpu2" + +#include + +#include "mpp_debug.h" +#include "mpp_common.h" +#include "mpp_mem.h" +#include "mpp_device.h" +#include "mpp_dec_cb_param.h" + +#include "hal_avsd_base.h" +#include "hal_avsd_vdpu2.h" +#include "hal_avsd_vdpu2_reg.h" + +static MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal) +{ + AvsdVdpu2Regs_t *p_regs = (AvsdVdpu2Regs_t *)p_hal->p_regs; + + p_regs->sw54.dec_out_endian = 1; + p_regs->sw54.dec_in_endian = 0; + p_regs->sw54.dec_strendian_e = 1; + p_regs->sw56.dec_max_burlen = 16; + p_regs->sw50.dec_ascmd0_dis = 0; + + p_regs->sw50.adv_pref_dis = 0; + p_regs->sw52.adv_pref_thrd = 8; + p_regs->sw50.adtion_latency = 0; + + p_regs->sw56.dec_data_discd_en = 0; + p_regs->sw54.dec_out_wordsp = 1; + p_regs->sw54.dec_in_wordsp = 1; + p_regs->sw54.dec_strm_wordsp = 1; + p_regs->sw55.timeout_det_sts = 0; + p_regs->sw57.dec_clkgate_en = 1; + p_regs->sw55.dec_irq_dis = 0; + + p_regs->sw56.dec_axi_id_rd = 0xFF; + p_regs->sw56.dec_axi_id_wr = 0; + + p_regs->sw59.pred_bc_tap_0_0 = 0x3FF; + p_regs->sw59.pred_bc_tap_0_1 = 5; + p_regs->sw59.pred_bc_tap_0_2 = 5; + p_regs->sw153.pred_bc_tap_0_3 = 0x3FF; + p_regs->sw153.pred_bc_tap_1_0 = 1; + p_regs->sw153.pred_bc_tap_1_1 = 7; + p_regs->sw154.pred_bc_tap_1_2 = 7; + p_regs->sw154.pred_bc_tap_1_3 = 1; + + p_regs->sw50.dec_tiled_lsb = 0; + + return MPP_OK; +} + +static MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AvsdSyntax_t *p_syn = &p_hal->syn; + AvsdVdpu2Regs_t *p_regs = (AvsdVdpu2Regs_t *)p_hal->p_regs; + + set_defalut_parameters(p_hal); + + p_regs->sw57.timeout_sts_en = 1; + p_regs->sw57.dec_clkgate_en = 1; + p_regs->sw55.dec_irq_dis = 0; + + //!< set wrok_out pic info + if (p_hal->work_out < 0) { + p_hal->work_out = get_queue_pic(p_hal); + if (p_hal->work_out < 0) { + ret = MPP_NOK; + mpp_err_f("cannot get a pic_info buffer.\n"); + goto __FAILED; + } + } + { + AvsdHalPic_t *p_work_out = &p_hal->pic[p_hal->work_out]; + + p_work_out->slot_idx = task->output; + p_work_out->pic_code_type = p_syn->pp.picCodingType; + p_work_out->picture_distance = p_syn->pp.pictureDistance; + } + //!< set register + p_regs->sw120.pic_mb_width = (p_syn->pp.horizontalSize + 15) >> 4; + p_regs->sw53.dec_fmt_sel = 11; //!< DEC_MODE_AVS + + if (p_syn->pp.pictureStructure == FRAMEPICTURE) { + p_regs->sw57.pic_interlace_e = 0; //!< interlace_e + p_regs->sw57.pic_fieldmode_e = 0; //!< fieldmode_e + p_regs->sw57.pic_topfield_e = 0; //!< topfield_e + } else { + p_regs->sw57.pic_interlace_e = 1; + p_regs->sw57.pic_fieldmode_e = 1; + p_regs->sw57.pic_topfield_e = p_hal->first_field; + } + + p_regs->sw120.pic_mb_height_p = (p_syn->pp.verticalSize + 15) >> 4; + p_regs->sw121.avs_h_ext = (p_syn->pp.verticalSize + 15) >> 12; + p_regs->sw57.pic_b_e = (p_syn->pp.picCodingType == BFRAME); + p_regs->sw57.pic_inter_e = (p_syn->pp.picCodingType != IFRAME) ? 1 : 0; + + p_regs->sw122.strm_start_bit = 8 * (p_hal->data_offset & 0x7); + p_hal->data_offset = (p_hal->data_offset & ~0x7); + p_regs->sw64.rlc_vlc_st_adr = get_packet_fd(p_hal, task->input); + mpp_dev_set_reg_offset(p_hal->dev, 64, p_hal->data_offset); + p_regs->sw51.stream_len = p_syn->bitstream_size - p_hal->data_offset; + p_regs->sw50.dec_fixed_quant = p_syn->pp.fixedPictureQp; + p_regs->sw51.init_qp = p_syn->pp.pictureQp; + + p_regs->sw63.dec_out_st_adr = get_frame_fd(p_hal, task->output); + if (p_syn->pp.pictureStructure == FIELDPICTURE && !p_hal->first_field) { + //!< start of bottom field line + mpp_dev_set_reg_offset(p_hal->dev, 63, p_syn->pp.horizontalSize); + } + { + RK_S32 tmp_fwd = -1; + RK_S32 refer0 = -1; + RK_S32 refer1 = -1; + + tmp_fwd = (p_hal->work1 < 0) ? p_hal->work0 : p_hal->work1; + tmp_fwd = (tmp_fwd < 0) ? p_hal->work_out : tmp_fwd; + + refer0 = (task->refer[0] < 0) ? task->output : task->refer[0]; + refer1 = (task->refer[1] < 0) ? refer0 : task->refer[1]; + if (!p_hal->first_field + && p_syn->pp.pictureStructure == FIELDPICTURE + && p_syn->pp.picCodingType != BFRAME) { + p_regs->sw131.refer0_base = get_frame_fd(p_hal, task->output); + p_regs->sw148.refer1_base = get_frame_fd(p_hal, refer0); + p_regs->sw134.refer2_base = get_frame_fd(p_hal, refer0); + p_regs->sw135.refer3_base = get_frame_fd(p_hal, refer1); + } else { + p_regs->sw131.refer0_base = get_frame_fd(p_hal, refer0); + p_regs->sw148.refer1_base = get_frame_fd(p_hal, refer0); + p_regs->sw134.refer2_base = get_frame_fd(p_hal, refer1); + p_regs->sw135.refer3_base = get_frame_fd(p_hal, refer1); + } + } + //!< block distances + if (p_syn->pp.pictureStructure == FRAMEPICTURE) { + if (p_syn->pp.picCodingType == BFRAME) { + RK_S32 tmp = 0; + //!< current to future anchor + if (p_hal->work0 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_syn->pp.pictureDistance + 512) & 0x1FF; + } + //!< prevent division by zero + if (!tmp) tmp = 2; + p_regs->sw133.ref_dist_cur_2 = tmp; + p_regs->sw133.ref_dist_cur_3 = tmp; + p_regs->sw147.ref_invd_cur_2 = 512 / tmp; + p_regs->sw147.ref_invd_cur_3 = 512 / tmp; + + //!< current to past anchor + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + p_regs->sw132.ref_dist_cur_0 = tmp; + p_regs->sw132.ref_dist_cur_1 = tmp; + p_regs->sw146.ref_invd_cur_0 = 512 / tmp; + p_regs->sw146.ref_invd_cur_1 = 512 / tmp; + //!< future anchor to past anchor + if (p_hal->work0 >= 0 && p_hal->work1 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + tmp = 16384 / tmp; + p_regs->sw129.ref_invd_col_0 = tmp; + p_regs->sw129.ref_invd_col_1 = tmp; + //!< future anchor to previous past anchor + tmp = p_hal->future2prev_past_dist; + tmp = 16384 / tmp; + p_regs->sw130.ref_invd_col_2 = tmp; + p_regs->sw130.ref_invd_col_3 = tmp; + } else { + RK_S32 tmp = 0; + //!< current to past anchor + if (p_hal->work0 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF; + } + if (!tmp) tmp = 2; + p_regs->sw132.ref_dist_cur_0 = tmp; + p_regs->sw132.ref_dist_cur_1 = tmp; + p_regs->sw146.ref_invd_cur_0 = 512 / tmp; + p_regs->sw146.ref_invd_cur_1 = 512 / tmp; + //!< current to previous past anchor + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + //!< this will become "future to previous past" for next B + p_hal->future2prev_past_dist = tmp; + + p_regs->sw133.ref_dist_cur_2 = tmp; + p_regs->sw133.ref_dist_cur_3 = tmp; + p_regs->sw147.ref_invd_cur_2 = 512 / tmp; + p_regs->sw147.ref_invd_cur_3 = 512 / tmp; + + p_regs->sw129.ref_invd_col_0 = 0; + p_regs->sw129.ref_invd_col_1 = 0; + p_regs->sw130.ref_invd_col_2 = 0; + p_regs->sw130.ref_invd_col_3 = 0; + } + } else { + //!< field interlaced + if (p_syn->pp.picCodingType == BFRAME) { + RK_S32 tmp = 0; + //!< block distances + if (p_hal->work0 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_syn->pp.pictureDistance + 512) & 0x1FF; + } + //!< prevent division by zero + if (!tmp) tmp = 2; + + if (p_hal->first_field) { + p_regs->sw133.ref_dist_cur_2 = tmp; + p_regs->sw133.ref_dist_cur_3 = tmp + 1; + p_regs->sw147.ref_invd_cur_2 = 512 / tmp; + p_regs->sw147.ref_invd_cur_3 = 512 / (tmp + 1); + } else { + p_regs->sw133.ref_dist_cur_2 = tmp - 1; + p_regs->sw133.ref_dist_cur_3 = tmp; + p_regs->sw147.ref_invd_cur_2 = 512 / (tmp - 1); + p_regs->sw147.ref_invd_cur_3 = 512 / tmp; + } + + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + if (p_hal->first_field) { + p_regs->sw132.ref_dist_cur_0 = (tmp - 1); + p_regs->sw132.ref_dist_cur_1 = tmp; + p_regs->sw146.ref_invd_cur_0 = 512 / (tmp - 1); + p_regs->sw146.ref_invd_cur_1 = 512 / tmp; + } else { + p_regs->sw132.ref_dist_cur_0 = tmp; + p_regs->sw132.ref_dist_cur_1 = tmp + 1; + p_regs->sw146.ref_invd_cur_0 = 512 / tmp; + p_regs->sw146.ref_invd_cur_1 = 512 / (tmp + 1); + } + + if (p_hal->work0 >= 0 && p_hal->work1 >= 0) { + tmp = (2 * p_hal->pic[p_hal->work0].picture_distance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + + if (p_syn->pp.pbFieldEnhancedFlag && !p_hal->first_field) { + //!< in this case, BlockDistanceRef is different with before, the mvRef points to top field + p_regs->sw129.ref_invd_col_0 = 16384 / (tmp - 1); + p_regs->sw129.ref_invd_col_1 = 16384 / tmp; + + //!< future anchor to previous past anchor + tmp = p_hal->future2prev_past_dist; + + p_regs->sw130.ref_invd_col_2 = 16384 / (tmp - 1); + p_regs->sw130.ref_invd_col_3 = 16384 / tmp; + } else { + if (p_hal->first_field) { + p_regs->sw129.ref_invd_col_0 = 16384 / (tmp - 1); + p_regs->sw129.ref_invd_col_1 = 16384 / tmp; + } else { + p_regs->sw129.ref_invd_col_0 = 16384; + p_regs->sw129.ref_invd_col_1 = 16384 / tmp; + p_regs->sw130.ref_invd_col_2 = 16384 / (tmp + 1); + } + + //!< future anchor to previous past anchor + tmp = p_hal->future2prev_past_dist; + + if (p_hal->first_field) { + p_regs->sw130.ref_invd_col_2 = 16384 / (tmp - 1); + p_regs->sw130.ref_invd_col_3 = 16384 / tmp; + } else { + p_regs->sw130.ref_invd_col_3 = 16384 / tmp; + } + } + } else { + RK_S32 tmp = 0; + if (p_hal->work0 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF; + } + if (!tmp) tmp = 2; + + if (!p_hal->first_field) { + p_regs->sw132.ref_dist_cur_0 = 1; + p_regs->sw133.ref_dist_cur_2 = tmp + 1; + + p_regs->sw146.ref_invd_cur_0 = 512; + p_regs->sw147.ref_invd_cur_2 = 512 / (tmp + 1); + } else { + p_regs->sw132.ref_dist_cur_0 = tmp - 1; + p_regs->sw146.ref_invd_cur_0 = 512 / (tmp - 1); + } + p_regs->sw132.ref_dist_cur_1 = tmp; + p_regs->sw146.ref_invd_cur_1 = 512 / tmp; + + if (p_hal->work1 >= 0) { + tmp = (2 * p_syn->pp.pictureDistance - + 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF; + if (!tmp) tmp = 2; + } + //!< this will become "future to previous past" for next B + p_hal->future2prev_past_dist = tmp; + if (p_hal->first_field) { + p_regs->sw133.ref_dist_cur_2 = tmp - 1; + p_regs->sw133.ref_dist_cur_3 = tmp; + + p_regs->sw147.ref_invd_cur_2 = 512 / (tmp - 1); + p_regs->sw147.ref_invd_cur_3 = 512 / tmp; + } else { + p_regs->sw133.ref_dist_cur_3 = tmp; + p_regs->sw147.ref_invd_cur_3 = 512 / tmp; + } + + p_regs->sw129.ref_invd_col_0 = 0; + p_regs->sw129.ref_invd_col_1 = 0; + p_regs->sw130.ref_invd_col_2 = 0; + p_regs->sw130.ref_invd_col_3 = 0; + } + } + + p_regs->sw52.startmb_x = 0; + p_regs->sw52.startmb_y = 0; + + p_regs->sw50.filtering_dis = p_syn->pp.loopFilterDisable; + p_regs->sw122.alpha_offset = p_syn->pp.alphaOffset; + p_regs->sw122.beta_offset = p_syn->pp.betaOffset; + p_regs->sw50.skip_mode = p_syn->pp.skipModeFlag; + p_regs->sw120.pic_refer_flag = p_syn->pp.pictureReferenceFlag; + + if (p_syn->pp.picCodingType == PFRAME + || (p_syn->pp.picCodingType == IFRAME && !p_hal->first_field)) { + p_regs->sw57.dmmv_wr_en = 1; + } else { + p_regs->sw57.dmmv_wr_en = 0; + } + + //!< set mv base + p_regs->sw62.dmmv_st_adr = mpp_buffer_get_fd(p_hal->mv_buf); + if (p_hal->first_field || + (p_syn->pp.picCodingType == BFRAME && p_hal->prev_pic_structure)) { + } else { + RK_U32 frame_width = 0, frame_height = 0, offset = 0; + frame_width = (p_syn->pp.horizontalSize + 15) >> 4; + if (p_syn->pp.progressiveFrame) + frame_height = (p_syn->pp.verticalSize + 15) >> 4; + else + frame_height = 2 * ((p_syn->pp.verticalSize + 31) >> 5); + offset = MPP_ALIGN(frame_width * frame_height / 2, 2) * 16; + mpp_dev_set_reg_offset(p_hal->dev, 62, offset); + } + { + RK_U32 pic_type = 0; + RK_U32 prev_anc_type = 0; + if (p_hal->work0 >= 0) { + pic_type = p_hal->pic[p_hal->work0].pic_type; + } + prev_anc_type = !pic_type || (!p_hal->first_field && !p_hal->prev_pic_structure); + p_regs->sw136.prev_anc_type = prev_anc_type; + } + //!< b-picture needs to know if future reference is field or frame coded + // p_regs->sw134.refer2_field_e = (!p_hal->prev_pic_structure) ? 1 : 0; + // p_regs->sw135.refer3_field_e = (!p_hal->prev_pic_structure) ? 1 : 0; + if (!p_hal->prev_pic_structure) { + mpp_dev_set_reg_offset(p_hal->dev, 134, 2); + mpp_dev_set_reg_offset(p_hal->dev, 135, 3); + } + + p_regs->sw57.dec_out_dis = 0; + p_regs->sw57.dec_e = 1; + + return MPP_OK; +__FAILED: + return ret; +} + +static MPP_RET update_parameters(AvsdHalCtx_t *p_hal) +{ + AvsdSyntax_t *p_syn = &p_hal->syn; + + if (p_syn->pp.pictureStructure == FRAMEPICTURE || !p_hal->first_field) { + p_hal->first_field = 1; + if (p_syn->pp.picCodingType != BFRAME) { + RK_S32 temp = p_hal->work1; + + p_hal->work1 = p_hal->work0; + p_hal->work0 = p_hal->work_out; + + p_hal->pic[p_hal->work_out].pic_type = p_syn->pp.picCodingType == IFRAME; + p_hal->work_out = temp; + p_hal->prev_pic_structure = p_syn->pp.pictureStructure; + } + p_hal->prev_pic_code_type = p_syn->pp.picCodingType; + } else { + p_hal->first_field = 0; + } + + return MPP_OK; +} + +static MPP_RET repeat_other_field(AvsdHalCtx_t *p_hal, HalTaskInfo *task) +{ + RK_U8 i = 0; + RK_U8 *pdata = NULL; + MppBuffer mbuffer = NULL; + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdVdpu2Regs_t *p_regs = (AvsdVdpu2Regs_t *)p_hal->p_regs; + + //!< re-find start code and calculate offset + p_hal->data_offset = p_regs->sw64.rlc_vlc_st_adr >> 10; + p_hal->data_offset += p_hal->syn.bitstream_offset; + p_hal->data_offset -= MPP_MIN(p_hal->data_offset, 8); + + mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &mbuffer); + pdata = (RK_U8 *)mpp_buffer_get_ptr(mbuffer) + p_hal->data_offset; + + while (i < 16) { + if (pdata[i] == 0 && pdata[i + 1] == 0 && pdata[i + 2] == 1) { + p_hal->data_offset += i; + break; + } + i++; + } + + AVSD_HAL_DBG(AVSD_HAL_DBG_OFFSET, "frame_no %d idx %d offset %x\n", + p_hal->frame_no, i, p_hal->data_offset); + + //!< re-generate register + FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); + hal_avsd_vdpu2_start((void *)p_hal, task); + hal_avsd_vdpu2_wait((void *)p_hal, task); + + return ret = MPP_OK; +__FAILED: + return ret; +} + + +/*! + *********************************************************************** + * \brief + * init + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_init(void *decoder, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + RK_U32 buf_size = 0; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("AVS_vdpu2 In."); + + buf_size = (1920 * 1088) * 2; + FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->mv_buf, buf_size)); + + p_hal->p_regs = mpp_calloc_size(RK_U32, sizeof(AvsdVdpu2Regs_t)); + MEM_CHECK(ret, p_hal->p_regs); + + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align); + + p_hal->regs_num = 159; + //!< initial for control + p_hal->first_field = 1; + p_hal->prev_pic_structure = 0; //!< field + + memset(p_hal->pic, 0, sizeof(p_hal->pic)); + p_hal->work_out = -1; + p_hal->work0 = -1; + p_hal->work1 = -1; + + AVSD_HAL_TRACE("Out."); + (void)cfg; + return ret = MPP_OK; +__FAILED: + return ret; + +} +/*! + *********************************************************************** + * \brief + * deinit + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_deinit(void *decoder) +{ + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + if (p_hal->mv_buf) { + mpp_buffer_put(p_hal->mv_buf); + p_hal->mv_buf = NULL; + } + MPP_FREE(p_hal->p_regs); + + AVSD_HAL_TRACE("Out."); + + return MPP_OK; +} +/*! + *********************************************************************** + * \brief + * generate register + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_gen_regs(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __RETURN; + } + p_hal->data_offset = p_hal->syn.bitstream_offset; + + FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec)); +__RETURN: + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +__FAILED: + return ret; + +} +/*! + *********************************************************************** + * \brief h + * start hard + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_start(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __RETURN; + } + + do { + MppDevRegWrCfg wr_cfg; + MppDevRegRdCfg rd_cfg; + RK_U32 reg_size = 159 * sizeof(RK_U32); + + wr_cfg.reg = p_hal->p_regs; + wr_cfg.size = reg_size; + wr_cfg.offset = 0; + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg); + if (ret) { + mpp_err_f("set register write failed %d\n", ret); + break; + } + + rd_cfg.reg = p_hal->p_regs; + rd_cfg.size = reg_size; + rd_cfg.offset = 0; + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg); + if (ret) { + mpp_err_f("set register read failed %d\n", ret); + break; + } + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL); + if (ret) { + mpp_err_f("send cmd failed %d\n", ret); + break; + } + } while (0); + +__RETURN: + AVSD_HAL_TRACE("Out."); + return ret = MPP_OK; +} +/*! + *********************************************************************** + * \brief + * wait hard + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_wait(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + if (task->dec.flags.parse_err || task->dec.flags.ref_err) { + goto __SKIP_HARD; + } + + ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL); + if (ret) + mpp_err_f("poll cmd failed %d\n", ret); + +__SKIP_HARD: + if (p_hal->dec_cb) { + DecCbHalDone param; + + param.task = (void *)&task->dec; + param.regs = (RK_U32 *)p_hal->p_regs; + + if (!((AvsdVdpu2Regs_t *)p_hal->p_regs)->sw55.dec_rdy_sts) { + param.hard_err = 1; + } else + param.hard_err = 0; + + mpp_callback(p_hal->dec_cb, ¶m); + AVSD_HAL_DBG(AVSD_HAL_DBG_WAIT, "reg[55]=%08x, ref=%d, dpberr=%d, harderr=%d\n", + p_hal->p_regs[55], task->dec.flags.used_for_ref, task->dec.flags.ref_err, param.hard_err); + } + + update_parameters(p_hal); + memset(&p_hal->p_regs[55], 0, sizeof(RK_U32)); + if (!p_hal->first_field && p_hal->syn.pp.pictureStructure == FIELDPICTURE && + !task->dec.flags.parse_err && !task->dec.flags.ref_err) { + repeat_other_field(p_hal, task); + } + p_hal->frame_no++; + + AVSD_HAL_TRACE("Out."); + return ret = MPP_OK; +} +/*! + *********************************************************************** + * \brief + * reset + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_reset(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder; + + AVSD_HAL_TRACE("In."); + + p_hal->first_field = 1; + p_hal->prev_pic_structure = 0; //!< field + + memset(p_hal->pic, 0, sizeof(p_hal->pic)); + p_hal->work_out = -1; + p_hal->work0 = -1; + p_hal->work1 = -1; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} +/*! + *********************************************************************** + * \brief + * flush + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_flush(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} +/*! + *********************************************************************** + * \brief + * control + *********************************************************************** + */ +//extern "C" +MPP_RET hal_avsd_vdpu2_control(void *decoder, MpiCmd cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + (void)cmd_type; + (void)param; + + AVSD_HAL_TRACE("Out."); + + return ret = MPP_OK; +} diff --git a/mpp/hal/rkdec/avsd/hal_avsd_vdpu2.h b/mpp/hal/rkdec/avsd/hal_avsd_vdpu2.h new file mode 100644 index 00000000..00fcad55 --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_vdpu2.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#ifndef __HAL_AVSD_VDPU2_H__ +#define __HAL_AVSD_VDPU2_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET hal_avsd_vdpu2_init (void *decoder, MppHalCfg *cfg); +MPP_RET hal_avsd_vdpu2_deinit (void *decoder); +MPP_RET hal_avsd_vdpu2_gen_regs(void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_vdpu2_start (void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_vdpu2_wait (void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_vdpu2_reset (void *decoder); +MPP_RET hal_avsd_vdpu2_flush (void *decoder); +MPP_RET hal_avsd_vdpu2_control (void *decoder, MpiCmd cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_AVSD_VDPU2_H__*/ diff --git a/mpp/hal/rkdec/avsd/hal_avsd_vdpu2_reg.h b/mpp/hal/rkdec/avsd/hal_avsd_vdpu2_reg.h new file mode 100644 index 00000000..858db880 --- /dev/null +++ b/mpp/hal/rkdec/avsd/hal_avsd_vdpu2_reg.h @@ -0,0 +1,230 @@ +/* + * 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. + */ + +#ifndef __HAL_AVSD_VDPU2_REG_H__ +#define __HAL_AVSD_VDPU2_REG_H__ + + +typedef struct { + RK_U32 sw00_49[50]; + struct { + RK_U32 dec_tiled_msb : 1; + RK_U32 adtion_latency : 6; + RK_U32 dec_fixed_quant : 1; + RK_U32 filtering_dis : 1; + RK_U32 skip_mode : 1; + RK_U32 dec_ascmd0_dis : 1; + RK_U32 adv_pref_dis : 1; + RK_U32 dec_tiled_lsb : 1; + RK_U32 refbuf_thrd : 12; + RK_U32 refbuf_pid : 5; + RK_U32 reverse0 : 2; + } sw50; + struct { + RK_U32 stream_len : 24; + RK_U32 stream_len_ext : 1; + RK_U32 init_qp : 6; + RK_U32 reverse0 : 1; + } sw51; + struct { + RK_U32 startmb_y : 8; + RK_U32 startmb_x : 9; + RK_U32 adv_pref_thrd : 14; + RK_U32 reverse0 : 1; + } sw52; + struct { + RK_U32 dec_fmt_sel : 4; + RK_U32 reverse0 : 28; + } sw53; + struct { + RK_U32 dec_in_endian : 1; + RK_U32 dec_out_endian : 1; + RK_U32 dec_in_wordsp : 1; + RK_U32 dec_out_wordsp : 1; + RK_U32 dec_strm_wordsp : 1; + RK_U32 dec_strendian_e : 1; + RK_U32 reverse0 : 26; + } sw54; + struct { + RK_U32 dec_irq : 1; + RK_U32 dec_irq_dis : 1; + RK_U32 reverse0 : 2; + RK_U32 dec_rdy_sts : 1; + RK_U32 pp_bus_sts : 1; + RK_U32 buf_emt_sts : 1; + RK_U32 reverse1 : 1; + RK_U32 aso_det_sts : 1; + RK_U32 slice_det_sts : 1; + RK_U32 bslice_det_sts : 1; + RK_U32 reverse2 : 1; + RK_U32 error_det_sts : 1; + RK_U32 timeout_det_sts : 1; + RK_U32 reverse3 : 18; + } sw55; + struct { + RK_U32 dec_axi_id_rd : 8; + RK_U32 dec_axi_id_wr : 8; + RK_U32 dec_max_burlen : 5; + RK_U32 bus_pos_sel : 1; + RK_U32 dec_data_discd_en : 1; + RK_U32 axi_sel : 1; + RK_U32 reverse0 : 8; + } sw56; + struct { + RK_U32 dec_e : 1; + RK_U32 refpic_buf2_en : 1; + RK_U32 dec_out_dis : 1; + RK_U32 reverse0 : 1; + RK_U32 dec_clkgate_en : 1; + RK_U32 timeout_sts_en : 1; + RK_U32 rd_cnt_tab_en : 1; + RK_U32 reverse1 : 1; + RK_U32 first_reftop_en : 1; + RK_U32 reftop_en : 1; + RK_U32 dmmv_wr_en : 1; + RK_U32 reverse2 : 1; + RK_U32 fwd_interlace_e : 1; + RK_U32 pic_topfield_e : 1; + RK_U32 pic_inter_e : 1; + RK_U32 pic_b_e : 1; + RK_U32 pic_fieldmode_e : 1; + RK_U32 pic_interlace_e : 1; + RK_U32 reverse3 : 2; + RK_U32 rlc_mode_en : 1; + RK_U32 addit_ch_fmt_wen : 1; + RK_U32 st_code_exit : 1; + RK_U32 reverse4 : 2; + RK_U32 inter_dblspeed : 1; + RK_U32 intra_dblspeed : 1; + RK_U32 intra_dbl3t : 1; + RK_U32 pref_sigchan : 1; + RK_U32 cache_en : 1; + RK_U32 reverse5 : 1; + RK_U32 dec_timeout_mode : 1; + } sw57; + RK_U32 sw58; + struct { + RK_U32 reserve : 2; + RK_S32 pred_bc_tap_0_2 : 10; + RK_S32 pred_bc_tap_0_1 : 10; + RK_S32 pred_bc_tap_0_0 : 10; + } sw59; + RK_U32 sw60; + RK_U32 sw61; + struct { + RK_U32 dmmv_st_adr : 32; + } sw62; + struct { + RK_U32 dec_out_st_adr : 32; + } sw63; + struct { + RK_U32 rlc_vlc_st_adr : 32; + } sw64; + RK_U32 sw65_119[55]; + struct { + RK_U32 pic_refer_flag : 1; + RK_U32 reserver0 : 6; + RK_U32 mb_height_off : 4; + RK_U32 pic_mb_height_p : 8; + RK_U32 mb_width_off : 4; + RK_U32 pic_mb_width : 9; + } sw120; + struct { + RK_U32 reserve0 : 25; + RK_U32 avs_h_ext : 1; + RK_U32 reserve1 : 6; + } sw121; + struct { + RK_U32 beta_offset : 5; + RK_U32 alpha_offset : 5; + RK_U32 reserver0 : 16; + RK_U32 strm_start_bit : 6; + } sw122; + RK_U32 sw123_128[6]; + struct { + RK_U32 ref_invd_col_0 : 16; + RK_U32 ref_invd_col_1 : 16; + } sw129; + struct { + RK_U32 ref_invd_col_2 : 16; + RK_U32 ref_invd_col_3 : 16; + } sw130; + union { + RK_U32 refer0_base : 32; + struct { //!< left move 10bit + RK_U32 refer0_topc_e : 1; + RK_U32 refer0_field_e : 1; + }; + } sw131; + struct { + RK_U32 ref_dist_cur_0 : 16; + RK_U32 ref_dist_cur_1 : 16; + } sw132; + struct { + RK_U32 ref_dist_cur_2 : 16; + RK_U32 ref_dist_cur_3 : 16; + } sw133; + union { + RK_U32 refer2_base : 32; + struct { //!< left move 10bit + RK_U32 refer2_topc_e : 1; + RK_U32 refer2_field_e : 1; + }; + } sw134; + union { + RK_U32 refer3_base : 32; + struct { //!< left move 10bit + RK_U32 refer3_topc_e : 1; + RK_U32 refer3_field_e : 1; + }; + } sw135; + struct { + RK_U32 prev_anc_type : 1; + RK_U32 reserver0 : 31; + } sw136; + RK_U32 sw137_145[9]; + struct { + RK_U32 ref_invd_cur_0 : 16; + RK_U32 ref_invd_cur_1 : 16; + } sw146; + struct { + RK_U32 ref_invd_cur_2 : 16; + RK_U32 ref_invd_cur_3 : 16; + } sw147; + union { + RK_U32 refer1_base : 32; + struct { //!< left move 10bit + RK_U32 refer1_topc_e : 1; + RK_U32 refer1_field_e : 1; + }; + } sw148; + RK_U32 sw149_152[4]; + struct { + RK_U32 reserve : 2; + RK_U32 pred_bc_tap_1_1 : 10; + RK_U32 pred_bc_tap_1_0 : 10; + RK_U32 pred_bc_tap_0_3 : 10; + } sw153; + struct { + RK_U32 reserve : 2; + RK_U32 pred_bc_tap_2_0 : 10; + RK_U32 pred_bc_tap_1_3 : 10; + RK_U32 pred_bc_tap_1_2 : 10; + } sw154; + RK_U32 sw155_158[4]; +} AvsdVdpu2Regs_t; + +#endif /*__HAL_AVSD_VDPU2_REG_H__*/ diff --git a/mpp/hal/vpu/jpegd/hal_jpegd_rkv.c b/mpp/hal/vpu/jpegd/hal_jpegd_rkv.c index 51a049f3..cbe5b4db 100644 --- a/mpp/hal/vpu/jpegd/hal_jpegd_rkv.c +++ b/mpp/hal/vpu/jpegd/hal_jpegd_rkv.c @@ -256,7 +256,7 @@ MPP_RET hal_jpegd_rkv_init(void *hal, MppHalCfg *cfg) ret = mpp_dev_init(&ctx->dev, ctx->dev_type); if (ret) { - mpp_err("mpp_device_init failed. ret: %d\n", ret); + mpp_err("mpp_dev_init failed. ret: %d\n", ret); return ret; } diff --git a/mpp/legacy/vpu.c b/mpp/legacy/vpu.c index 7d951a62..5b056218 100644 --- a/mpp/legacy/vpu.c +++ b/mpp/legacy/vpu.c @@ -134,8 +134,8 @@ int VPUClientInit(VPU_CLIENT_TYPE type) ctx_type = MPP_CTX_DEC; type = VPU_DEC; break; - case VPU_DEC_AVS: - coding = MPP_VIDEO_CodingAVS; + case VPU_DEC_AVSPLUS: + coding = MPP_VIDEO_CodingAVSPLUS; ctx_type = MPP_CTX_DEC; type = VPU_DEC; break; diff --git a/mpp/mpi.cpp b/mpp/mpi.cpp index 219a241b..9e86544c 100644 --- a/mpp/mpi.cpp +++ b/mpp/mpi.cpp @@ -60,6 +60,7 @@ static MppCodingTypeInfo support_list[] = { { MPP_CTX_DEC, MPP_VIDEO_CodingVP9, "dec", "VP9", }, #endif #if HAVE_AVSD + { MPP_CTX_DEC, MPP_VIDEO_CodingAVS, "dec", "avs", }, { MPP_CTX_DEC, MPP_VIDEO_CodingAVSPLUS, "dec", "avs+", }, #endif #if HAVE_AVS2D diff --git a/osal/mpp_soc.cpp b/osal/mpp_soc.cpp index 418b8425..13d3b878 100644 --- a/osal/mpp_soc.cpp +++ b/osal/mpp_soc.cpp @@ -49,7 +49,7 @@ #define HAVE_AVS2 ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingAVS2)))) #define HAVE_AV1 ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingAV1)))) -#define CAP_CODING_VDPU (HAVE_MPEG2|HAVE_H263|HAVE_MPEG4|HAVE_AVC|HAVE_MJPEG|HAVE_VP8) +#define CAP_CODING_VDPU (HAVE_MPEG2|HAVE_H263|HAVE_MPEG4|HAVE_AVC|HAVE_MJPEG|HAVE_VP8|HAVE_AVS) #define CAP_CODING_JPEGD_PP (HAVE_MJPEG) #define CAP_CODING_AVSD (HAVE_AVS) #define CAP_CODING_AVSPD (HAVE_AVSP) @@ -303,23 +303,6 @@ static const MppDecHwCap vdpu38x = { .reserved = 0, }; -static const MppDecHwCap avsd = { - .cap_coding = CAP_CODING_AVSD, - .type = VPU_CLIENT_AVSPLUS_DEC, - .cap_fbc = 0, - .cap_4k = 0, - .cap_8k = 0, - .cap_colmv_buf = 0, - .cap_hw_h265_rps = 0, - .cap_hw_vp9_prob = 0, - .cap_jpg_pp_out = 0, - .cap_10bit = 0, - .cap_down_scale = 0, - .cap_lmt_linebuf = 1, - .cap_core_num = 1, - .reserved = 0, -}; - static const MppDecHwCap avspd = { .cap_coding = CAP_CODING_AVSPD, .type = VPU_CLIENT_AVSPLUS_DEC, @@ -582,7 +565,7 @@ static const MppSocInfo mpp_soc_infos[] = { "rk3228h", ROCKCHIP_SOC_RK3228H, HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_AVSDEC | HAVE_VEPU22, - { &vdpu341_lite, &vdpu2, &vdpu2_jpeg_pp, &avsd, NULL, NULL, }, + { &vdpu341_lite, &vdpu2, &vdpu2_jpeg_pp, &avspd, NULL, NULL, }, { &vepu2_no_jpeg, &vepu22, NULL, NULL, }, }, { /* diff --git a/osal/test/mpp_platform_test.c b/osal/test/mpp_platform_test.c index 2196a1db..f27a7eaa 100644 --- a/osal/test/mpp_platform_test.c +++ b/osal/test/mpp_platform_test.c @@ -86,8 +86,8 @@ int main() dev = mpp_get_vcodec_dev_name(MPP_CTX_DEC, MPP_VIDEO_CodingVP9); mpp_log("VP9 decoder: %s\n", dev); - dev = mpp_get_vcodec_dev_name(MPP_CTX_DEC, MPP_VIDEO_CodingAVS); - mpp_log("avs decoder: %s\n", dev); + dev = mpp_get_vcodec_dev_name(MPP_CTX_DEC, MPP_VIDEO_CodingAVSPLUS); + mpp_log("avs+ decoder: %s\n", dev); mpp_log("\n"); mpp_log("start probing encoder device name:\n");