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