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(<_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(<_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