decoder: CF1 Prealloc Mechanism based on single decoder instance. [2/2]
PD#SWPL-188670
Problem:
Prealloc Mechanism based on single decoder instance.
Solution:
Add prealloc function for decoder
depends on CL:
486559
Verify:
T6d
Change-Id: I9f7c61a6da9e519d02760a25fea924b2b08afdb4
Signed-off-by: lele xiang <lele.xiang@amlogic.com>
diff --git a/drivers/amvdec_ports/aml_buf_mgr.c b/drivers/amvdec_ports/aml_buf_mgr.c
index ce4e91a..41a7649 100644
--- a/drivers/amvdec_ports/aml_buf_mgr.c
+++ b/drivers/amvdec_ports/aml_buf_mgr.c
@@ -213,6 +213,9 @@
/* init bmmu box */
bmmu_flag |= (CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER);
+ if (bm->config.enable_secure)
+ bmmu_flag |= CODEC_MM_FLAGS_FOR_TRY_PREALLOC;
+
*bmmu = decoder_bmmu_box_alloc_box(bm->bc.name,
bm->bc.id,
BUF_FBC_NUM_MAX,
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index c231733..1483382 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -118,6 +118,7 @@
#define PAGE_NUM_ONE_MB (256)
//#define USEC_PER_SEC 1000000
+#define PREALLOC_YUV_BUF_NUM 10
#define INVALID_IDX -1
#define DEMUX_ES_MAGIC_NUM 0x5a5a5a5a
@@ -838,6 +839,17 @@
aml_buf_put_dma(&ctx->bm);
+ if (config.enable_fbc && config.enable_secure) {
+ int align_2n = decoder_bmmu_box_get_align_2n(ctx->bm.bmmu);
+ int memflags = decoder_bmmu_box_get_memflags(ctx->bm.bmmu);
+
+ /* get header and page size */
+ if (!vdec_if_get_param(ctx, GET_PARAM_COMP_BUF_INFO, &ctx->comp_info)) {
+ submit_prealloc_job(PREALLOC_AVBC_HEADER_TYPE, CTX_BUF_TOTAL(ctx),
+ ctx->comp_info.header_size, align_2n, memflags);
+ }
+ }
+
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
"Update picture buffer count: dec:%u, vpp:%u, ge2d:%u, margin:%u, total:%u\n",
ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
@@ -3415,6 +3427,48 @@
}
}
+int cal_yuv_size(struct aml_vcodec_ctx *ctx, u32 dw)
+{
+ int yuv_size = 0;
+ int max_width = 1920;
+ int max_height = 1088;
+ int y_size, uv_size;
+
+ /* currently only support 2k */
+ if (hevc_is_support_4k())
+ return 0;
+
+ /* currently only for android */
+ if (multiplanar)
+ return 0;
+
+ if ((ctx->output_pix_fmt != V4L2_PIX_FMT_HEVC) &&
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_VP9) &&
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_AV1))
+ return 0;
+
+ if (dw == 2 || dw == 3) {
+ y_size = ALIGN(max_width >> 2, 64) * ALIGN(max_height >> 2, 64);
+ uv_size = y_size >> 1;
+ } else if (dw == 0x200) {
+ y_size = ALIGN(max_width, 64) * ALIGN(max_height, 64);
+ uv_size = y_size >> 1;
+ } else if (dw == 0x400) {
+ max_width = 1024;
+ max_height = 576;
+ y_size = ALIGN(max_width, 64) * ALIGN(max_height, 64);
+ uv_size = y_size >> 1;
+ } else {
+ y_size = 0;
+ uv_size = 0;
+ }
+
+ yuv_size = y_size + uv_size;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, "dw is %d yuv_size %d\n", dw, yuv_size);
+
+ return yuv_size;
+}
+
static int vidioc_vdec_s_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
@@ -3513,6 +3567,13 @@
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_IDLE) {
+ if (ctx->is_drm_mode) {
+ struct aml_dec_params *dec = &ctx->config.parm.dec;
+ submit_prealloc_job(PREALLOC_YUV_TYPE, PREALLOC_YUV_BUF_NUM,
+ cal_yuv_size(ctx, dec->cfg.double_write_mode),
+ PAGE_SHIFT, CODEC_MM_FLAGS_TVP);
+ }
+
ret = vdec_if_init(ctx, q_data->fmt->fourcc);
if (ret) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -3553,6 +3614,12 @@
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_IDLE) {
+ if (ctx->is_drm_mode) {
+ struct aml_dec_params *dec = &ctx->config.parm.dec;
+ submit_prealloc_job(PREALLOC_YUV_TYPE, PREALLOC_YUV_BUF_NUM,
+ cal_yuv_size(ctx, dec->cfg.double_write_mode),
+ PAGE_SHIFT, CODEC_MM_FLAGS_TVP);
+ }
ret = vdec_if_init(ctx, q_data->fmt->fourcc);
if (ret) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -4661,6 +4728,17 @@
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"early box init fail!, ret:%d\n", ret);
}
+
+ if (config.enable_secure) {
+ int align_2n = decoder_bmmu_box_get_align_2n(ctx->bm.bmmu);
+ int memflags = decoder_bmmu_box_get_memflags(ctx->bm.bmmu);
+
+ /* get header and page size */
+ if (!vdec_if_get_param(ctx, GET_PARAM_COMP_BUF_INFO, &ctx->comp_info)) {
+ submit_prealloc_job(PREALLOC_AVBC_HEADER_TYPE, CTX_BUF_TOTAL(ctx),
+ ctx->comp_info.header_size, align_2n, memflags);
+ }
+ }
}
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
index d552f6f..9c5bbd9 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
@@ -246,6 +246,7 @@
aml_v4l_vpp_release_early(ctx);
kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
mutex_unlock(&dev->dev_mutex);
+ release_prealloc_job();
return 0;
}
diff --git a/drivers/amvdec_ports/aml_vcodec_util.h b/drivers/amvdec_ports/aml_vcodec_util.h
index b5829ff..d55a732 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.h
+++ b/drivers/amvdec_ports/aml_vcodec_util.h
@@ -32,6 +32,7 @@
#include "aml_buf_core.h"
#include "aml_task_chain.h"
#include "../common/media_utils/media_utils.h"
+#include <linux/amlogic/media/codec_mm/codec_mm_prealloc.h>
/*
typedef unsigned long long u64;
diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c
index c4479b4..cd17471 100644
--- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c
+++ b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c
@@ -376,6 +376,28 @@
}
EXPORT_SYMBOL(decoder_bmmu_try_to_release_box);
+int decoder_bmmu_box_get_align_2n(void *box_handle)
+{
+ struct decoder_bmmu_box *box = box_handle;
+
+ if (!box)
+ return 0;
+
+ return box->align2n;
+}
+EXPORT_SYMBOL(decoder_bmmu_box_get_align_2n);
+
+int decoder_bmmu_box_get_memflags(void *box_handle)
+{
+ struct decoder_bmmu_box *box = box_handle;
+
+ if (!box)
+ return 0;
+
+ return box->mem_flags;
+}
+EXPORT_SYMBOL(decoder_bmmu_box_get_memflags);
+
void *decoder_bmmu_box_get_mem_handle(void *box_handle, int idx)
{
struct decoder_bmmu_box *box = box_handle;
diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h
index e262d47..0ef5ab7 100644
--- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h
+++ b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h
@@ -69,6 +69,8 @@
bool decoder_bmmu_box_valid_check(void *box);
void decoder_bmmu_try_to_release_box(void *handle);
+int decoder_bmmu_box_get_align_2n(void *box_handle);
+int decoder_bmmu_box_get_memflags(void *box_handle);
int decoder_bmmu_box_init(void);
void decoder_bmmu_box_exit(void);
diff --git a/drivers/frame_provider/decoder_v4l/h265/vh265.c b/drivers/frame_provider/decoder_v4l/h265/vh265.c
index da9f670..a289f38 100644
--- a/drivers/frame_provider/decoder_v4l/h265/vh265.c
+++ b/drivers/frame_provider/decoder_v4l/h265/vh265.c
@@ -3330,7 +3330,7 @@
static int init_mmu_buffers(struct hevc_state_s *hevc, bool bmmu_flag)
{
int tvp_flag = vdec_secure(hw_to_vdec(hevc)) ?
- CODEC_MM_FLAGS_TVP : 0;
+ (CODEC_MM_FLAGS_TVP | CODEC_MM_FLAGS_FOR_TRY_PREALLOC) : 0;
int buf_size = hevc_max_mmu_buf_size(hevc->max_pic_w,
hevc->max_pic_h);
@@ -11635,6 +11635,22 @@
}
}
+void h265_prealloc_mv_buf(struct hevc_state_s *hw, int count, int size)
+{
+ int align_2n = decoder_bmmu_box_get_align_2n(hw->bmmu_box);
+ int memflags = decoder_bmmu_box_get_memflags(hw->bmmu_box);
+
+ if (!vdec_secure(hw_to_vdec(hw)))
+ return;
+
+ if (size && count) {
+ submit_prealloc_job(PREALLOC_MV_TYPE, count, size, align_2n, memflags);
+ } else {
+ hevc_print(hw, H265_DEBUG_BUFMGR_MORE, "invalid para type for mv type size is %u count is %u\n",
+ size, count);
+ }
+}
+
static int v4l_res_change(struct hevc_state_s *hevc, union param_u *rpm_param)
{
struct aml_vcodec_ctx *ctx =
@@ -11658,18 +11674,6 @@
height,
hevc->interlace_flag);
- if (IS_8K_SIZE(hevc->pic_w, hevc->pic_h))
- new_size = MPRED_8K_MV_BUF_SIZE;
- else if (IS_4K_SIZE(hevc->pic_w, hevc->pic_h))
- new_size = MPRED_4K_MV_BUF_SIZE; /*0x120000*/
- else
- new_size = MPRED_MV_BUF_SIZE;
-
- if (new_size != hevc->mv_buf_size) {
- dealloc_mv_bufs(hevc);
- hevc->mv_buf_size = new_size;
- }
-
if (get_valid_double_write_mode(hevc) != 16) {
struct vdec_comp_buf_info info;
@@ -11683,6 +11687,19 @@
ctx->v4l_resolution_change = 1;
hevc->resolution_change = true;
+ if (IS_8K_SIZE(hevc->pic_w, hevc->pic_h))
+ new_size = MPRED_8K_MV_BUF_SIZE;
+ else if (IS_4K_SIZE(hevc->pic_w, hevc->pic_h))
+ new_size = MPRED_4K_MV_BUF_SIZE; /*0x120000*/
+ else
+ new_size = MPRED_MV_BUF_SIZE;
+
+ if (new_size != hevc->mv_buf_size) {
+ dealloc_mv_bufs(hevc);
+ h265_prealloc_mv_buf(hevc, ps.dpb_frames - 1, new_size);
+ hevc->mv_buf_size = new_size;
+ }
+
/*
* marks frame valid on the dpb is the output state,
* then via flush_output all frames can be flushed out.
@@ -12967,6 +12984,16 @@
vdec_v4l_set_comp_buf_info(ctx, &info);
}
vh265_get_ps_info(hevc, &hevc->param, &ps);
+ if (hevc->mv_buf_size == 0) {
+ int new_size;
+ if (IS_8K_SIZE(hevc->pic_w, hevc->pic_h))
+ new_size = MPRED_8K_MV_BUF_SIZE;
+ else if (IS_4K_SIZE(hevc->pic_w, hevc->pic_h))
+ new_size = MPRED_4K_MV_BUF_SIZE; /*0x120000*/
+ else
+ new_size = MPRED_MV_BUF_SIZE;
+ h265_prealloc_mv_buf(hevc, ps.dpb_frames - 1, new_size);
+ }
/*notice the v4l2 codec.*/
vdec_v4l_set_ps_infos(ctx, &ps);
ctx->decoder_status_info.frame_height = ps.visible_height;
diff --git a/drivers/frame_provider/decoder_v4l/vav1/vav1.c b/drivers/frame_provider/decoder_v4l/vav1/vav1.c
index d4809b4..b038f93 100644
--- a/drivers/frame_provider/decoder_v4l/vav1/vav1.c
+++ b/drivers/frame_provider/decoder_v4l/vav1/vav1.c
@@ -8939,6 +8939,21 @@
return 0;
}
+static inline void av1_prealloc_mv_buf(struct AV1HW_s *hw, int count, int size)
+{
+ int align_2n = decoder_bmmu_box_get_align_2n(hw->bmmu_box);
+ int memflags = decoder_bmmu_box_get_memflags(hw->bmmu_box);
+
+ if (!vdec_secure(hw_to_vdec(hw)))
+ return;
+
+ if (size && count)
+ submit_prealloc_job(PREALLOC_MV_TYPE, count, size, align_2n, memflags);
+ else
+ av1_print(hw, AV1_DEBUG_BUFMGR, "invalid para type for mv type size is %u count is %u\n",
+ size, count);
+}
+
static int v4l_res_change(struct AV1HW_s *hw)
{
struct aml_vcodec_ctx *ctx =
@@ -8950,6 +8965,7 @@
hw->res_ch_flag == 0) {
struct aml_vdec_ps_infos ps;
struct vdec_comp_buf_info comp;
+ int new_size;
if ((hw->frame_width != 0 &&
hw->frame_height != 0) &&
@@ -8999,10 +9015,14 @@
}
vav1_get_ps_info(hw, &ps);
vdec_v4l_set_ps_infos(ctx, &ps);
- /*
- if (init_mv_buf_list(hw) < 0)
- pr_err("%s: !!!!Error, reinit_mv_buf_list fail\n", __func__);
- */
+ new_size = cal_mv_buf_size(hw, hw->frame_width, hw->frame_height);
+
+ if (new_size != hw->mv_buf_size) {
+ dealloc_mv_bufs(hw);
+ av1_prealloc_mv_buf(hw, ps.dpb_frames - 1, new_size);
+ hw->mv_buf_size = new_size;
+ }
+
vdec_v4l_res_ch_event(ctx);
hw->v4l_params_parsed = false;
hw->res_ch_flag = 1;
@@ -9642,8 +9662,11 @@
vav1_get_comp_buf_info(hw, &comp);
vdec_v4l_set_comp_buf_info(ctx, &comp);
}
-
vav1_get_ps_info(hw, &ps);
+ if (hw->mv_buf_size == 0) {
+ int new_size = cal_mv_buf_size(hw, hw->frame_width, hw->frame_height);
+ av1_prealloc_mv_buf(hw, ps.dpb_frames - 1, new_size);
+ }
/*notice the v4l2 codec.*/
vdec_v4l_set_ps_infos(ctx, &ps);
ctx->decoder_status_info.frame_height = ps.visible_height;
@@ -10495,7 +10518,7 @@
static int amvdec_av1_mmu_init(struct AV1HW_s *hw)
{
int tvp_flag = vdec_secure(hw_to_vdec(hw)) ?
- CODEC_MM_FLAGS_TVP : 0;
+ (CODEC_MM_FLAGS_TVP | CODEC_MM_FLAGS_FOR_TRY_PREALLOC) : 0;
int buf_size = 48;
struct aml_vcodec_ctx *ctx = hw->v4l2_ctx;
diff --git a/drivers/frame_provider/decoder_v4l/vp9/vvp9.c b/drivers/frame_provider/decoder_v4l/vp9/vvp9.c
index d36aa2c..93e37ec 100644
--- a/drivers/frame_provider/decoder_v4l/vp9/vvp9.c
+++ b/drivers/frame_provider/decoder_v4l/vp9/vvp9.c
@@ -1278,6 +1278,7 @@
ulong rdma_mem_handle;
bool timeout;
int v4l_duration;
+ int mv_buf_size;
#ifdef MULTI_INSTANCE_SUPPORT
u32 vp9_segment_data[8];
#endif
@@ -1926,6 +1927,9 @@
__func__, pbi->init_pic_w, pbi->init_pic_h, count);
}
+ if (size != pbi->mv_buf_size)
+ pbi->mv_buf_size = size;
+
for (i = 0; i < count; i++) {
if (alloc_mv_buf(pbi, i, size) < 0) {
ret = -1;
@@ -9206,6 +9210,21 @@
return ret;
}
+static inline void vp9_prealloc_mv_buf(struct VP9Decoder_s *hw, int count, int size)
+{
+ int align_2n = decoder_bmmu_box_get_align_2n(hw->bmmu_box);
+ int memflags = decoder_bmmu_box_get_memflags(hw->bmmu_box);
+
+ if (!vdec_secure(hw_to_vdec(hw)))
+ return;
+
+ if (size && count)
+ submit_prealloc_job(PREALLOC_MV_TYPE, count, size, align_2n, memflags);
+ else
+ vp9_print(hw, VP9_DEBUG_BUFMGR, "invalid para type for mv type size is %u count is %u\n",
+ size, count);
+}
+
static int v4l_res_change(struct VP9Decoder_s *pbi)
{
struct aml_vcodec_ctx *ctx =
@@ -9217,6 +9236,7 @@
struct aml_vdec_ps_infos ps;
struct vdec_comp_buf_info comp;
struct VP9_Common_s *cm = &pbi->common;
+ int new_size;
if ((pbi->last_width != 0 &&
pbi->last_height != 0) &&
@@ -9233,6 +9253,13 @@
vvp9_get_ps_info(pbi, &ps);
vdec_v4l_set_ps_infos(ctx, &ps);
+ new_size = cal_mv_buf_size(pbi, pbi->frame_width, pbi->frame_height);
+
+ if (new_size != pbi->mv_buf_size) {
+ dealloc_mv_bufs(pbi);
+ vp9_prealloc_mv_buf(pbi, 2, new_size);
+ pbi->mv_buf_size = new_size;
+ }
vdec_v4l_res_ch_event(ctx);
pbi->init_pic_w = pbi->frame_width;
@@ -9679,6 +9706,10 @@
ctx->dec_intf.decinfo_event_report(ctx, AML_DECINFO_EVENT_STATISTIC, NULL);
}
pbi->v4l_params_parsed = true;
+ if (pbi->mv_buf_size == 0) {
+ int new_size = cal_mv_buf_size(pbi, pbi->frame_width, pbi->frame_height);
+ vp9_prealloc_mv_buf(pbi, 2, new_size);
+ }
pbi->postproc_done = 0;
pbi->process_busy = 0;
ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
@@ -10412,7 +10443,7 @@
static int amvdec_vp9_mmu_init(struct VP9Decoder_s *pbi)
{
int tvp_flag = vdec_secure(hw_to_vdec(pbi)) ?
- CODEC_MM_FLAGS_TVP : 0;
+ (CODEC_MM_FLAGS_TVP | CODEC_MM_FLAGS_FOR_TRY_PREALLOC) : 0;
int buf_size = vp9_max_mmu_buf_size(pbi->max_pic_w, pbi->max_pic_h);
struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);