From 70b572a2c0906e284fa5a376ca5cda3649a18b02 Mon Sep 17 00:00:00 2001 From: Hongjin Li Date: Thu, 9 Jan 2025 14:29:29 +0800 Subject: [PATCH] fix[mpp_sys_cfg]: Fix abnormal stride calculation. Platform: General Error case: If the specification specifies a stride, it should be configured according to the specification's stride rather than calculated based on width and height, especially in scenarios involving H.264 field-based sources. For the case of FBC, hor_stride needs to be processed based on pixels and is unrelated to bit depth. Reported-by: Johnson Ding Source: rk_32.h264 Signed-off-by: Hongjin Li Change-Id: I02058432f2baeeea4c5a87c6845b24de8a78b276 --- inc/mpp_sys_cfg.h | 2 + inc/mpp_sys_cfg_st.h | 11 +++-- mpp/base/mpp_buf_slot.cpp | 4 ++ mpp/base/mpp_sys_cfg.cpp | 69 ++++++++++++++++---------------- mpp/base/mpp_sys_cfg_st.cpp | 5 +++ mpp/base/test/mpp_sys_cfg_test.c | 2 + 6 files changed, 55 insertions(+), 38 deletions(-) diff --git a/inc/mpp_sys_cfg.h b/inc/mpp_sys_cfg.h index 049cfc8f..c373039a 100644 --- a/inc/mpp_sys_cfg.h +++ b/inc/mpp_sys_cfg.h @@ -23,6 +23,8 @@ typedef enum MppSysDecBufCkhCfgChange_e { MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_RIGHT = (1 << 10), MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FLAG_METADATA = (1 << 11), MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FLAG_THUMBNAIL = (1 << 12), + MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_H_STRIDE_BYTE = (1 << 13), + MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_V_STRIDE = (1 << 14), MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_ALL = (0xFFFFFFFF), } MppSysDecBufCkhChange; diff --git a/inc/mpp_sys_cfg_st.h b/inc/mpp_sys_cfg_st.h index 789636a6..d1928b21 100644 --- a/inc/mpp_sys_cfg_st.h +++ b/inc/mpp_sys_cfg_st.h @@ -16,6 +16,7 @@ typedef struct MppSysCfgStHStrd_t { MppCodingType type; RK_U32 fmt_fbc; RK_U32 width; + RK_U32 h_stride_by_byte; /* output args start */ RK_U32 h_stride_by_pixel; @@ -28,7 +29,7 @@ typedef struct MppSysCfgStHByteStrd_t { RK_U32 fmt_fbc; RK_U32 width; - /* output args start */ + /* in/output args start */ RK_U32 h_stride_by_byte; } MppSysCfgStHByteStrd; @@ -38,7 +39,7 @@ typedef struct MppSysCfgStVStrd_t { RK_U32 fmt_fbc; RK_U32 height; - /* output args start */ + /* in/output args start */ RK_U32 v_stride; } MppSysCfgStVStrd; @@ -50,10 +51,12 @@ typedef struct MppSysCfgStSize_t { RK_U32 width; RK_U32 height; - /* output args start */ - RK_U32 h_stride_by_pixel; + /* in/output args start */ RK_U32 h_stride_by_byte; RK_U32 v_stride; + + /* output args start */ + RK_U32 h_stride_by_pixel; RK_U32 size_total; RK_U32 size_fbc_hdr; RK_U32 size_fbc_bdy; diff --git a/mpp/base/mpp_buf_slot.cpp b/mpp/base/mpp_buf_slot.cpp index f381642f..0f52f718 100644 --- a/mpp/base/mpp_buf_slot.cpp +++ b/mpp/base/mpp_buf_slot.cpp @@ -391,6 +391,8 @@ static void prepare_info_set_by_sys_cfg(MppBufSlotsImpl *impl, MppFrame frame, { const RK_U32 width = mpp_frame_get_width(frame); const RK_U32 height = mpp_frame_get_height(frame); + const RK_U32 codec_hor_stride = mpp_frame_get_hor_stride(frame); + const RK_U32 codec_ver_stride = mpp_frame_get_ver_stride(frame); const MppFrameFormat fmt = mpp_frame_get_fmt(frame); MPP_RET ret = MPP_OK; MppSysCfg cfg; @@ -409,6 +411,8 @@ static void prepare_info_set_by_sys_cfg(MppBufSlotsImpl *impl, MppFrame frame, ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:fmt_hdr", fmt & MPP_FRAME_HDR_MASK); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:width", width); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:height", height); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:h_stride_by_byte", codec_hor_stride); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:v_stride", codec_ver_stride); /* get result */ mpp_sys_cfg_ioctl(cfg); diff --git a/mpp/base/mpp_sys_cfg.cpp b/mpp/base/mpp_sys_cfg.cpp index bbbdcedc..639f1b93 100644 --- a/mpp/base/mpp_sys_cfg.cpp +++ b/mpp/base/mpp_sys_cfg.cpp @@ -22,6 +22,7 @@ #include "mpp_sys_cfg.h" #include "mpp_soc.h" #include "mpp_mem_pool.h" +#include "mpp_compat_impl.h" #define MPP_SYS_CFG_DBG_FUNC (0x00000001) #define MPP_SYS_CFG_DBG_INFO (0x00000002) @@ -97,12 +98,12 @@ public: 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_byte, U32, RK_U32, 0, dec_buf_chk, h_stride_by_byte) \ ENTRY(dec_buf_chk, h_stride_by_pixel, U32, RK_U32, 0, dec_buf_chk, h_stride_by_pixel) \ - ENTRY(dec_buf_chk, v_stride, U32, RK_U32, 0, dec_buf_chk, v_stride) \ 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) \ @@ -261,16 +262,16 @@ static RK_S32 get_afbc_min_size(RK_S32 width, RK_S32 height, RK_S32 bpp) } /* - * in: fmt_fbc,type,width + * in: fmt_fbc,type,width,h_stride * out: stride_w * - * in: fmt_fbc,type,height + * in: fmt_fbc,type,height,v_stride * out: stride_h * - * in: fmt_fbc,type,fmt_codec,width + * in: fmt_fbc,type,fmt_codec,width,h_stride * out: h_stride_by_byte * - * in: fmt_fbc,type,fmt_codec,width,height + * 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) @@ -281,46 +282,54 @@ MPP_RET mpp_sys_dec_buf_chk_proc(MppSysDecBufChkCfg *cfg) (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 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; + if (MPP_FRAME_FMT_IS_FBC(fmt)) { /* fbc case */ - RK_U32 aligned_pixel; - RK_U32 aligned_pixel_byte; - RK_U32 aligned_byte; - RK_U32 aligned_height; - RK_U32 size_total; - switch (type) { case MPP_VIDEO_CodingHEVC : case MPP_VIDEO_CodingAV1 : { aligned_pixel = MPP_ALIGN(cfg->width, 64); - aligned_height = MPP_ALIGN(cfg->height, 8); + aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 8); } 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(cfg->height, 16); + 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(cfg->height, 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(cfg->height, 16); + aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16); } break; } - if (MPP_FRAME_FMT_IS_YUV_10BIT(fmt)) - aligned_pixel_byte = aligned_pixel * 10 / 8; + /*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 = aligned_pixel; + aligned_pixel_byte = MPP_ALIGN(aligned_pixel, 64) * depth >> 3; switch (type) { case MPP_VIDEO_CodingAVC : @@ -373,33 +382,25 @@ MPP_RET mpp_sys_dec_buf_chk_proc(MppSysDecBufChkCfg *cfg) } else { /* tile case */ /* raster case */ - RK_U32 aligned_pixel; - RK_U32 aligned_pixel_byte; - RK_U32 aligned_byte; - RK_U32 aligned_height; - RK_U32 size_total; RockchipSocType soc_type = mpp_get_soc_type(); switch (type) { case MPP_VIDEO_CodingHEVC : case MPP_VIDEO_CodingVP9 : { - aligned_pixel = MPP_ALIGN(cfg->width, 64); - aligned_height = MPP_ALIGN(cfg->height, 64); + aligned_pixel = MPP_ALIGN(aligned_pixel ? aligned_pixel : cfg->width, 64); + aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 64); } break; case MPP_VIDEO_CodingAV1 : { - aligned_pixel = MPP_ALIGN(cfg->width, 128); - aligned_height = MPP_ALIGN(cfg->height, 128); + aligned_pixel = MPP_ALIGN(aligned_pixel ? aligned_pixel : cfg->width, 128); + aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 128); } break; default : { - aligned_pixel = MPP_ALIGN(cfg->width, 16); - aligned_height = MPP_ALIGN(cfg->height, 16); + aligned_pixel = MPP_ALIGN(aligned_pixel ? aligned_pixel : cfg->width, 16); + aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16); } break; } - if (MPP_FRAME_FMT_IS_YUV_10BIT(fmt)) - aligned_pixel_byte = aligned_pixel * 10 / 8; - else - aligned_pixel_byte = aligned_pixel; + aligned_pixel_byte = aligned_pixel * depth / 8; switch (type) { case MPP_VIDEO_CodingHEVC : { diff --git a/mpp/base/mpp_sys_cfg_st.cpp b/mpp/base/mpp_sys_cfg_st.cpp index eec838d1..1a73818f 100644 --- a/mpp/base/mpp_sys_cfg_st.cpp +++ b/mpp/base/mpp_sys_cfg_st.cpp @@ -30,6 +30,7 @@ MPP_RET mpp_sys_cfg_st_get_h_stride(MppSysCfgStHStrd *h_stride_cfg) ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:type", h_stride_cfg->type); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:fmt_fbc", h_stride_cfg->fmt_fbc); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:width", h_stride_cfg->width); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:h_stride_by_byte", h_stride_cfg->h_stride_by_byte); /* get result */ mpp_sys_cfg_ioctl(cfg); @@ -65,6 +66,7 @@ MPP_RET mpp_sys_cfg_st_get_byte_stride(MppSysCfgStHByteStrd *byte_stride_cfg) ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:fmt_codec", byte_stride_cfg->fmt_codec); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:fmt_fbc", byte_stride_cfg->fmt_fbc); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:width", byte_stride_cfg->width); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:h_stride_by_byte", byte_stride_cfg->h_stride_by_byte); /* get result */ mpp_sys_cfg_ioctl(cfg); @@ -99,6 +101,7 @@ MPP_RET mpp_sys_cfg_st_get_v_stride(MppSysCfgStVStrd *v_stride_cfg) ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:type", v_stride_cfg->type); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:fmt_fbc", v_stride_cfg->fmt_fbc); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:height", v_stride_cfg->height); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:v_stride", v_stride_cfg->v_stride); /* get result */ mpp_sys_cfg_ioctl(cfg); @@ -134,6 +137,8 @@ MPP_RET mpp_sys_cfg_st_get_size(MppSysCfgStSize *size_cfg) ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:fmt_fbc", size_cfg->fmt_fbc); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:width", size_cfg->width); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:height", size_cfg->height); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:h_stride_by_byte", size_cfg->h_stride_by_byte); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:v_stride", size_cfg->v_stride); /* get result */ mpp_sys_cfg_ioctl(cfg); diff --git a/mpp/base/test/mpp_sys_cfg_test.c b/mpp/base/test/mpp_sys_cfg_test.c index ae79133d..03b0bbfb 100644 --- a/mpp/base/test/mpp_sys_cfg_test.c +++ b/mpp/base/test/mpp_sys_cfg_test.c @@ -49,6 +49,8 @@ int main() ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:fmt_fbc", MPP_FRAME_FBC_AFBC_V1); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:width", width); ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:height", height); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:h_stride_by_byte", 0); + ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:h_stride_by_pixel", 0); /* try get readonly parameter */ ret = mpp_sys_cfg_set_u32(cfg, "dec_buf_chk:cap_fbc", 1);