From 8ce07dbfba236e63a5199ac94dbf2cdba8b99368 Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Mon, 20 Jun 2022 16:34:59 +0800 Subject: [PATCH] [hal_vepu580]: Add slice segment info output Change-Id: I79a036b6ed5c75b587564a91f392ac81f305e505 Signed-off-by: Herman Chen Signed-off-by: sayon.chen --- inc/rk_venc_cmd.h | 11 ++++++++-- mpp/codec/mpp_enc_impl.cpp | 5 ++++- mpp/hal/rkenc/h264e/hal_h264e_vepu580.c | 29 +++++++++++++++++-------- mpp/hal/rkenc/h265e/hal_h265e_vepu580.c | 27 +++++++++++++++++------ 4 files changed, 53 insertions(+), 19 deletions(-) diff --git a/inc/rk_venc_cmd.h b/inc/rk_venc_cmd.h index cd99dd4a..53a85a50 100644 --- a/inc/rk_venc_cmd.h +++ b/inc/rk_venc_cmd.h @@ -1105,6 +1105,11 @@ typedef enum MppEncSplitMode_e { MPP_ENC_SPLIT_BY_CTU, } MppEncSplitMode; +typedef enum MppEncSplitOutMode_e { + MPP_ENC_SPLIT_OUT_LOWDELAY = (1 << 0), + MPP_ENC_SPLIT_OUT_SEGMENT = (1 << 1), +} MppEncSplitOutMode; + typedef struct MppEncSliceSplit_t { RK_U32 change; @@ -1130,8 +1135,10 @@ typedef struct MppEncSliceSplit_t { /* * slice split output mode * - * 0 - output all slice in one packet - * 1 - output each slice in a single packet + * MPP_ENC_SPLIT_OUT_LOWDELAY + * - When enabled encoder will lowdelay output each slice in a single packet + * MPP_ENC_SPLIT_OUT_SEGMENT + * - When enabled encoder will packet with segment info for each slice */ RK_U32 split_out; } MppEncSliceSplit; diff --git a/mpp/codec/mpp_enc_impl.cpp b/mpp/codec/mpp_enc_impl.cpp index 5e26a7e6..01e3e089 100644 --- a/mpp/codec/mpp_enc_impl.cpp +++ b/mpp/codec/mpp_enc_impl.cpp @@ -390,7 +390,7 @@ static void check_low_delay_output(MppEncImpl *enc) enc->low_delay_output = 0; - if (!cfg->split.split_mode || !cfg->split.split_out) + if (!cfg->split.split_mode || !(cfg->split.split_out & MPP_ENC_SPLIT_OUT_LOWDELAY)) return; if (cfg->rc.max_reenc_times) { @@ -492,6 +492,9 @@ MPP_RET mpp_enc_callback(const char *caller, void *ctx, RK_S32 cmd, void *param) mpp_meta_set_s32(impl->meta, KEY_OUTPUT_INTRA, frm->is_intra); } + mpp_packet_copy_segment_info(impl, packet); + mpp_packet_reset_segment(packet); + enc_dbg_detail("pkt %d new pos %p len %d\n", task->part_count, last_pos, slice_length); diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c index 6b0b945b..60e77946 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c @@ -22,6 +22,7 @@ #include "mpp_mem.h" #include "mpp_common.h" #include "mpp_frame_impl.h" +#include "mpp_packet_impl.h" #include "mpp_rc.h" #include "h264e_sps.h" @@ -2058,21 +2059,25 @@ static MPP_RET hal_h264e_vepu580_wait(void *hal, HalEncTask *task) MPP_RET ret = MPP_OK; HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal; HalVepu580RegSet *regs = &ctx->regs_sets[task->flags.reg_idx]; + RK_U32 split_out = ctx->cfg->split.split_out; + RK_S32 i; hal_h264e_dbg_func("enter %p\n", hal); - if (ctx->cfg->split.split_out) { + if (split_out) { EncOutParam param; RK_U32 slice_len; RK_U32 slice_last; + MppPacket pkt = task->packet; + RK_S32 offset = mpp_packet_get_length(pkt); + H264NaluType type = ctx->slice->slice_type == H264_I_SLICE ? + H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE; MppDevPollCfg *poll_cfg = (MppDevPollCfg *)((char *)ctx->poll_cfgs + task->flags.reg_idx * ctx->poll_cfg_size); param.task = task; param.base = mpp_packet_get_data(task->packet); do { - RK_S32 i; - poll_cfg->poll_type = 0; poll_cfg->poll_ret = 0; poll_cfg->count_max = ctx->poll_slice_max; @@ -2084,14 +2089,20 @@ static MPP_RET hal_h264e_vepu580_wait(void *hal, HalEncTask *task) slice_last = poll_cfg->slice_info[i].last; slice_len = poll_cfg->slice_info[i].length; - param.length = slice_len; + if (split_out & MPP_ENC_SPLIT_OUT_SEGMENT) { + mpp_packet_add_segment_info(pkt, type, offset, slice_len); + offset += slice_len; + } + if (split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) { + param.length = slice_len; - if (slice_last) - ctx->output_cb->cmd = ENC_OUTPUT_FINISH; - else - ctx->output_cb->cmd = ENC_OUTPUT_SLICE; + if (slice_last) + ctx->output_cb->cmd = ENC_OUTPUT_FINISH; + else + ctx->output_cb->cmd = ENC_OUTPUT_SLICE; - mpp_callback(ctx->output_cb, ¶m); + mpp_callback(ctx->output_cb, ¶m); + } } } while (!slice_last); } else { diff --git a/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c b/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c index 957caef5..5a9658f4 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c +++ b/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c @@ -25,6 +25,7 @@ #include "mpp_soc.h" #include "mpp_common.h" #include "mpp_frame_impl.h" +#include "mpp_packet_impl.h" #include "hal_h265e_debug.h" #include "h265e_syntax_new.h" @@ -2510,6 +2511,8 @@ MPP_RET hal_h265e_v580_wait(void *hal, HalEncTask *task) H265eV580HalContext *ctx = (H265eV580HalContext *)hal; HalEncTask *enc_task = task; H265eV580StatusElem *elem = (H265eV580StatusElem *)ctx->reg_out; + RK_U32 split_out = ctx->cfg->split.split_out; + hal_h265e_enter(); if (enc_task->flags.err) { @@ -2518,15 +2521,19 @@ MPP_RET hal_h265e_v580_wait(void *hal, HalEncTask *task) return MPP_NOK; } - if (ctx->cfg->split.split_out) { + if (split_out) { EncOutParam param; RK_U32 slice_len = 0; RK_U32 slice_last = 0; RK_U32 finish_cnt = 0; RK_U32 tile1_offset = 0; - RK_U32 stream_len = 0; - RK_U32 offset = mpp_packet_get_length(enc_task->packet); - void* ptr = mpp_packet_get_pos(enc_task->packet); + MppPacket pkt = enc_task->packet; + RK_U32 offset = mpp_packet_get_length(pkt); + RK_U32 seg_offset = offset; + void* ptr = mpp_packet_get_pos(pkt); + H265eV580RegSet *regs = (H265eV580RegSet *)ctx->regs[0]; + hevc_vepu580_base *reg_base = ®s->reg_base; + RK_U32 type = reg_base->reg0236_synt_nal.nal_unit_type; MppDevPollCfg *poll_cfg = (MppDevPollCfg *)((char *)ctx->poll_cfgs); param.task = task; @@ -2549,7 +2556,7 @@ MPP_RET hal_h265e_v580_wait(void *hal, HalEncTask *task) if (finish_cnt > 0) { void *tile1_ptr = mpp_buffer_get_ptr(ctx->hw_tile_stream); - memcpy(ptr + stream_len + offset, tile1_ptr + tile1_offset, slice_len); + memcpy(ptr + seg_offset, tile1_ptr + tile1_offset, slice_len); tile1_offset += slice_len; } @@ -2563,8 +2570,13 @@ MPP_RET hal_h265e_v580_wait(void *hal, HalEncTask *task) } } - stream_len += slice_len; - mpp_callback(ctx->output_cb, ¶m); + if (split_out & MPP_ENC_SPLIT_OUT_SEGMENT) + mpp_packet_add_segment_info(pkt, type, seg_offset, slice_len); + + if (split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) + mpp_callback(ctx->output_cb, ¶m); + + seg_offset += slice_len; } if (ctx->tile_parall_en) { @@ -2577,6 +2589,7 @@ MPP_RET hal_h265e_v580_wait(void *hal, HalEncTask *task) } while (1); } else { RK_U32 i = 0; + if (ctx->tile_parall_en) { for (i = 0; i < ctx->tile_num; i ++) ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);