/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* * Copyright (c) 2024 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_sys_cfg" #include #include "rk_mpp_cfg.h" #include "mpp_env.h" #include "mpp_mem.h" #include "mpp_list.h" #include "mpp_time.h" #include "mpp_debug.h" #include "mpp_common.h" #include "mpp_thread.h" #include "mpp_singleton.h" #include "mpp_cfg.h" #include "mpp_soc.h" #include "mpp_trie.h" #include "mpp_sys_cfg.h" #include "mpp_mem_pool.h" #include "mpp_compat_impl.h" #define SYS_CFG_DBG_FUNC (0x00000001) #define SYS_CFG_DBG_INFO (0x00000002) #define SYS_CFG_DBG_SET (0x00000004) #define SYS_CFG_DBG_GET (0x00000008) #define SYS_CFG_DBG_DEC_BUF (0x00000010) #define sys_cfg_dbg(flag, fmt, ...) _mpp_dbg_f(mpp_sys_cfg_debug, flag, fmt, ## __VA_ARGS__) #define sys_cfg_dbg_func(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_FUNC, fmt, ## __VA_ARGS__) #define sys_cfg_dbg_info(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_INFO, fmt, ## __VA_ARGS__) #define sys_cfg_dbg_set(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_SET, fmt, ## __VA_ARGS__) #define sys_cfg_dbg_get(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_GET, fmt, ## __VA_ARGS__) #define sys_cfg_dbg_dec_buf(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_DEC_BUF, fmt, ## __VA_ARGS__) #define get_srv_sys_cfg_f() \ ({ \ MppSysCfgSrv *__tmp; \ if (srv_sys_cfg) { \ __tmp = srv_sys_cfg; \ } else { \ mpp_sys_cfg_srv_init(); \ __tmp = srv_sys_cfg; \ if (!__tmp) \ mpp_err("mpp sys cfg srv not init at %s\n", __FUNCTION__); \ } \ __tmp; \ }) typedef struct MppSysCfgSrv_t { MppTrie trie; MppMemPool pool; } MppSysCfgSrv; static MppSysCfgSrv *srv_sys_cfg = NULL; static RK_U32 mpp_sys_cfg_debug = 0; #define EXPAND_AS_TRIE(base, name, cfg_type, in_type, flag, field_change, field_data) \ do { \ MppCfgInfo tmp = { \ CFG_FUNC_TYPE_##cfg_type, \ (RK_U32)((long)&(((MppSysCfgSet *)0)->field_change.change)), \ (RK_U32)((long)&(((MppSysCfgSet *)0)->field_change.field_data)), \ sizeof((((MppSysCfgSet *)0)->field_change.field_data)), \ }; \ mpp_trie_add_info(srv->trie, #base":"#name, &tmp, sizeof(tmp)); \ } while (0); #define ENTRY_TABLE(ENTRY) \ ENTRY(dec_buf_chk, enable, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_ENABLE, dec_buf_chk, enable) \ ENTRY(dec_buf_chk, type, u32, MppCodingType, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_TYPE, dec_buf_chk, type) \ ENTRY(dec_buf_chk, fmt_codec, u32, MppFrameFormat, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FMT_CODEC, dec_buf_chk, fmt_codec) \ ENTRY(dec_buf_chk, fmt_fbc, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FMT_FBC, dec_buf_chk, fmt_fbc) \ ENTRY(dec_buf_chk, fmt_hdr, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FMT_HDR, dec_buf_chk, fmt_hdr) \ ENTRY(dec_buf_chk, width, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_WIDTH, dec_buf_chk, width) \ ENTRY(dec_buf_chk, height, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_HEIGHT, dec_buf_chk, height) \ ENTRY(dec_buf_chk, crop_top, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_TOP, dec_buf_chk, crop_top) \ ENTRY(dec_buf_chk, crop_bottom, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_BOTTOM, dec_buf_chk, crop_bottom) \ ENTRY(dec_buf_chk, crop_left, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_LEFT, dec_buf_chk, crop_left) \ ENTRY(dec_buf_chk, crop_right, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_RIGHT, dec_buf_chk, crop_right) \ ENTRY(dec_buf_chk, unit_size, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_RIGHT, dec_buf_chk, unit_size) \ ENTRY(dec_buf_chk, has_metadata, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FLAG_METADATA, dec_buf_chk, has_metadata) \ ENTRY(dec_buf_chk, has_thumbnail, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FLAG_THUMBNAIL, dec_buf_chk, has_thumbnail) \ ENTRY(dec_buf_chk, h_stride_by_byte, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_H_STRIDE_BYTE, dec_buf_chk, h_stride_by_byte) \ ENTRY(dec_buf_chk, v_stride, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_V_STRIDE, dec_buf_chk, v_stride) \ /* read-only config */ \ ENTRY(dec_buf_chk, cap_fbc, u32, RK_U32, 0, dec_buf_chk, cap_fbc) \ ENTRY(dec_buf_chk, cap_tile, u32, RK_U32, 0, dec_buf_chk, cap_tile) \ ENTRY(dec_buf_chk, h_stride_by_pixel, u32, RK_U32, 0, dec_buf_chk, h_stride_by_pixel) \ ENTRY(dec_buf_chk, offset_y, u32, RK_U32, 0, dec_buf_chk, offset_y) \ ENTRY(dec_buf_chk, size_total, u32, RK_U32, 0, dec_buf_chk, size_total) \ ENTRY(dec_buf_chk, size_fbc_hdr, u32, RK_U32, 0, dec_buf_chk, size_fbc_hdr) \ ENTRY(dec_buf_chk, size_fbc_bdy, u32, RK_U32, 0, dec_buf_chk, size_fbc_bdy) \ ENTRY(dec_buf_chk, size_metadata, u32, RK_U32, 0, dec_buf_chk, size_metadata) \ ENTRY(dec_buf_chk, size_thumbnail, u32, RK_U32, 0, dec_buf_chk, size_thumbnail) static void mpp_sys_cfg_srv_init() { MppSysCfgSrv *srv = srv_sys_cfg; mpp_env_get_u32("mpp_sys_cfg_debug", &mpp_sys_cfg_debug, mpp_sys_cfg_debug); if (srv) return ; srv = mpp_calloc(MppSysCfgSrv, 1); if (!srv) { mpp_err_f("failed to allocate sys cfg set service\n"); return ; } mpp_trie_init(&srv->trie, "MppSysCfg"); srv->pool = mpp_mem_pool_init_f(MODULE_TAG, sizeof(MppSysCfgSet)); if (!srv->trie || !srv->pool) { mpp_err_f("failed to init sys cfg set service\n"); if (srv->trie) { mpp_trie_deinit(srv->trie); srv->trie = NULL; } if (srv->pool) { mpp_mem_pool_deinit_f(srv->pool); srv->pool = NULL; } MPP_FREE(srv); return ; } srv_sys_cfg = srv; ENTRY_TABLE(EXPAND_AS_TRIE) mpp_trie_add_info(srv->trie, NULL, NULL, 0); sys_cfg_dbg_func("info cnt %d node cnt %d size %d\n", mpp_trie_get_info_count(srv->trie), mpp_trie_get_node_count(srv->trie), mpp_trie_get_buf_size(srv->trie)); } static void mpp_sys_cfg_srv_deinit() { MppSysCfgSrv *srv = srv_sys_cfg; if (!srv) return ; if (srv->trie) { mpp_trie_deinit(srv->trie); srv->trie = NULL; } if (srv->pool) { mpp_mem_pool_deinit_f(srv->pool); srv->pool = NULL; } MPP_FREE(srv_sys_cfg); } MPP_SINGLETON(MPP_SGLN_SYS_CFG, mpp_sys_cfg, mpp_sys_cfg_srv_init, mpp_sys_cfg_srv_deinit) static MppSysCfgSet *srv_get_cfg(MppSysCfgSrv *srv) { MppSysCfgSet *node = (MppSysCfgSet*)mpp_mem_pool_get_f(srv->pool); node->dec_buf_chk.type = MPP_VIDEO_CodingUnused; return node; } static MPP_RET srv_put_cfg(MppSysCfgSrv *srv, MppSysCfgSet *node) { mpp_mem_pool_put_f(srv->pool, node); return MPP_OK; } MPP_RET mpp_sys_cfg_get(MppSysCfg *cfg) { MppSysCfgSrv *srv = get_srv_sys_cfg_f(); if (!cfg) { mpp_err_f("invalid NULL input config\n"); return MPP_ERR_NULL_PTR; } *cfg = NULL; if (!srv) return MPP_NOK; mpp_env_get_u32("mpp_sys_cfg_debug", &mpp_sys_cfg_debug, mpp_sys_cfg_debug); *cfg = srv_get_cfg(srv); return *cfg ? MPP_OK : MPP_NOK; } MPP_RET mpp_sys_cfg_put(MppSysCfg cfg) { MppSysCfgSrv *srv = get_srv_sys_cfg_f(); if (!srv) return MPP_NOK; return srv_put_cfg(srv, (MppSysCfgSet *)cfg); } typedef enum SysCfgAlignType_e { SYS_CFG_ALIGN_8, SYS_CFG_ALIGN_16, SYS_CFG_ALIGN_32, SYS_CFG_ALIGN_64, SYS_CFG_ALIGN_128, SYS_CFG_ALIGN_256, SYS_CFG_ALIGN_256_ODD, SYS_CFG_ALIGN_128_ODD_PLUS_64, SYS_CFG_ALIGN_LEN_DEFAULT, SYS_CFG_ALIGN_LEN_420, SYS_CFG_ALIGN_LEN_422, SYS_CFG_ALIGN_LEN_444, SYS_CFG_ALIGN_LEN_422_AVC, SYS_CFG_ALIGN_LEN_420_AV1, SYS_CFG_ALIGN_LEN_422_AV1, SYS_CFG_ALIGN_BUTT, } SysCfgAlignType; static RK_U32 mpp_sys_cfg_align(SysCfgAlignType type, RK_U32 val) { switch (type) { case SYS_CFG_ALIGN_8: { return MPP_ALIGN(val, 8);}; case SYS_CFG_ALIGN_16: { return MPP_ALIGN(val, 16);}; case SYS_CFG_ALIGN_32: { return MPP_ALIGN(val, 32);}; case SYS_CFG_ALIGN_64: { return MPP_ALIGN(val, 64);}; case SYS_CFG_ALIGN_128: { return MPP_ALIGN(val, 128);}; case SYS_CFG_ALIGN_256: { return MPP_ALIGN(val, 256);}; case SYS_CFG_ALIGN_256_ODD: {return MPP_ALIGN(val, 256) | 256;}; case SYS_CFG_ALIGN_128_ODD_PLUS_64: { val = MPP_ALIGN(val, 64); if (((val - 64) % 256 == 128)) return val; else return ((MPP_ALIGN(val, 128) | 128) + 64); }; case SYS_CFG_ALIGN_LEN_DEFAULT: { return (9 * MPP_ALIGN(val, 16) / 5);}; case SYS_CFG_ALIGN_LEN_420: case SYS_CFG_ALIGN_LEN_422: { return (2 * MPP_ALIGN(val, 16));}; case SYS_CFG_ALIGN_LEN_444: { return (3 * MPP_ALIGN(val, 16));}; case SYS_CFG_ALIGN_LEN_422_AVC: { return ((5 * MPP_ALIGN(val, 16)) / 2);}; case SYS_CFG_ALIGN_LEN_420_AV1: { return (2 * MPP_ALIGN(val, 128));}; case SYS_CFG_ALIGN_LEN_422_AV1: { return ((5 * MPP_ALIGN(val, 64)) / 2);}; default: { mpp_err("Specifying the align type is necessary"); return MPP_NOK; }; } } /* Based on drm_gem_framebuffer_helper.c drm_gem_afbc_min_size() */ static RK_S32 get_afbc_min_size(RK_S32 width, RK_S32 height, RK_S32 bpp) { #define AFBC_HEADER_SIZE 16 #define AFBC_HDR_ALIGN 64 #define AFBC_SUPERBLOCK_PIXELS 256 #define AFBC_SUPERBLOCK_ALIGNMENT 128 RK_S32 n_blocks, hdr_alignment, size; /* AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 and !AFBC_FORMAT_MOD_TILED */ width = MPP_ALIGN(width, 16); height = MPP_ALIGN(height, 16); hdr_alignment = AFBC_HDR_ALIGN; n_blocks = (width * height) / AFBC_SUPERBLOCK_PIXELS; size = MPP_ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment); size += n_blocks * MPP_ALIGN(bpp * AFBC_SUPERBLOCK_PIXELS / 8, AFBC_SUPERBLOCK_ALIGNMENT); return size; } /* * in: fmt_fbc,type,width,h_stride * out: stride_w * * in: fmt_fbc,type,height,v_stride * out: stride_h * * in: fmt_fbc,type,fmt_codec,width,h_stride * out: h_stride_by_byte * * in: fmt_fbc,type,fmt_codec,width,height,h_stride,v_stride * out: buffer_size */ MPP_RET mpp_sys_dec_buf_chk_proc(MppSysDecBufChkCfg *cfg) { MppCodingType type = cfg->type; MppFrameFormat fmt = (MppFrameFormat)(((RK_U32)cfg->fmt_codec & MPP_FRAME_FMT_MASK) | (cfg->fmt_fbc & MPP_FRAME_FBC_MASK) | (cfg->fmt_hdr & MPP_FRAME_HDR_MASK)); MppFrameFormat fmt_raw = cfg->fmt_codec; RK_U32 aligned_pixel = 0; RK_U32 aligned_pixel_byte = 0; RK_U32 aligned_byte = 0; RK_U32 aligned_height = 0; RK_U32 size_total = 0; RK_U32 size_total_old = 0; RK_U32 depth = MPP_FRAME_FMT_IS_YUV_10BIT(fmt) ? 10 : 8; if (type == MPP_VIDEO_CodingUnused) { mpp_err("The coding type is invalid"); return MPP_NOK; } /* use codec stride */ if (cfg->h_stride_by_byte) aligned_pixel = cfg->h_stride_by_byte * 8 / depth; if (cfg->v_stride) aligned_height = cfg->v_stride; sys_cfg_dbg_dec_buf("org pixel wxh: [%d %d]\n", cfg->width, cfg->height); sys_cfg_dbg_dec_buf("outside stride wxh: [%d %d]\n", cfg->h_stride_by_byte, cfg->v_stride); if (MPP_FRAME_FMT_IS_FBC(fmt)) { /* fbc case */ switch (type) { case MPP_VIDEO_CodingHEVC : case MPP_VIDEO_CodingAV1 : { aligned_pixel = MPP_ALIGN(cfg->width, 64); aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16); } break; case MPP_VIDEO_CodingAVC : case MPP_VIDEO_CodingAVSPLUS : case MPP_VIDEO_CodingAVS : case MPP_VIDEO_CodingAVS2 : { aligned_pixel = MPP_ALIGN(cfg->width, 64); aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16); } break; case MPP_VIDEO_CodingVP9 : { aligned_pixel = MPP_ALIGN(cfg->width, 64); aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 64); } break; default : { aligned_pixel = MPP_ALIGN(cfg->width, 16); aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16); } break; } sys_cfg_dbg_dec_buf("spec aligned pixel wxh: [%d %d]\n", aligned_pixel, aligned_height); /*fbc stride default 64 align*/ if (*compat_ext_fbc_hdr_256_odd) aligned_pixel_byte = (MPP_ALIGN(aligned_pixel, 256) | 256) * depth >> 3; else aligned_pixel_byte = MPP_ALIGN(aligned_pixel, 64) * depth >> 3; sys_cfg_dbg_dec_buf("need 256 odd align: %d\n", *compat_ext_fbc_hdr_256_odd); switch (type) { case MPP_VIDEO_CodingAVC : case MPP_VIDEO_CodingAVSPLUS : case MPP_VIDEO_CodingAVS : case MPP_VIDEO_CodingAVS2 : { aligned_byte = MPP_ALIGN(aligned_pixel_byte, 64); } break; case MPP_VIDEO_CodingHEVC : { aligned_byte = MPP_ALIGN(aligned_pixel_byte, 64); } break; case MPP_VIDEO_CodingVP9 : { aligned_byte = MPP_ALIGN(aligned_pixel_byte, 64); } break; case MPP_VIDEO_CodingAV1 : { aligned_byte = MPP_ALIGN(aligned_pixel_byte, 16); } break; default : { aligned_byte = MPP_ALIGN(aligned_pixel_byte, 16); } break; } sys_cfg_dbg_dec_buf("dec hw aligned hor_byte: [%d]\n", aligned_byte); cfg->h_stride_by_byte = aligned_byte; cfg->h_stride_by_pixel = aligned_pixel; cfg->v_stride = aligned_height; switch ((fmt_raw & MPP_FRAME_FMT_MASK)) { case MPP_FMT_YUV420SP_10BIT : { size_total = get_afbc_min_size(aligned_pixel, aligned_height, 15); } break; case MPP_FMT_YUV422SP_10BIT : { size_total = get_afbc_min_size(aligned_pixel, aligned_height, 20); } break; case MPP_FMT_YUV420SP : { size_total = get_afbc_min_size(aligned_pixel, aligned_height, 12); } break; case MPP_FMT_YUV422SP : { size_total = get_afbc_min_size(aligned_pixel, aligned_height, 16); } break; case MPP_FMT_YUV444SP : { size_total = get_afbc_min_size(aligned_pixel, aligned_height, 24); } break; case MPP_FMT_YUV444SP_10BIT : { size_total = get_afbc_min_size(aligned_pixel, aligned_height, 30); } break; default : { size_total = aligned_byte * aligned_height * 3 / 2; mpp_err("dec out fmt 0x%x is no support", fmt_raw & MPP_FRAME_FMT_MASK); } break; } sys_cfg_dbg_dec_buf("res aligned_pixel %d\n", aligned_pixel); sys_cfg_dbg_dec_buf("res aligned_byte %d\n", aligned_byte); sys_cfg_dbg_dec_buf("res aligned_height %d\n", aligned_height); sys_cfg_dbg_dec_buf("res GPU aligned size_total: [%d]\n", size_total); cfg->size_total = size_total; } else { /* tile case */ /* raster case */ RockchipSocType soc_type = mpp_get_soc_type(); aligned_pixel = cfg->width; switch (type) { case MPP_VIDEO_CodingHEVC : { aligned_pixel = MPP_ALIGN(cfg->width, 64); aligned_height = MPP_ALIGN(cfg->height, 8); } break; /* * avc aligned to ctu * p_Vid->width = p_Vid->PicWidthInMbs * 16 * p_Vid->height = p_Vid->FrameHeightInMbs * 16 */ case MPP_VIDEO_CodingAVC : { aligned_pixel = MPP_ALIGN(cfg->width, 16); aligned_height = MPP_ALIGN(cfg->height, 16); } break; case MPP_VIDEO_CodingVP9 : { if (soc_type == ROCKCHIP_SOC_RK3399) aligned_height = MPP_ALIGN(cfg->height, 64); else if (soc_type == ROCKCHIP_SOC_RK3588) aligned_height = MPP_ALIGN(cfg->height, 16); else aligned_height = MPP_ALIGN(cfg->height, 8); } break; case MPP_VIDEO_CodingAV1 : { aligned_height = MPP_ALIGN(cfg->height, 8); } break; case MPP_VIDEO_CodingVP8 : case MPP_VIDEO_CodingH263 : case MPP_VIDEO_CodingMPEG2 : case MPP_VIDEO_CodingMPEG4 : { aligned_height = MPP_ALIGN(cfg->height, 16); } break; case MPP_VIDEO_CodingAVS2 : { aligned_pixel = MPP_ALIGN(cfg->width, 64); aligned_height = MPP_ALIGN(cfg->height, 8); } break; default : { aligned_height = MPP_ALIGN(cfg->height, 8); } break; } sys_cfg_dbg_dec_buf("spec aligned pixel wxh: [%d %d]\n", aligned_pixel, aligned_height); aligned_pixel_byte = cfg->h_stride_by_byte ? cfg->h_stride_by_byte : aligned_pixel * depth / 8; aligned_height = cfg->v_stride ? cfg->v_stride : aligned_height; switch (type) { case MPP_VIDEO_CodingHEVC : { aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_64, aligned_pixel_byte); } break; case MPP_VIDEO_CodingVP9 : { if (soc_type == ROCKCHIP_SOC_RK3576) aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_128_ODD_PLUS_64, aligned_pixel_byte); else aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_256_ODD, aligned_pixel_byte); } break; case MPP_VIDEO_CodingAV1 : { if (soc_type == ROCKCHIP_SOC_RK3588) aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_16, aligned_pixel_byte); else aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_128, aligned_pixel_byte); } break; default : { aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_16, aligned_pixel_byte); } break; } sys_cfg_dbg_dec_buf("dec hw aligned hor_byte: [%d %d]\n", aligned_byte); /* * NOTE: rk3576 use 128 odd plus 64 for all non jpeg format * all the other socs use 256 odd on larger than 1080p */ if ((aligned_byte > 1920 || soc_type == ROCKCHIP_SOC_RK3576) && type != MPP_VIDEO_CodingMJPEG) { rk_s32 update = 0; switch (soc_type) { case ROCKCHIP_SOC_RK3399 : case ROCKCHIP_SOC_RK3568 : case ROCKCHIP_SOC_RK3562 : case ROCKCHIP_SOC_RK3528 : case ROCKCHIP_SOC_RK3588 : { aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_256_ODD, aligned_byte); update = 1; } break; case ROCKCHIP_SOC_RK3576 : { aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_128_ODD_PLUS_64, aligned_byte); update = 1; } break; default : { } break; } /* * recalc aligned_pixel here * NOTE: no RGB format here in fact */ if (update) { switch (fmt & MPP_FRAME_FMT_MASK) { case MPP_FMT_YUV420SP_10BIT: case MPP_FMT_YUV422SP_10BIT: case MPP_FMT_YUV444SP_10BIT: { aligned_pixel = aligned_byte * 8 / 10; } break; case MPP_FMT_YUV422_YVYU: case MPP_FMT_YUV422_YUYV: case MPP_FMT_RGB565: case MPP_FMT_BGR565: { aligned_pixel = aligned_byte / 2; } break; case MPP_FMT_RGB888: case MPP_FMT_BGR888: { aligned_pixel = aligned_byte / 3; } break; default : { aligned_pixel = aligned_byte; } break; } } } sys_cfg_dbg_dec_buf("dec hw performance aligned hor_byte: [%d]\n", aligned_pixel); cfg->h_stride_by_byte = aligned_byte; cfg->h_stride_by_pixel = aligned_pixel; cfg->v_stride = aligned_height; size_total = aligned_byte * aligned_height; size_total_old = size_total; sys_cfg_dbg_dec_buf("fmt_raw %x\n", fmt_raw); sys_cfg_dbg_dec_buf("res aligned_pixel %d\n", aligned_pixel); sys_cfg_dbg_dec_buf("res aligned_byte %d\n", aligned_byte); sys_cfg_dbg_dec_buf("res aligned_height %d\n", aligned_height); switch (fmt_raw) { case MPP_FMT_YUV420SP : case MPP_FMT_YUV420SP_10BIT : case MPP_FMT_YUV420P : case MPP_FMT_YUV420SP_VU : { SysCfgAlignType align_type = SYS_CFG_ALIGN_LEN_DEFAULT; /* hevc and vp9 - SYS_CFG_ALIGN_LEN_DEFAULT */ if (type == MPP_VIDEO_CodingAV1) align_type = SYS_CFG_ALIGN_LEN_420_AV1; else if (type == MPP_VIDEO_CodingAVC) align_type = SYS_CFG_ALIGN_LEN_420; size_total = mpp_sys_cfg_align(align_type, size_total); } break; case MPP_FMT_YUV422SP : case MPP_FMT_YUV422SP_10BIT : case MPP_FMT_YUV422P : case MPP_FMT_YUV422SP_VU : case MPP_FMT_YUV422_YUYV : case MPP_FMT_YUV422_YVYU : case MPP_FMT_YUV422_UYVY : case MPP_FMT_YUV422_VYUY : case MPP_FMT_YUV440SP : case MPP_FMT_YUV411SP : { SysCfgAlignType align_type; if (type == MPP_VIDEO_CodingAVC) align_type = SYS_CFG_ALIGN_LEN_422_AVC; else if (type == MPP_VIDEO_CodingAV1) align_type = SYS_CFG_ALIGN_LEN_422_AV1; else align_type = SYS_CFG_ALIGN_LEN_422; size_total = mpp_sys_cfg_align(align_type, size_total); } break; case MPP_FMT_YUV400 : { /* do nothing */ } break; case MPP_FMT_YUV444SP : case MPP_FMT_YUV444P : case MPP_FMT_YUV444SP_10BIT : { size_total = mpp_sys_cfg_align(SYS_CFG_ALIGN_LEN_444, size_total); } break; default : { size_total = size_total * 3 / 2; } } sys_cfg_dbg_dec_buf("res size total %d -> %d\n", size_total_old, size_total); cfg->size_total = size_total; } return MPP_OK; } MPP_RET mpp_sys_cfg_ioctl(MppSysCfg cfg) { MppSysCfgSet *p = (MppSysCfgSet *)cfg; if (!cfg) { mpp_err_f("invalid NULL input config\n"); return MPP_ERR_NULL_PTR; } if (p->dec_buf_chk.enable) { mpp_sys_dec_buf_chk_proc(&p->dec_buf_chk); p->dec_buf_chk.enable = 0; } return MPP_OK; } #define MPP_CFG_SET_ACCESS(func_name, in_type, cfg_type) \ MPP_RET func_name(MppSysCfg cfg, const char *name, in_type val) \ { \ MppSysCfgSrv *srv = get_srv_sys_cfg_f(); \ MppSysCfgSet *p; \ MppTrieInfo *node; \ MppCfgInfo *info; \ if (!srv) \ return MPP_NOK; \ if (!cfg || !name) { \ mpp_err_f("invalid input cfg %p name %p\n", cfg, name); \ return MPP_ERR_NULL_PTR; \ } \ p = (MppSysCfgSet *)cfg; \ node = mpp_trie_get_info(srv->trie, name); \ info = (MppCfgInfo *)mpp_trie_info_ctx(node); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ if (!info->flag_offset) { \ mpp_log_f("can not set readonly cfg %s\n", mpp_trie_info_name(node)); \ return MPP_NOK; \ } \ sys_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), \ strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_SET_##cfg_type(info, p, val); \ return ret; \ } MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_s32, RK_S32, s32); MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_u32, RK_U32, u32); MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_s64, RK_S64, s64); MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_u64, RK_U64, u64); MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_ptr, void *, ptr); MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_st, void *, st); #define MPP_CFG_GET_ACCESS(func_name, in_type, cfg_type) \ MPP_RET func_name(MppSysCfg cfg, const char *name, in_type *val) \ { \ MppSysCfgSrv *srv = get_srv_sys_cfg_f(); \ MppSysCfgSet *p; \ MppTrieInfo *node; \ MppCfgInfo *info; \ if (!srv) \ return MPP_NOK; \ if (!cfg || !name) { \ mpp_err_f("invalid input cfg %p name %p\n", cfg, name); \ return MPP_ERR_NULL_PTR; \ } \ p = (MppSysCfgSet *)cfg; \ node = mpp_trie_get_info(srv->trie, name); \ info = (MppCfgInfo *)mpp_trie_info_ctx(node); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ sys_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), \ strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_GET_##cfg_type(info, p, val); \ return ret; \ } MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_s32, RK_S32, s32); MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_u32, RK_U32, u32); MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_s64, RK_S64, s64); MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_u64, RK_U64, u64); MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_ptr, void *, ptr); MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_st, void , st); void mpp_sys_cfg_show(void) { MppSysCfgSrv *srv = get_srv_sys_cfg_f(); MppTrieInfo *root; MppTrie trie; if (!srv) return ; trie = srv->trie; root = mpp_trie_get_info_first(trie); mpp_log("dumping valid configure string start\n"); if (root) { MppTrieInfo *node = root; rk_s32 len = mpp_trie_get_name_max(trie); do { if (mpp_trie_info_is_self(node)) continue; if (node->ctx_len == sizeof(MppCfgInfo)) { MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node); mpp_log("%-*s type %s - %d:%d\n", len, mpp_trie_info_name(node), strof_cfg_type(info->data_type), info->data_offset, info->data_size); } else { mpp_log("%-*s size - %d\n", len, mpp_trie_info_name(node), node->ctx_len); } } while ((node = mpp_trie_get_info_next(trie, node))); } mpp_log("dumping valid configure string done\n"); mpp_log("sys cfg size %d count %d with trie node %d size %d\n", sizeof(MppSysCfgSet), mpp_trie_get_info_count(trie), mpp_trie_get_node_count(trie), mpp_trie_get_buf_size(trie)); }