Bladeren bron

[avs]: Add avs module

NOTE: I frame header decoding should check stream version.

Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
Signed-off-by: Yandong Lin <yandong.lin@rock-chips.com>
Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Change-Id: I1c8276f4499d73e3b60d582890037dec376e136f
Yandong Lin 3 jaren geleden
bovenliggende
commit
3adde926e2

+ 1 - 1
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;

+ 2 - 1
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

+ 125 - 77
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));
-
-    } while (mpp_packet_get_length(pkt) && !task->valid);
+    mpp_packet_set_length(p_dec->task_pkt, p_dec->left_length);
 
-    if (task->valid) {
-        //!< bit stream
-        RK_U32 align_len = MPP_ALIGN(p_dec->p_stream->len + 32, 16);
+    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);
 
-        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);
+        RK_U8 *dst = mpp_malloc_size(RK_U8, p_dec->stream_size);
+        mpp_assert(dst);
 
-        p_dec->syn->bitstream_size = align_len;
-        p_dec->syn->bitstream = p_dec->p_stream->pbuf;
+        if (p_dec->left_length > 0) {
+            memcpy(dst, p_dec->streambuf, p_dec->left_length);
+        }
+        mpp_free(p_dec->streambuf);
+        p_dec->streambuf = dst;
 
-        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;
 }
 /*!
@@ -328,7 +362,7 @@ MPP_RET avsd_callback(void *decoder, void *info)
 */
 const ParserApi api_avsd_parser = {
     .name = "avsd_parse",
-    .coding = MPP_VIDEO_CodingAVSPLUS,
+    .coding = MPP_VIDEO_CodingAVS,
     .ctx_size = sizeof(AvsdCtx_t),
     .flag = 0,
     .init = avsd_init,
@@ -341,3 +375,17 @@ const ParserApi api_avsd_parser = {
     .callback = avsd_callback,
 };
 
+const ParserApi api_avsd_plus_parser = {
+    .name = "avsd_parse",
+    .coding = MPP_VIDEO_CodingAVSPLUS,
+    .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,
+};

+ 167 - 181
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);
+        vsh->version = 1;
+    } else {
+        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);
-    if (!ph->progressive_frame) {
+
+    ph->picture_structure = 1;  // default frame
+    if (!ph->progressive_frame)
         READ_ONEBIT(bitctx, &ph->picture_structure);
-    } else {
-        ph->picture_structure = 1; //!< frame picture
-    }
+
     READ_ONEBIT(bitctx, &ph->top_field_first);
     READ_ONEBIT(bitctx, &ph->repeat_first_field);
     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;
-
-    RK_U32 prefix = 0xFFFFFFFF;
-
-    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;
+    MPP_RET ret = MPP_NOK;
+    AVSD_PARSE_TRACE("In.\n");
+
+    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;
+
+    // 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;
+    // 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;
+                }
+            }
         }
     }
-    //!< 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);
+    // the last packet
+    if (src_eos && src_pos >= src_len) {
+        mpp_packet_set_eos(dst);
+        ret = MPP_OK;
+    }
 
-__RETURN:
-    AVSD_PARSE_TRACE("Out.");
+    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 *data = (RK_U8 *)mpp_packet_get_data(task->input_packet);
+    RK_S32 length = (RK_S32)mpp_packet_get_length(task->input_packet);
+
+    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);
 
-    RK_U8 pic_type = 0;
-    AvsdNalu_t *p_nalu = (AvsdNalu_t *)p_dec->p_header->pbuf;
-
-    task->valid = 0;
-    while (!p_nalu->eof) {
-        RK_U32 startcode = p_nalu->header;
-
-        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;
 }
-
-
-
-

+ 34 - 48
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;
-
-    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;
+    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;
+
     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

+ 1 - 0
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);

+ 1 - 0
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,

+ 15 - 16
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;
 

+ 15 - 16
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
 }

+ 1 - 0
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,

+ 11 - 2
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

+ 199 - 256
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 <stdlib.h>
 #include <string.h>
 
+#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)
-{
-    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;
-    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++;
-    }
-    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;
-
-}
-/*!
-***********************************************************************
-* \brief
-*    init
-***********************************************************************
-*/
-//extern "C"
-MPP_RET hal_avsd_init(void *decoder, MppHalCfg *cfg)
+static MPP_RET init_hard_platform(AvsdHalCtx_t *p_hal, MppCodingType coding)
 {
+    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;
-    AvsdHalCtx_t *p_hal = NULL;
 
-    AVSD_HAL_TRACE("In.");
-    INP_CHECK(ret, NULL == decoder);
+    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;
 
-    mpp_env_get_u32("avsd_debug", &avsd_hal_debug, 0);
-
-    p_hal = (AvsdHalCtx_t *)decoder;
-    memset(p_hal, 0, sizeof(AvsdHalCtx_t));
+        if (!(vcodec_type & hw_flag ))
+            mpp_err("coding %x vcodec_type %x do not found avs hw %x\n",
+                    coding, vcodec_type, hw_flag);
+    }
 
-    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
+    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);
 
-    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_gen_regs(void *decoder, HalTaskInfo *task)
+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);
-    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));
+    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 h
-*    start hard
-***********************************************************************
-*/
+ ***********************************************************************
+ * \brief
+ *    generate register
+ ***********************************************************************
+ */
 //extern "C"
-MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task)
+MPP_RET hal_avsd_gen_regs(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);
-
-    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;
+    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);
 
-        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;
+            p_hal->dev = NULL;
         }
-
-        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);
+        ret = init_hard_platform(p_hal, coding);
         if (ret) {
-            mpp_err_f("set register read failed %d\n", ret);
-            break;
+            mpp_err_f("change paltform %x -> %x error\n", p_hal->coding, coding);
+            return ret;
         }
-
-        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 p_hal->hal_api.reg_gen(decoder, task);
+}
+/*!
+ ***********************************************************************
+ * \brief h
+ *    start hard
+ ***********************************************************************
+ */
+//extern "C"
+MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task)
+{
+    AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
 
-    return ret;
+    return p_hal->hal_api.start(decoder, task);
 }
 /*!
-***********************************************************************
-* \brief
-*    wait hard
-***********************************************************************
-*/
+ ***********************************************************************
+ * \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, &param);
-    }
-
-    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.");
-
-    memset(p_hal->p_regs, 0, sizeof(AvsdRegs_t));
-
-    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 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;
 
-    AVSD_HAL_TRACE("Out.");
+    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;
 
-    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,
 };

+ 80 - 0
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 <assert.h>
+#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;
+}

+ 146 - 0
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__*/

+ 334 - 80
mpp/hal/rkdec/avsd/hal_avsd_reg.c → 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.
-*/
-
-#define MODULE_TAG "hal_avsd_reg"
+ * 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_plus"
+
+#include <string.h>
 
 #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, &param);
+    }
+    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;
+}

+ 37 - 0
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__*/

+ 25 - 132
mpp/hal/rkdec/avsd/hal_avsd_reg.h → 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;
-
-
-
-
-#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
+} AvsdPlusRegs_t;
 
-#endif /*__HAL_AVSD_REG_H__*/
+#endif /*__HAL_AVSD_PLUS_REG_H__*/

+ 728 - 0
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 <string.h>
+
+#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, &param);
+        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;
+}

+ 39 - 0
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__*/

+ 247 - 0
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__*/

+ 727 - 0
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 <string.h>
+
+#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, &param);
+        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;
+}

+ 39 - 0
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__*/

+ 230 - 0
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__*/

+ 1 - 1
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;
     }
 

+ 2 - 2
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;

+ 1 - 0
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

+ 2 - 19
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, },
     },
     {   /*

+ 2 - 2
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");