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