13d0407baSopenharmony_ci/*
23d0407baSopenharmony_ci * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
33d0407baSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43d0407baSopenharmony_ci * you may not use this file except in compliance with the License.
53d0407baSopenharmony_ci * You may obtain a copy of the License at
63d0407baSopenharmony_ci *
73d0407baSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83d0407baSopenharmony_ci *
93d0407baSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103d0407baSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113d0407baSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123d0407baSopenharmony_ci * See the License for the specific language governing permissions and
133d0407baSopenharmony_ci * limitations under the License.
143d0407baSopenharmony_ci */
153d0407baSopenharmony_ci
163d0407baSopenharmony_ci#define MODULE_TAG "mpi_enc_utils"
173d0407baSopenharmony_ci
183d0407baSopenharmony_ci#include <string.h>
193d0407baSopenharmony_ci#include "securec.h"
203d0407baSopenharmony_ci#include "mpp_mem.h"
213d0407baSopenharmony_ci#include "mpp_env.h"
223d0407baSopenharmony_ci#include "mpp_log.h"
233d0407baSopenharmony_ci#include "mpp_buffer.h"
243d0407baSopenharmony_ci#include "rk_mpi.h"
253d0407baSopenharmony_ci#include "mpp_common.h"
263d0407baSopenharmony_ci#include "mpp_packet.h"
273d0407baSopenharmony_ci#include "mpi_enc_utils.h"
283d0407baSopenharmony_ci
293d0407baSopenharmony_ci#define GOP_MODE_TSVC4 3
303d0407baSopenharmony_ci#define GOP_MODE_TSVC3 2
313d0407baSopenharmony_ci#define GOP_MODE_TSVC2 1
323d0407baSopenharmony_ci
333d0407baSopenharmony_ci#define TEMPORAL_ID_0 0
343d0407baSopenharmony_ci#define TEMPORAL_ID_1 1
353d0407baSopenharmony_ci#define TEMPORAL_ID_2 2
363d0407baSopenharmony_ci#define TEMPORAL_ID_3 3
373d0407baSopenharmony_ci
383d0407baSopenharmony_ci#define REF_NUM_0  0
393d0407baSopenharmony_ci#define REF_NUM_1  1
403d0407baSopenharmony_ci#define REF_NUM_2  2
413d0407baSopenharmony_ci#define REF_NUM_3  3
423d0407baSopenharmony_ci#define REF_NUM_4  4
433d0407baSopenharmony_ci#define REF_NUM_5  5
443d0407baSopenharmony_ci#define REF_NUM_6  6
453d0407baSopenharmony_ci#define REF_NUM_7  7
463d0407baSopenharmony_ci#define REF_NUM_8  8
473d0407baSopenharmony_ci
483d0407baSopenharmony_ci#define ST_COUNT_3 3
493d0407baSopenharmony_ci#define ST_COUNT_5 5
503d0407baSopenharmony_ci
513d0407baSopenharmony_cistatic MPP_RET mpi_enc_gen_ref_cfg(MppEncRefCfg ref, RK_S32 gop_mode)
523d0407baSopenharmony_ci{
533d0407baSopenharmony_ci    MppEncRefLtFrmCfg lt_ref[4];
543d0407baSopenharmony_ci    MppEncRefStFrmCfg st_ref[16];
553d0407baSopenharmony_ci    RK_S32 lt_cnt = 0;
563d0407baSopenharmony_ci    RK_S32 st_cnt = 0;
573d0407baSopenharmony_ci    MPP_RET ret = 0;
583d0407baSopenharmony_ci
593d0407baSopenharmony_ci    errno_t eok = memset_s(&lt_ref, sizeof(lt_ref), 0, sizeof(lt_ref));
603d0407baSopenharmony_ci    if (eok != EOK) {
613d0407baSopenharmony_ci        mpp_err("memset_s failed\n");
623d0407baSopenharmony_ci        return MPP_NOK;
633d0407baSopenharmony_ci    }
643d0407baSopenharmony_ci    eok = memset_s(&st_ref, sizeof(st_ref), 0, sizeof(st_ref));
653d0407baSopenharmony_ci    if (eok != EOK) {
663d0407baSopenharmony_ci        mpp_err("memset_s failed\n");
673d0407baSopenharmony_ci        return MPP_NOK;
683d0407baSopenharmony_ci    }
693d0407baSopenharmony_ci
703d0407baSopenharmony_ci    switch (gop_mode) {
713d0407baSopenharmony_ci        case GOP_MODE_TSVC4 : {
723d0407baSopenharmony_ci            // tsvc4
733d0407baSopenharmony_ci            //      /-> P1      /-> P3        /-> P5      /-> P7
743d0407baSopenharmony_ci            //     /           /             /           /
753d0407baSopenharmony_ci            //    //--------> P2            //--------> P6
763d0407baSopenharmony_ci            //   //                        //
773d0407baSopenharmony_ci            //  ///---------------------> P4
783d0407baSopenharmony_ci            // ///
793d0407baSopenharmony_ci            // P0 ------------------------------------------------> P8
803d0407baSopenharmony_ci            lt_cnt = 1;
813d0407baSopenharmony_ci
823d0407baSopenharmony_ci            /* set 8 frame lt-ref gap */
833d0407baSopenharmony_ci            lt_ref[REF_NUM_0].lt_idx        = 0;
843d0407baSopenharmony_ci            lt_ref[REF_NUM_0].temporal_id   = TEMPORAL_ID_0;
853d0407baSopenharmony_ci            lt_ref[REF_NUM_0].ref_mode      = REF_TO_PREV_LT_REF;
863d0407baSopenharmony_ci            lt_ref[REF_NUM_0].lt_gap        = 8; // 8:set 8 frame
873d0407baSopenharmony_ci            lt_ref[REF_NUM_0].lt_delay      = 0;
883d0407baSopenharmony_ci
893d0407baSopenharmony_ci            st_cnt = 9;
903d0407baSopenharmony_ci            /* set tsvc4 st-ref struct */
913d0407baSopenharmony_ci            /* st 0 layer 0 - ref */
923d0407baSopenharmony_ci            st_ref[REF_NUM_0].is_non_ref    = 0;
933d0407baSopenharmony_ci            st_ref[REF_NUM_0].temporal_id   = TEMPORAL_ID_0;
943d0407baSopenharmony_ci            st_ref[REF_NUM_0].ref_mode      = REF_TO_TEMPORAL_LAYER;
953d0407baSopenharmony_ci            st_ref[REF_NUM_0].ref_arg       = 0;
963d0407baSopenharmony_ci            st_ref[REF_NUM_0].repeat        = 0;
973d0407baSopenharmony_ci            /* st 1 layer 3 - non-ref */
983d0407baSopenharmony_ci            st_ref[REF_NUM_1].is_non_ref    = 1;
993d0407baSopenharmony_ci            st_ref[REF_NUM_1].temporal_id   = TEMPORAL_ID_3;
1003d0407baSopenharmony_ci            st_ref[REF_NUM_1].ref_mode      = REF_TO_PREV_REF_FRM;
1013d0407baSopenharmony_ci            st_ref[REF_NUM_1].ref_arg       = 0;
1023d0407baSopenharmony_ci            st_ref[REF_NUM_1].repeat        = 0;
1033d0407baSopenharmony_ci            /* st 2 layer 2 - ref */
1043d0407baSopenharmony_ci            st_ref[REF_NUM_2].is_non_ref    = 0;
1053d0407baSopenharmony_ci            st_ref[REF_NUM_2].temporal_id   = TEMPORAL_ID_2;
1063d0407baSopenharmony_ci            st_ref[REF_NUM_2].ref_mode      = REF_TO_PREV_REF_FRM;
1073d0407baSopenharmony_ci            st_ref[REF_NUM_2].ref_arg       = 0;
1083d0407baSopenharmony_ci            st_ref[REF_NUM_2].repeat        = 0;
1093d0407baSopenharmony_ci            /* st 3 layer 3 - non-ref */
1103d0407baSopenharmony_ci            st_ref[REF_NUM_3].is_non_ref    = 1;
1113d0407baSopenharmony_ci            st_ref[REF_NUM_3].temporal_id   = TEMPORAL_ID_3;
1123d0407baSopenharmony_ci            st_ref[REF_NUM_3].ref_mode      = REF_TO_PREV_REF_FRM;
1133d0407baSopenharmony_ci            st_ref[REF_NUM_3].ref_arg       = 0;
1143d0407baSopenharmony_ci            st_ref[REF_NUM_3].repeat        = 0;
1153d0407baSopenharmony_ci            /* st 4 layer 1 - ref */
1163d0407baSopenharmony_ci            st_ref[REF_NUM_4].is_non_ref    = 0;
1173d0407baSopenharmony_ci            st_ref[REF_NUM_4].temporal_id   = TEMPORAL_ID_1;
1183d0407baSopenharmony_ci            st_ref[REF_NUM_4].ref_mode      = REF_TO_PREV_LT_REF;
1193d0407baSopenharmony_ci            st_ref[REF_NUM_4].ref_arg       = 0;
1203d0407baSopenharmony_ci            st_ref[REF_NUM_4].repeat        = 0;
1213d0407baSopenharmony_ci            /* st 5 layer 3 - non-ref */
1223d0407baSopenharmony_ci            st_ref[REF_NUM_5].is_non_ref    = 1;
1233d0407baSopenharmony_ci            st_ref[REF_NUM_5].temporal_id   = TEMPORAL_ID_3;
1243d0407baSopenharmony_ci            st_ref[REF_NUM_5].ref_mode      = REF_TO_PREV_REF_FRM;
1253d0407baSopenharmony_ci            st_ref[REF_NUM_5].ref_arg       = 0;
1263d0407baSopenharmony_ci            st_ref[REF_NUM_5].repeat        = 0;
1273d0407baSopenharmony_ci            /* st 6 layer 2 - ref */
1283d0407baSopenharmony_ci            st_ref[REF_NUM_6].is_non_ref    = 0;
1293d0407baSopenharmony_ci            st_ref[REF_NUM_6].temporal_id   = TEMPORAL_ID_2;
1303d0407baSopenharmony_ci            st_ref[REF_NUM_6].ref_mode      = REF_TO_PREV_REF_FRM;
1313d0407baSopenharmony_ci            st_ref[REF_NUM_6].ref_arg       = 0;
1323d0407baSopenharmony_ci            st_ref[REF_NUM_6].repeat        = 0;
1333d0407baSopenharmony_ci            /* st 7 layer 3 - non-ref */
1343d0407baSopenharmony_ci            st_ref[REF_NUM_7].is_non_ref    = 1;
1353d0407baSopenharmony_ci            st_ref[REF_NUM_7].temporal_id   = TEMPORAL_ID_3;
1363d0407baSopenharmony_ci            st_ref[REF_NUM_7].ref_mode      = REF_TO_PREV_REF_FRM;
1373d0407baSopenharmony_ci            st_ref[REF_NUM_7].ref_arg       = 0;
1383d0407baSopenharmony_ci            st_ref[REF_NUM_7].repeat        = 0;
1393d0407baSopenharmony_ci            /* st 8 layer 0 - ref */
1403d0407baSopenharmony_ci            st_ref[REF_NUM_8].is_non_ref    = 0;
1413d0407baSopenharmony_ci            st_ref[REF_NUM_8].temporal_id   = TEMPORAL_ID_0;
1423d0407baSopenharmony_ci            st_ref[REF_NUM_8].ref_mode      = REF_TO_TEMPORAL_LAYER;
1433d0407baSopenharmony_ci            st_ref[REF_NUM_8].ref_arg       = 0;
1443d0407baSopenharmony_ci            st_ref[REF_NUM_8].repeat        = 0;
1453d0407baSopenharmony_ci        }
1463d0407baSopenharmony_ci            break;
1473d0407baSopenharmony_ci        case GOP_MODE_TSVC3 : {
1483d0407baSopenharmony_ci            // tsvc3
1493d0407baSopenharmony_ci            //     /-> P1      /-> P3
1503d0407baSopenharmony_ci            //    /           /
1513d0407baSopenharmony_ci            //   //--------> P2
1523d0407baSopenharmony_ci            //  //
1533d0407baSopenharmony_ci            // P0/---------------------> P4
1543d0407baSopenharmony_ci            lt_cnt = 0;
1553d0407baSopenharmony_ci
1563d0407baSopenharmony_ci            st_cnt = ST_COUNT_5;
1573d0407baSopenharmony_ci            /* set tsvc4 st-ref struct */
1583d0407baSopenharmony_ci            /* st 0 layer 0 - ref */
1593d0407baSopenharmony_ci            st_ref[REF_NUM_0].is_non_ref    = 0;
1603d0407baSopenharmony_ci            st_ref[REF_NUM_0].temporal_id   = TEMPORAL_ID_0;
1613d0407baSopenharmony_ci            st_ref[REF_NUM_0].ref_mode      = REF_TO_TEMPORAL_LAYER;
1623d0407baSopenharmony_ci            st_ref[REF_NUM_0].ref_arg       = 0;
1633d0407baSopenharmony_ci            st_ref[REF_NUM_0].repeat        = 0;
1643d0407baSopenharmony_ci            /* st 1 layer 2 - non-ref */
1653d0407baSopenharmony_ci            st_ref[REF_NUM_1].is_non_ref    = 1;
1663d0407baSopenharmony_ci            st_ref[REF_NUM_1].temporal_id   = TEMPORAL_ID_2;
1673d0407baSopenharmony_ci            st_ref[REF_NUM_1].ref_mode      = REF_TO_PREV_REF_FRM;
1683d0407baSopenharmony_ci            st_ref[REF_NUM_1].ref_arg       = 0;
1693d0407baSopenharmony_ci            st_ref[REF_NUM_1].repeat        = 0;
1703d0407baSopenharmony_ci            /* st 2 layer 1 - ref */
1713d0407baSopenharmony_ci            st_ref[REF_NUM_2].is_non_ref    = 0;
1723d0407baSopenharmony_ci            st_ref[REF_NUM_2].temporal_id   = TEMPORAL_ID_1;
1733d0407baSopenharmony_ci            st_ref[REF_NUM_2].ref_mode      = REF_TO_PREV_REF_FRM;
1743d0407baSopenharmony_ci            st_ref[REF_NUM_2].ref_arg       = 0;
1753d0407baSopenharmony_ci            st_ref[REF_NUM_2].repeat        = 0;
1763d0407baSopenharmony_ci            /* st 3 layer 2 - non-ref */
1773d0407baSopenharmony_ci            st_ref[REF_NUM_3].is_non_ref    = 1;
1783d0407baSopenharmony_ci            st_ref[REF_NUM_3].temporal_id   = TEMPORAL_ID_2;
1793d0407baSopenharmony_ci            st_ref[REF_NUM_3].ref_mode      = REF_TO_PREV_REF_FRM;
1803d0407baSopenharmony_ci            st_ref[REF_NUM_3].ref_arg       = 0;
1813d0407baSopenharmony_ci            st_ref[REF_NUM_3].repeat        = 0;
1823d0407baSopenharmony_ci            /* st 4 layer 0 - ref */
1833d0407baSopenharmony_ci            st_ref[REF_NUM_4].is_non_ref    = 0;
1843d0407baSopenharmony_ci            st_ref[REF_NUM_4].temporal_id   = TEMPORAL_ID_0;
1853d0407baSopenharmony_ci            st_ref[REF_NUM_4].ref_mode      = REF_TO_TEMPORAL_LAYER;
1863d0407baSopenharmony_ci            st_ref[REF_NUM_4].ref_arg       = 0;
1873d0407baSopenharmony_ci            st_ref[REF_NUM_4].repeat        = 0;
1883d0407baSopenharmony_ci        }
1893d0407baSopenharmony_ci            break;
1903d0407baSopenharmony_ci        case GOP_MODE_TSVC2 : {
1913d0407baSopenharmony_ci            // tsvc2
1923d0407baSopenharmony_ci            //   /-> P1
1933d0407baSopenharmony_ci            //  /
1943d0407baSopenharmony_ci            // P0--------> P2
1953d0407baSopenharmony_ci            lt_cnt = 0;
1963d0407baSopenharmony_ci
1973d0407baSopenharmony_ci            st_cnt = ST_COUNT_3;
1983d0407baSopenharmony_ci            /* set tsvc4 st-ref struct */
1993d0407baSopenharmony_ci            /* st 0 layer 0 - ref */
2003d0407baSopenharmony_ci            st_ref[REF_NUM_0].is_non_ref    = 0;
2013d0407baSopenharmony_ci            st_ref[REF_NUM_0].temporal_id   = TEMPORAL_ID_0;
2023d0407baSopenharmony_ci            st_ref[REF_NUM_0].ref_mode      = REF_TO_TEMPORAL_LAYER;
2033d0407baSopenharmony_ci            st_ref[REF_NUM_0].ref_arg       = 0;
2043d0407baSopenharmony_ci            st_ref[REF_NUM_0].repeat        = 0;
2053d0407baSopenharmony_ci            /* st 1 layer 2 - non-ref */
2063d0407baSopenharmony_ci            st_ref[REF_NUM_1].is_non_ref    = 1;
2073d0407baSopenharmony_ci            st_ref[REF_NUM_1].temporal_id   = TEMPORAL_ID_1;
2083d0407baSopenharmony_ci            st_ref[REF_NUM_1].ref_mode      = REF_TO_PREV_REF_FRM;
2093d0407baSopenharmony_ci            st_ref[REF_NUM_1].ref_arg       = 0;
2103d0407baSopenharmony_ci            st_ref[REF_NUM_1].repeat        = 0;
2113d0407baSopenharmony_ci            /* st 2 layer 1 - ref */
2123d0407baSopenharmony_ci            st_ref[REF_NUM_2].is_non_ref    = 0;
2133d0407baSopenharmony_ci            st_ref[REF_NUM_2].temporal_id   = TEMPORAL_ID_0;
2143d0407baSopenharmony_ci            st_ref[REF_NUM_2].ref_mode      = REF_TO_PREV_REF_FRM;
2153d0407baSopenharmony_ci            st_ref[REF_NUM_2].ref_arg       = 0;
2163d0407baSopenharmony_ci            st_ref[REF_NUM_2].repeat        = 0;
2173d0407baSopenharmony_ci        }
2183d0407baSopenharmony_ci            break;
2193d0407baSopenharmony_ci        default : {
2203d0407baSopenharmony_ci            mpp_err_f("unsupport gop mode %d\n", gop_mode);
2213d0407baSopenharmony_ci        }
2223d0407baSopenharmony_ci            break;
2233d0407baSopenharmony_ci    }
2243d0407baSopenharmony_ci
2253d0407baSopenharmony_ci    if (lt_cnt || st_cnt) {
2263d0407baSopenharmony_ci        ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
2273d0407baSopenharmony_ci
2283d0407baSopenharmony_ci        if (lt_cnt)
2293d0407baSopenharmony_ci            ret = mpp_enc_ref_cfg_add_lt_cfg(ref, lt_cnt, lt_ref);
2303d0407baSopenharmony_ci
2313d0407baSopenharmony_ci        if (st_cnt)
2323d0407baSopenharmony_ci            ret = mpp_enc_ref_cfg_add_st_cfg(ref, st_cnt, st_ref);
2333d0407baSopenharmony_ci
2343d0407baSopenharmony_ci        /* check and get dpb size */
2353d0407baSopenharmony_ci        ret = mpp_enc_ref_cfg_check(ref);
2363d0407baSopenharmony_ci    }
2373d0407baSopenharmony_ci
2383d0407baSopenharmony_ci    return ret;
2393d0407baSopenharmony_ci}
2403d0407baSopenharmony_ci
2413d0407baSopenharmony_cistatic MPP_RET mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref, RK_S32 gop_len, RK_S32 vi_len)
2423d0407baSopenharmony_ci{
2433d0407baSopenharmony_ci    MppEncRefLtFrmCfg lt_ref[4];
2443d0407baSopenharmony_ci    MppEncRefStFrmCfg st_ref[16];
2453d0407baSopenharmony_ci    RK_S32 lt_cnt = 1;
2463d0407baSopenharmony_ci    RK_S32 st_cnt = 8;
2473d0407baSopenharmony_ci    RK_S32 pos = 0;
2483d0407baSopenharmony_ci    MPP_RET ret = 0;
2493d0407baSopenharmony_ci
2503d0407baSopenharmony_ci    errno_t eok = memset_s(&lt_ref, sizeof(lt_ref), 0, sizeof(lt_ref));
2513d0407baSopenharmony_ci    if (eok != EOK) {
2523d0407baSopenharmony_ci        mpp_err("memset_s failed\n");
2533d0407baSopenharmony_ci        return MPP_NOK;
2543d0407baSopenharmony_ci    }
2553d0407baSopenharmony_ci    eok = memset_s(&st_ref, sizeof(st_ref), 0, sizeof(st_ref));
2563d0407baSopenharmony_ci    if (eok != EOK) {
2573d0407baSopenharmony_ci        mpp_err("memset_s failed\n");
2583d0407baSopenharmony_ci        return MPP_NOK;
2593d0407baSopenharmony_ci    }
2603d0407baSopenharmony_ci
2613d0407baSopenharmony_ci    ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
2623d0407baSopenharmony_ci
2633d0407baSopenharmony_ci    /* set 8 frame lt-ref gap */
2643d0407baSopenharmony_ci    lt_ref[0].lt_idx        = 0;
2653d0407baSopenharmony_ci    lt_ref[0].temporal_id   = 0;
2663d0407baSopenharmony_ci    lt_ref[0].ref_mode      = REF_TO_PREV_LT_REF;
2673d0407baSopenharmony_ci    lt_ref[0].lt_gap        = gop_len;
2683d0407baSopenharmony_ci    lt_ref[0].lt_delay      = 0;
2693d0407baSopenharmony_ci
2703d0407baSopenharmony_ci    mpp_enc_ref_cfg_add_lt_cfg(ref, 1, lt_ref);
2713d0407baSopenharmony_ci
2723d0407baSopenharmony_ci    /* st 0 layer 0 - ref */
2733d0407baSopenharmony_ci    st_ref[pos].is_non_ref  = 0;
2743d0407baSopenharmony_ci    st_ref[pos].temporal_id = 0;
2753d0407baSopenharmony_ci    st_ref[pos].ref_mode    = REF_TO_PREV_INTRA;
2763d0407baSopenharmony_ci    st_ref[pos].ref_arg     = 0;
2773d0407baSopenharmony_ci    st_ref[pos].repeat      = 0;
2783d0407baSopenharmony_ci    pos++;
2793d0407baSopenharmony_ci
2803d0407baSopenharmony_ci    /* st 1 layer 1 - non-ref */
2813d0407baSopenharmony_ci    if (vi_len > 1) {
2823d0407baSopenharmony_ci        st_ref[pos].is_non_ref  = 0;
2833d0407baSopenharmony_ci        st_ref[pos].temporal_id = 1;
2843d0407baSopenharmony_ci        st_ref[pos].ref_mode    = REF_TO_PREV_REF_FRM;
2853d0407baSopenharmony_ci        st_ref[pos].ref_arg     = 0;
2863d0407baSopenharmony_ci        st_ref[pos].repeat      = vi_len - 2;
2873d0407baSopenharmony_ci        pos++;
2883d0407baSopenharmony_ci    }
2893d0407baSopenharmony_ci
2903d0407baSopenharmony_ci    st_ref[pos].is_non_ref  = 0;
2913d0407baSopenharmony_ci    st_ref[pos].temporal_id = 0;
2923d0407baSopenharmony_ci    st_ref[pos].ref_mode    = REF_TO_PREV_INTRA;
2933d0407baSopenharmony_ci    st_ref[pos].ref_arg     = 0;
2943d0407baSopenharmony_ci    st_ref[pos].repeat      = 0;
2953d0407baSopenharmony_ci    pos++;
2963d0407baSopenharmony_ci
2973d0407baSopenharmony_ci    mpp_enc_ref_cfg_add_st_cfg(ref, pos, st_ref);
2983d0407baSopenharmony_ci
2993d0407baSopenharmony_ci    /* check and get dpb size */
3003d0407baSopenharmony_ci    ret = mpp_enc_ref_cfg_check(ref);
3013d0407baSopenharmony_ci
3023d0407baSopenharmony_ci    return ret;
3033d0407baSopenharmony_ci}
3043d0407baSopenharmony_ci
3053d0407baSopenharmony_ci/* ���˱������õ�һЩ����������ߣ�����ͼ���ʽ����������ʽ�ȣ�����������֪��ֱ����0
3063d0407baSopenharmony_ci * test_mpp_enc_cfg_setup�������Զ�����Ĭ�ϵIJ�����bps�� gop�Ȳ���
3073d0407baSopenharmony_ci */
3083d0407baSopenharmony_cistatic MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd)
3093d0407baSopenharmony_ci{
3103d0407baSopenharmony_ci    MpiEncTestData *p = NULL;
3113d0407baSopenharmony_ci    MPP_RET ret = 0;
3123d0407baSopenharmony_ci
3133d0407baSopenharmony_ci    if (!data || !cmd) {
3143d0407baSopenharmony_ci        mpp_err_f("invalid input data %p cmd %p\n", data, cmd);
3153d0407baSopenharmony_ci        return MPP_ERR_NULL_PTR;
3163d0407baSopenharmony_ci    }
3173d0407baSopenharmony_ci
3183d0407baSopenharmony_ci    p = mpp_calloc(MpiEncTestData, 1);
3193d0407baSopenharmony_ci    if (!p) {
3203d0407baSopenharmony_ci        mpp_err_f("create MpiEncTestData failed\n");
3213d0407baSopenharmony_ci        ret = MPP_ERR_MALLOC;
3223d0407baSopenharmony_ci        *data = p;
3233d0407baSopenharmony_ci        return ret;
3243d0407baSopenharmony_ci    }
3253d0407baSopenharmony_ci
3263d0407baSopenharmony_ci    // get paramter from cmd
3273d0407baSopenharmony_ci    p->width        = cmd->width;
3283d0407baSopenharmony_ci    p->height       = cmd->height;
3293d0407baSopenharmony_ci    p->hor_stride   = MPP_ALIGN(cmd->width, 16); // 16:hor_stride
3303d0407baSopenharmony_ci    p->ver_stride   = MPP_ALIGN(cmd->height, 16); // 16:ver_stride
3313d0407baSopenharmony_ci    p->fmt          = cmd->format;
3323d0407baSopenharmony_ci    p->type         = cmd->type;
3333d0407baSopenharmony_ci
3343d0407baSopenharmony_ci    // update resource parameter
3353d0407baSopenharmony_ci    switch (p->fmt & MPP_FRAME_FMT_MASK) {
3363d0407baSopenharmony_ci        case MPP_FMT_YUV420SP:
3373d0407baSopenharmony_ci        case MPP_FMT_YUV420P: {
3383d0407baSopenharmony_ci            p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2;
3393d0407baSopenharmony_ci        }
3403d0407baSopenharmony_ci            break;
3413d0407baSopenharmony_ci
3423d0407baSopenharmony_ci        case MPP_FMT_YUV422_YUYV :
3433d0407baSopenharmony_ci        case MPP_FMT_YUV422_YVYU :
3443d0407baSopenharmony_ci        case MPP_FMT_YUV422_UYVY :
3453d0407baSopenharmony_ci        case MPP_FMT_YUV422_VYUY :
3463d0407baSopenharmony_ci        case MPP_FMT_YUV422P :
3473d0407baSopenharmony_ci        case MPP_FMT_YUV422SP :
3483d0407baSopenharmony_ci        case MPP_FMT_RGB444 :
3493d0407baSopenharmony_ci        case MPP_FMT_BGR444 :
3503d0407baSopenharmony_ci        case MPP_FMT_RGB555 :
3513d0407baSopenharmony_ci        case MPP_FMT_BGR555 :
3523d0407baSopenharmony_ci        case MPP_FMT_RGB565 :
3533d0407baSopenharmony_ci        case MPP_FMT_BGR565 : {
3543d0407baSopenharmony_ci            p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 2;
3553d0407baSopenharmony_ci        }
3563d0407baSopenharmony_ci            break;
3573d0407baSopenharmony_ci        default: {
3583d0407baSopenharmony_ci            p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4;
3593d0407baSopenharmony_ci        }
3603d0407baSopenharmony_ci            break;
3613d0407baSopenharmony_ci    }
3623d0407baSopenharmony_ci    *data = p;
3633d0407baSopenharmony_ci    return ret;
3643d0407baSopenharmony_ci}
3653d0407baSopenharmony_ci
3663d0407baSopenharmony_cistatic MPP_RET test_ctx_deinit(MpiEncTestData **data)
3673d0407baSopenharmony_ci{
3683d0407baSopenharmony_ci    MpiEncTestData *p = NULL;
3693d0407baSopenharmony_ci
3703d0407baSopenharmony_ci    if (!data) {
3713d0407baSopenharmony_ci        mpp_err_f("invalid input data %p\n", data);
3723d0407baSopenharmony_ci        return MPP_ERR_NULL_PTR;
3733d0407baSopenharmony_ci    }
3743d0407baSopenharmony_ci    p = *data;
3753d0407baSopenharmony_ci    if (p) {
3763d0407baSopenharmony_ci        MPP_FREE(p);
3773d0407baSopenharmony_ci        *data = NULL;
3783d0407baSopenharmony_ci    }
3793d0407baSopenharmony_ci    return MPP_OK;
3803d0407baSopenharmony_ci}
3813d0407baSopenharmony_ci
3823d0407baSopenharmony_cistatic MPP_RET test_mpp_enc_cfg_setup(MpiEncTestData *p)
3833d0407baSopenharmony_ci{
3843d0407baSopenharmony_ci    MPP_RET ret;
3853d0407baSopenharmony_ci    MppApi *mpi;
3863d0407baSopenharmony_ci    MppCtx ctx;
3873d0407baSopenharmony_ci    MppEncCfg cfg;
3883d0407baSopenharmony_ci
3893d0407baSopenharmony_ci    if (p == NULL)
3903d0407baSopenharmony_ci        return MPP_ERR_NULL_PTR;
3913d0407baSopenharmony_ci
3923d0407baSopenharmony_ci    mpi = p->mpi;
3933d0407baSopenharmony_ci    ctx = p->ctx;
3943d0407baSopenharmony_ci    cfg = p->cfg;
3953d0407baSopenharmony_ci
3963d0407baSopenharmony_ci    /* setup default parameter */
3973d0407baSopenharmony_ci    if (p->fps_in_den == 0)
3983d0407baSopenharmony_ci        p->fps_in_den = 1;
3993d0407baSopenharmony_ci    if (p->fps_in_num == 0)
4003d0407baSopenharmony_ci        p->fps_in_num = 30;
4013d0407baSopenharmony_ci    if (p->fps_out_den == 0)
4023d0407baSopenharmony_ci        p->fps_out_den = 1;
4033d0407baSopenharmony_ci    if (p->fps_out_num == 0)
4043d0407baSopenharmony_ci        p->fps_out_num = 30;
4053d0407baSopenharmony_ci
4063d0407baSopenharmony_ci    /* ����Ĭ��bps */
4073d0407baSopenharmony_ci    if (!p->bps)
4083d0407baSopenharmony_ci        p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
4093d0407baSopenharmony_ci
4103d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);
4113d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "prep:height", p->height);
4123d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", p->hor_stride);
4133d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", p->ver_stride);
4143d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "prep:format", p->fmt);
4153d0407baSopenharmony_ci
4163d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:mode", p->rc_mode);
4173d0407baSopenharmony_ci
4183d0407baSopenharmony_ci    /* fix input / output frame rate */
4193d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", p->fps_in_flex);
4203d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", p->fps_in_num);
4213d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denorm", p->fps_in_den);
4223d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", p->fps_out_flex);
4233d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", p->fps_out_num);
4243d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denorm", p->fps_out_den);
4253d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:gop", p->gop_len ? p->gop_len : p->fps_out_num * 2);
4263d0407baSopenharmony_ci
4273d0407baSopenharmony_ci    /* drop frame or not when bitrate overflow */
4283d0407baSopenharmony_ci    mpp_enc_cfg_set_u32(cfg, "rc:drop_mode", MPP_ENC_RC_DROP_FRM_DISABLED);
4293d0407baSopenharmony_ci    mpp_enc_cfg_set_u32(cfg, "rc:drop_thd", 20);        /* 20% of max bps */
4303d0407baSopenharmony_ci    mpp_enc_cfg_set_u32(cfg, "rc:drop_gap", 1);         /* Do not continuous drop frame */
4313d0407baSopenharmony_ci
4323d0407baSopenharmony_ci    /* setup bitrate for different rc_mode */
4333d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
4343d0407baSopenharmony_ci    switch (p->rc_mode) {
4353d0407baSopenharmony_ci        case MPP_ENC_RC_MODE_FIXQP : {
4363d0407baSopenharmony_ci            /* do not setup bitrate on FIXQP mode */
4373d0407baSopenharmony_ci        }
4383d0407baSopenharmony_ci            break;
4393d0407baSopenharmony_ci        case MPP_ENC_RC_MODE_CBR : {
4403d0407baSopenharmony_ci            /* CBR mode has narrow bound */
4413d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
4423d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
4433d0407baSopenharmony_ci        }
4443d0407baSopenharmony_ci            break;
4453d0407baSopenharmony_ci        case MPP_ENC_RC_MODE_VBR :
4463d0407baSopenharmony_ci        case MPP_ENC_RC_MODE_AVBR : {
4473d0407baSopenharmony_ci            /* VBR mode has wide bound */
4483d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
4493d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 1 / 16);
4503d0407baSopenharmony_ci        }
4513d0407baSopenharmony_ci            break;
4523d0407baSopenharmony_ci        default : {
4533d0407baSopenharmony_ci            /* default use CBR mode */
4543d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
4553d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
4563d0407baSopenharmony_ci        }
4573d0407baSopenharmony_ci            break;
4583d0407baSopenharmony_ci    }
4593d0407baSopenharmony_ci
4603d0407baSopenharmony_ci    /* setup qp for different codec and rc_mode */
4613d0407baSopenharmony_ci    switch (p->type) {
4623d0407baSopenharmony_ci        case MPP_VIDEO_CodingAVC :
4633d0407baSopenharmony_ci        case MPP_VIDEO_CodingHEVC : {
4643d0407baSopenharmony_ci            switch (p->rc_mode) {
4653d0407baSopenharmony_ci                case MPP_ENC_RC_MODE_FIXQP : {
4663d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_init", 20); // 20:mpp cfg value
4673d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_max", 20); // 20:mpp cfg value
4683d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_min", 20); // 20:mpp cfg value
4693d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 20); // 20:mpp cfg value
4703d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 20); // 20:mpp cfg value
4713d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
4723d0407baSopenharmony_ci                }
4733d0407baSopenharmony_ci                    break;
4743d0407baSopenharmony_ci                case MPP_ENC_RC_MODE_CBR :
4753d0407baSopenharmony_ci                case MPP_ENC_RC_MODE_VBR :
4763d0407baSopenharmony_ci                case MPP_ENC_RC_MODE_AVBR : {
4773d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_init", 26); // 26:mpp cfg value
4783d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_max", 51); // 51:mpp cfg value
4793d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_min", 10); // 10:mpp cfg value
4803d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 51); // 51:mpp cfg value
4813d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 10); // 10:mpp cfg value
4823d0407baSopenharmony_ci                    mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
4833d0407baSopenharmony_ci                }
4843d0407baSopenharmony_ci                    break;
4853d0407baSopenharmony_ci                default : {
4863d0407baSopenharmony_ci                    mpp_err_f("unsupport encoder rc mode %d\n", p->rc_mode);
4873d0407baSopenharmony_ci                }
4883d0407baSopenharmony_ci                    break;
4893d0407baSopenharmony_ci            }
4903d0407baSopenharmony_ci        }
4913d0407baSopenharmony_ci            break;
4923d0407baSopenharmony_ci        case MPP_VIDEO_CodingVP8 : {
4933d0407baSopenharmony_ci            /* vp8 only setup base qp range */
4943d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:qp_init", 40); // 40:mpp cfg value
4953d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:qp_max",  127); // 127:mpp cfg value
4963d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:qp_min",  0);
4973d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 127); // 127:mpp cfg value
4983d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 0);
4993d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 6); // 6:mpp cfg value
5003d0407baSopenharmony_ci        }
5013d0407baSopenharmony_ci            break;
5023d0407baSopenharmony_ci        case MPP_VIDEO_CodingMJPEG : {
5033d0407baSopenharmony_ci            /* jpeg use special codec config to control qtable */
5043d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", 80); // 80:mpp cfg value
5053d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", 99); // 99:mpp cfg value
5063d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", 1);
5073d0407baSopenharmony_ci        }
5083d0407baSopenharmony_ci            break;
5093d0407baSopenharmony_ci        default : {
5103d0407baSopenharmony_ci        }
5113d0407baSopenharmony_ci            break;
5123d0407baSopenharmony_ci    }
5133d0407baSopenharmony_ci
5143d0407baSopenharmony_ci    /* setup codec  */
5153d0407baSopenharmony_ci    mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
5163d0407baSopenharmony_ci    switch (p->type) {
5173d0407baSopenharmony_ci        case MPP_VIDEO_CodingAVC : {
5183d0407baSopenharmony_ci            /*
5193d0407baSopenharmony_ci            * H.264 profile_idc parameter
5203d0407baSopenharmony_ci            * 66  - Baseline profile
5213d0407baSopenharmony_ci            * 77  - Main profile
5223d0407baSopenharmony_ci            * 100 - High profile
5233d0407baSopenharmony_ci            */
5243d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
5253d0407baSopenharmony_ci            /*
5263d0407baSopenharmony_ci            * H.264 level_idc parameter
5273d0407baSopenharmony_ci            * 10 / 11 / 12 / 13    - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
5283d0407baSopenharmony_ci            * 20 / 21 / 22         - cif@30fps / half-D1@@25fps / D1@12.5fps
5293d0407baSopenharmony_ci            * 30 / 31 / 32         - D1@25fps / 720p@30fps / 720p@60fps
5303d0407baSopenharmony_ci            * 40 / 41 / 42         - 1080p@30fps / 1080p@30fps / 1080p@60fps
5313d0407baSopenharmony_ci            * 50 / 51 / 52         - 4K@30fps
5323d0407baSopenharmony_ci            */
5333d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
5343d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
5353d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
5363d0407baSopenharmony_ci            mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
5373d0407baSopenharmony_ci        }
5383d0407baSopenharmony_ci            break;
5393d0407baSopenharmony_ci        case MPP_VIDEO_CodingHEVC :
5403d0407baSopenharmony_ci        case MPP_VIDEO_CodingMJPEG :
5413d0407baSopenharmony_ci        case MPP_VIDEO_CodingVP8 : {
5423d0407baSopenharmony_ci        }
5433d0407baSopenharmony_ci            break;
5443d0407baSopenharmony_ci        default : {
5453d0407baSopenharmony_ci            mpp_err_f("unsupport encoder coding type %d\n", p->type);
5463d0407baSopenharmony_ci        }
5473d0407baSopenharmony_ci            break;
5483d0407baSopenharmony_ci    }
5493d0407baSopenharmony_ci
5503d0407baSopenharmony_ci    p->split_mode = 0;
5513d0407baSopenharmony_ci    p->split_arg = 0;
5523d0407baSopenharmony_ci
5533d0407baSopenharmony_ci    mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
5543d0407baSopenharmony_ci    mpp_env_get_u32("split_arg", &p->split_arg, 0);
5553d0407baSopenharmony_ci
5563d0407baSopenharmony_ci    if (p->split_mode) {
5573d0407baSopenharmony_ci        mpp_log("%p split_mode %d split_arg %d\n", ctx, p->split_mode, p->split_arg);
5583d0407baSopenharmony_ci        mpp_enc_cfg_set_s32(cfg, "split:mode", p->split_mode);
5593d0407baSopenharmony_ci        mpp_enc_cfg_set_s32(cfg, "split:arg", p->split_arg);
5603d0407baSopenharmony_ci    }
5613d0407baSopenharmony_ci
5623d0407baSopenharmony_ci    ret = mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
5633d0407baSopenharmony_ci    if (ret) {
5643d0407baSopenharmony_ci        mpp_err("mpi control enc set cfg failed ret %d\n", ret);
5653d0407baSopenharmony_ci        return ret;
5663d0407baSopenharmony_ci    }
5673d0407baSopenharmony_ci
5683d0407baSopenharmony_ci    /* optional */
5693d0407baSopenharmony_ci    p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
5703d0407baSopenharmony_ci    ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
5713d0407baSopenharmony_ci    if (ret) {
5723d0407baSopenharmony_ci        mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
5733d0407baSopenharmony_ci        return ret;
5743d0407baSopenharmony_ci    }
5753d0407baSopenharmony_ci
5763d0407baSopenharmony_ci    if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
5773d0407baSopenharmony_ci        p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
5783d0407baSopenharmony_ci        ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
5793d0407baSopenharmony_ci        if (ret) {
5803d0407baSopenharmony_ci            mpp_err("mpi control enc set header mode failed ret %d\n", ret);
5813d0407baSopenharmony_ci            return ret;
5823d0407baSopenharmony_ci        }
5833d0407baSopenharmony_ci    }
5843d0407baSopenharmony_ci
5853d0407baSopenharmony_ci    RK_U32 gop_mode = p->gop_mode;
5863d0407baSopenharmony_ci
5873d0407baSopenharmony_ci    mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
5883d0407baSopenharmony_ci    if (gop_mode) {
5893d0407baSopenharmony_ci        MppEncRefCfg ref;
5903d0407baSopenharmony_ci
5913d0407baSopenharmony_ci        mpp_enc_ref_cfg_init(&ref);
5923d0407baSopenharmony_ci
5933d0407baSopenharmony_ci        if (p->gop_mode < 4) {
5943d0407baSopenharmony_ci            mpi_enc_gen_ref_cfg(ref, gop_mode);
5953d0407baSopenharmony_ci        } else {
5963d0407baSopenharmony_ci            mpi_enc_gen_smart_gop_ref_cfg(ref, p->gop_len, p->vi_len);
5973d0407baSopenharmony_ci        }
5983d0407baSopenharmony_ci        ret = mpi->control(ctx, MPP_ENC_SET_REF_CFG, ref);
5993d0407baSopenharmony_ci        if (ret) {
6003d0407baSopenharmony_ci            mpp_err("mpi control enc set ref cfg failed ret %d\n", ret);
6013d0407baSopenharmony_ci            return ret;
6023d0407baSopenharmony_ci        }
6033d0407baSopenharmony_ci        mpp_enc_ref_cfg_deinit(&ref);
6043d0407baSopenharmony_ci    }
6053d0407baSopenharmony_ci    return ret;
6063d0407baSopenharmony_ci}
6073d0407baSopenharmony_ci
6083d0407baSopenharmony_cistatic void test_mpp_frame_set_param(MppFrame frame, MpiEncTestData *p)
6093d0407baSopenharmony_ci{
6103d0407baSopenharmony_ci    mpp_frame_set_width(frame, p->width);
6113d0407baSopenharmony_ci    mpp_frame_set_height(frame, p->height);
6123d0407baSopenharmony_ci    mpp_frame_set_hor_stride(frame, p->hor_stride);
6133d0407baSopenharmony_ci    mpp_frame_set_ver_stride(frame, p->ver_stride);
6143d0407baSopenharmony_ci    mpp_frame_set_fmt(frame, p->fmt);
6153d0407baSopenharmony_ci    mpp_frame_set_eos(frame, p->frm_eos);
6163d0407baSopenharmony_ci}
6173d0407baSopenharmony_ci
6183d0407baSopenharmony_cistatic void test_mpp_ctx_cleanup(MpiEncTestData *p)
6193d0407baSopenharmony_ci{
6203d0407baSopenharmony_ci    if (!p) {
6213d0407baSopenharmony_ci        mpp_err("test_mpp_ctx_cleanup p == NULL\n");
6223d0407baSopenharmony_ci        return;
6233d0407baSopenharmony_ci    }
6243d0407baSopenharmony_ci
6253d0407baSopenharmony_ci    if (p->mpi->reset) {
6263d0407baSopenharmony_ci        p->mpi->reset(p->ctx);
6273d0407baSopenharmony_ci    }
6283d0407baSopenharmony_ci
6293d0407baSopenharmony_ci    if (p->ctx) {
6303d0407baSopenharmony_ci        mpp_destroy(p->ctx);
6313d0407baSopenharmony_ci        p->ctx = NULL;
6323d0407baSopenharmony_ci    }
6333d0407baSopenharmony_ci
6343d0407baSopenharmony_ci    if (p->cfg) {
6353d0407baSopenharmony_ci        mpp_enc_cfg_deinit(p->cfg);
6363d0407baSopenharmony_ci        p->cfg = NULL;
6373d0407baSopenharmony_ci    }
6383d0407baSopenharmony_ci
6393d0407baSopenharmony_ci    if (p->pkt_buf) {
6403d0407baSopenharmony_ci        mpp_buffer_put(p->pkt_buf);
6413d0407baSopenharmony_ci        p->pkt_buf = NULL;
6423d0407baSopenharmony_ci    }
6433d0407baSopenharmony_ci
6443d0407baSopenharmony_ci    if (p->buf_grp) {
6453d0407baSopenharmony_ci        mpp_buffer_group_put(p->buf_grp);
6463d0407baSopenharmony_ci        p->buf_grp = NULL;
6473d0407baSopenharmony_ci    }
6483d0407baSopenharmony_ci
6493d0407baSopenharmony_ci    test_ctx_deinit(&p);
6503d0407baSopenharmony_ci}
6513d0407baSopenharmony_ci
6523d0407baSopenharmony_ciint hal_mpp_get_sps(void *ctx, unsigned char *buf, size_t *buf_size)
6533d0407baSopenharmony_ci{
6543d0407baSopenharmony_ci    int ret;
6553d0407baSopenharmony_ci    MppApi *mpi;
6563d0407baSopenharmony_ci    MppCtx mpp_ctx;
6573d0407baSopenharmony_ci    MppPacket packet = NULL;
6583d0407baSopenharmony_ci    MpiEncTestData *p = (MpiEncTestData *)ctx;
6593d0407baSopenharmony_ci    errno_t eok;
6603d0407baSopenharmony_ci
6613d0407baSopenharmony_ci    if (!p) {
6623d0407baSopenharmony_ci        mpp_err("mpi control enc get extra info failed\n");
6633d0407baSopenharmony_ci        return MPP_NOK;
6643d0407baSopenharmony_ci    }
6653d0407baSopenharmony_ci    mpi = p->mpi;
6663d0407baSopenharmony_ci    mpp_ctx = p->ctx;
6673d0407baSopenharmony_ci
6683d0407baSopenharmony_ci    /*
6693d0407baSopenharmony_ci     * Can use packet with normal malloc buffer as input not pkt_buf.
6703d0407baSopenharmony_ci     * Please refer to vpu_api_legacy.cpp for normal buffer case.
6713d0407baSopenharmony_ci     * Using pkt_buf buffer here is just for simplifing demo.
6723d0407baSopenharmony_ci     */
6733d0407baSopenharmony_ci
6743d0407baSopenharmony_ci    mpp_packet_init_with_buffer(&packet, p->pkt_buf);
6753d0407baSopenharmony_ci    /* NOTE: It is important to clear output packet length!! */
6763d0407baSopenharmony_ci    mpp_packet_set_length(packet, 0);
6773d0407baSopenharmony_ci
6783d0407baSopenharmony_ci    // ����һ��H264��H265ר�õ�һЩ����
6793d0407baSopenharmony_ci    if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
6803d0407baSopenharmony_ci        ret = mpi->control(mpp_ctx, MPP_ENC_GET_HDR_SYNC, packet);
6813d0407baSopenharmony_ci        if (ret) {
6823d0407baSopenharmony_ci            mpp_err("mpi control enc get extra info failed\n");
6833d0407baSopenharmony_ci            ret = MPP_NOK;
6843d0407baSopenharmony_ci            mpp_packet_deinit(&packet);
6853d0407baSopenharmony_ci            return ret;
6863d0407baSopenharmony_ci        }
6873d0407baSopenharmony_ci    }
6883d0407baSopenharmony_ci
6893d0407baSopenharmony_ci    void *ptr = mpp_packet_get_pos(packet);
6903d0407baSopenharmony_ci    size_t len = mpp_packet_get_length(packet);
6913d0407baSopenharmony_ci    if (*buf_size < len) {
6923d0407baSopenharmony_ci        mpp_err("mpi buffer size too small\n");
6933d0407baSopenharmony_ci        ret = MPP_NOK;
6943d0407baSopenharmony_ci        mpp_packet_deinit(&packet);
6953d0407baSopenharmony_ci        return ret;
6963d0407baSopenharmony_ci    }
6973d0407baSopenharmony_ci
6983d0407baSopenharmony_ci    eok = memcpy_s(buf, len, ptr, len);
6993d0407baSopenharmony_ci    if (eok != EOK) {
7003d0407baSopenharmony_ci        mpp_err("memcpy_s failed\n");
7013d0407baSopenharmony_ci        return MPP_NOK;
7023d0407baSopenharmony_ci    }
7033d0407baSopenharmony_ci
7043d0407baSopenharmony_ci    *buf_size = len;
7053d0407baSopenharmony_ci
7063d0407baSopenharmony_ci    ret = MPP_OK;
7073d0407baSopenharmony_ci    mpp_packet_deinit(&packet);
7083d0407baSopenharmony_ci    return ret;
7093d0407baSopenharmony_ci}
7103d0407baSopenharmony_ci
7113d0407baSopenharmony_ciint hal_mpp_encode(void *ctx, int dma_fd, unsigned char *buf, size_t *buf_size)
7123d0407baSopenharmony_ci{
7133d0407baSopenharmony_ci    if (!ctx) {
7143d0407baSopenharmony_ci        mpp_err("memset_s failed\n");
7153d0407baSopenharmony_ci        return MPP_NOK;
7163d0407baSopenharmony_ci    }
7173d0407baSopenharmony_ci
7183d0407baSopenharmony_ci    MPP_RET ret = 0;
7193d0407baSopenharmony_ci    MppFrame frame = NULL;
7203d0407baSopenharmony_ci    MppMeta meta = NULL;
7213d0407baSopenharmony_ci    MppPacket packet = NULL;
7223d0407baSopenharmony_ci    MpiEncTestData *p = (MpiEncTestData *)ctx;
7233d0407baSopenharmony_ci    MppApi *mpi = p->mpi;
7243d0407baSopenharmony_ci    RK_U32 eoi = 1;
7253d0407baSopenharmony_ci    RK_U32 packet_num = 0;
7263d0407baSopenharmony_ci    MppBuffer cam_buf = NULL;
7273d0407baSopenharmony_ci    MppBufferInfo info;
7283d0407baSopenharmony_ci
7293d0407baSopenharmony_ci    errno_t eok = memset_s(&info, sizeof(MppBufferInfo), 0, sizeof(MppBufferInfo));
7303d0407baSopenharmony_ci    if (eok != EOK) {
7313d0407baSopenharmony_ci        mpp_err("memset_s failed\n");
7323d0407baSopenharmony_ci        return MPP_NOK;
7333d0407baSopenharmony_ci    }
7343d0407baSopenharmony_ci    info.type = MPP_BUFFER_TYPE_EXT_DMA;
7353d0407baSopenharmony_ci    info.fd = dma_fd;
7363d0407baSopenharmony_ci    info.size = p->frame_size & 0x07ffffff;
7373d0407baSopenharmony_ci    info.index = (p->frame_size & 0xf8000000) >> 27;
7383d0407baSopenharmony_ci
7393d0407baSopenharmony_ci    ret = mpp_buffer_import(&cam_buf, &info);
7403d0407baSopenharmony_ci    if (ret != MPP_SUCCESS) {
7413d0407baSopenharmony_ci        mpp_err_f("mpp_buffer_import failed\n");
7423d0407baSopenharmony_ci        return MPP_NOK;
7433d0407baSopenharmony_ci    }
7443d0407baSopenharmony_ci
7453d0407baSopenharmony_ci    ret = mpp_frame_init(&frame);
7463d0407baSopenharmony_ci    if (ret) {
7473d0407baSopenharmony_ci        mpp_err_f("mpp_frame_init failed\n");
7483d0407baSopenharmony_ci        return MPP_NOK;
7493d0407baSopenharmony_ci    }
7503d0407baSopenharmony_ci
7513d0407baSopenharmony_ci    /* set frame size info */
7523d0407baSopenharmony_ci    test_mpp_frame_set_param(frame, p);
7533d0407baSopenharmony_ci
7543d0407baSopenharmony_ci    /* set frame data include fd */
7553d0407baSopenharmony_ci    mpp_frame_set_buffer(frame, cam_buf);
7563d0407baSopenharmony_ci
7573d0407baSopenharmony_ci    /* packet init */
7583d0407baSopenharmony_ci    mpp_packet_init_with_buffer(&packet, p->pkt_buf);
7593d0407baSopenharmony_ci    /* NOTE: It is important to clear output packet length!! */
7603d0407baSopenharmony_ci    mpp_packet_set_length(packet, 0);
7613d0407baSopenharmony_ci
7623d0407baSopenharmony_ci    meta = mpp_frame_get_meta(frame);
7633d0407baSopenharmony_ci    mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);
7643d0407baSopenharmony_ci
7653d0407baSopenharmony_ci    /*
7663d0407baSopenharmony_ci     * NOTE: in non-block mode the frame can be resent.
7673d0407baSopenharmony_ci     * The default input timeout mode is block.
7683d0407baSopenharmony_ci     *
7693d0407baSopenharmony_ci     * User should release the input frame to meet the requirements of
7703d0407baSopenharmony_ci     * resource creator must be the resource destroyer.
7713d0407baSopenharmony_ci     */
7723d0407baSopenharmony_ci    ret = mpi->encode_put_frame(p->ctx, frame);
7733d0407baSopenharmony_ci    if (ret) {
7743d0407baSopenharmony_ci        mpp_err("mpp encode put frame failed\n");
7753d0407baSopenharmony_ci        mpp_frame_deinit(&frame);
7763d0407baSopenharmony_ci        if (cam_buf) {
7773d0407baSopenharmony_ci            mpp_buffer_put(cam_buf);
7783d0407baSopenharmony_ci        }
7793d0407baSopenharmony_ci        mpp_packet_deinit(&packet);
7803d0407baSopenharmony_ci        return ret;
7813d0407baSopenharmony_ci    }
7823d0407baSopenharmony_ci
7833d0407baSopenharmony_ci    mpp_frame_deinit(&frame);
7843d0407baSopenharmony_ci
7853d0407baSopenharmony_ci    packet_num = 0;
7863d0407baSopenharmony_ci
7873d0407baSopenharmony_ci    do {
7883d0407baSopenharmony_ci        ret = mpi->encode_get_packet(p->ctx, &packet);
7893d0407baSopenharmony_ci        if (ret) {
7903d0407baSopenharmony_ci            mpp_err("mpp encode get packet failed\n");
7913d0407baSopenharmony_ci            if (cam_buf) {
7923d0407baSopenharmony_ci                mpp_buffer_put(cam_buf);
7933d0407baSopenharmony_ci            }
7943d0407baSopenharmony_ci            mpp_packet_deinit(&packet);
7953d0407baSopenharmony_ci            return ret;
7963d0407baSopenharmony_ci        }
7973d0407baSopenharmony_ci
7983d0407baSopenharmony_ci        mpp_assert(packet);
7993d0407baSopenharmony_ci
8003d0407baSopenharmony_ci        if (packet) {
8013d0407baSopenharmony_ci            /* for low delay partition encoding */
8023d0407baSopenharmony_ci            if (mpp_packet_is_partition(packet)) {
8033d0407baSopenharmony_ci                eoi = mpp_packet_is_eoi(packet);
8043d0407baSopenharmony_ci            }
8053d0407baSopenharmony_ci
8063d0407baSopenharmony_ci            p->frame_count += eoi;
8073d0407baSopenharmony_ci            packet_num++;
8083d0407baSopenharmony_ci        }
8093d0407baSopenharmony_ci    } while (!eoi);
8103d0407baSopenharmony_ci
8113d0407baSopenharmony_ci    void *ptr = mpp_packet_get_pos(packet);
8123d0407baSopenharmony_ci    size_t len = mpp_packet_get_length(packet);
8133d0407baSopenharmony_ci
8143d0407baSopenharmony_ci    if (packet_num != 1) {
8153d0407baSopenharmony_ci        mpp_err("packet_num %u != 1\n");
8163d0407baSopenharmony_ci        ret = MPP_NOK;
8173d0407baSopenharmony_ci        if (cam_buf) {
8183d0407baSopenharmony_ci            mpp_buffer_put(cam_buf);
8193d0407baSopenharmony_ci        }
8203d0407baSopenharmony_ci        mpp_packet_deinit(&packet);
8213d0407baSopenharmony_ci        return ret;
8223d0407baSopenharmony_ci    }
8233d0407baSopenharmony_ci
8243d0407baSopenharmony_ci    if (*buf_size < len) {
8253d0407baSopenharmony_ci        mpp_err("mpi buffer size too small\n");
8263d0407baSopenharmony_ci        ret = MPP_NOK;
8273d0407baSopenharmony_ci        if (cam_buf) {
8283d0407baSopenharmony_ci            mpp_buffer_put(cam_buf);
8293d0407baSopenharmony_ci        }
8303d0407baSopenharmony_ci        mpp_packet_deinit(&packet);
8313d0407baSopenharmony_ci        return ret;
8323d0407baSopenharmony_ci    }
8333d0407baSopenharmony_ci
8343d0407baSopenharmony_ci    eok = memcpy_s(buf, len, ptr, len);
8353d0407baSopenharmony_ci    if (eok != EOK) {
8363d0407baSopenharmony_ci        mpp_err("memcpy_s failed\n");
8373d0407baSopenharmony_ci        return MPP_NOK;
8383d0407baSopenharmony_ci    }
8393d0407baSopenharmony_ci
8403d0407baSopenharmony_ci    *buf_size = len;
8413d0407baSopenharmony_ci
8423d0407baSopenharmony_ci    ret = MPP_OK;
8433d0407baSopenharmony_ci    if (cam_buf)
8443d0407baSopenharmony_ci        mpp_buffer_put(cam_buf);
8453d0407baSopenharmony_ci
8463d0407baSopenharmony_ci    mpp_packet_deinit(&packet);
8473d0407baSopenharmony_ci    return ret;
8483d0407baSopenharmony_ci}
8493d0407baSopenharmony_ci
8503d0407baSopenharmony_civoid *hal_mpp_ctx_create(MpiEncTestArgs *args)
8513d0407baSopenharmony_ci{
8523d0407baSopenharmony_ci    MPP_RET ret = 0;
8533d0407baSopenharmony_ci    MpiEncTestData *p = NULL;
8543d0407baSopenharmony_ci    MppPollType timeout = MPP_POLL_BLOCK;
8553d0407baSopenharmony_ci
8563d0407baSopenharmony_ci    /* ��ʼ��һ�³��õIJ������ã�cmd�����ñȽ϶� */
8573d0407baSopenharmony_ci    ret = test_ctx_init(&p, args);
8583d0407baSopenharmony_ci    if (ret) {
8593d0407baSopenharmony_ci        mpp_err_f("test data init failed ret %d\n", ret);
8603d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
8613d0407baSopenharmony_ci        return NULL;
8623d0407baSopenharmony_ci    }
8633d0407baSopenharmony_ci
8643d0407baSopenharmony_ci    ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_DRM);
8653d0407baSopenharmony_ci    if (ret) {
8663d0407baSopenharmony_ci        mpp_err_f("failed to get mpp buffer group ret %d\n", ret);
8673d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
8683d0407baSopenharmony_ci        return NULL;
8693d0407baSopenharmony_ci    }
8703d0407baSopenharmony_ci
8713d0407baSopenharmony_ci    /* pkt_buf�����Ա���?���Ǹ�packetʹ�õ�buffer */
8723d0407baSopenharmony_ci    ret = mpp_buffer_get(p->buf_grp, &p->pkt_buf, p->frame_size);
8733d0407baSopenharmony_ci    if (ret) {
8743d0407baSopenharmony_ci        mpp_err_f("failed to get buffer for output packet ret %d\n", ret);
8753d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
8763d0407baSopenharmony_ci        return NULL;
8773d0407baSopenharmony_ci    }
8783d0407baSopenharmony_ci
8793d0407baSopenharmony_ci    // encoder demo
8803d0407baSopenharmony_ci    ret = mpp_create(&p->ctx, &p->mpi);
8813d0407baSopenharmony_ci    if (ret) {
8823d0407baSopenharmony_ci        mpp_err("mpp_create failed ret %d\n", ret);
8833d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
8843d0407baSopenharmony_ci        return NULL;
8853d0407baSopenharmony_ci    }
8863d0407baSopenharmony_ci
8873d0407baSopenharmony_ci    mpp_log("%p mpi_enc_test encoder test start w %d h %d type %d\n",
8883d0407baSopenharmony_ci            p->ctx, p->width, p->height, p->type);
8893d0407baSopenharmony_ci
8903d0407baSopenharmony_ci    ret = p->mpi->control(p->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
8913d0407baSopenharmony_ci    if (MPP_OK != ret) {
8923d0407baSopenharmony_ci        mpp_err("mpi control set output timeout %d ret %d\n", timeout, ret);
8933d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
8943d0407baSopenharmony_ci        return NULL;
8953d0407baSopenharmony_ci    }
8963d0407baSopenharmony_ci
8973d0407baSopenharmony_ci    ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type);
8983d0407baSopenharmony_ci    if (ret) {
8993d0407baSopenharmony_ci        mpp_err("mpp_init failed ret %d\n", ret);
9003d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
9013d0407baSopenharmony_ci        return NULL;
9023d0407baSopenharmony_ci    }
9033d0407baSopenharmony_ci
9043d0407baSopenharmony_ci    ret = mpp_enc_cfg_init(&p->cfg);
9053d0407baSopenharmony_ci    if (ret) {
9063d0407baSopenharmony_ci        mpp_err_f("mpp_enc_cfg_init failed ret %d\n", ret);
9073d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
9083d0407baSopenharmony_ci        return NULL;
9093d0407baSopenharmony_ci    }
9103d0407baSopenharmony_ci
9113d0407baSopenharmony_ci    ret = test_mpp_enc_cfg_setup(p);
9123d0407baSopenharmony_ci    if (ret) {
9133d0407baSopenharmony_ci        mpp_err_f("test mpp setup failed ret %d\n", ret);
9143d0407baSopenharmony_ci        mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
9153d0407baSopenharmony_ci        return NULL;
9163d0407baSopenharmony_ci    }
9173d0407baSopenharmony_ci
9183d0407baSopenharmony_ci    return p;
9193d0407baSopenharmony_ci}
9203d0407baSopenharmony_ci
9213d0407baSopenharmony_civoid hal_mpp_ctx_delete(void *ctx)
9223d0407baSopenharmony_ci{
9233d0407baSopenharmony_ci    test_mpp_ctx_cleanup(ctx);
9243d0407baSopenharmony_ci}
925