[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250930040348.3702923-23-h.dewangan@samsung.com>
Date: Tue, 30 Sep 2025 09:33:41 +0530
From: Himanshu Dewangan <h.dewangan@...sung.com>
To: mchehab@...nel.org, robh@...nel.org, krzk+dt@...nel.org,
conor+dt@...nel.org, sumit.semwal@...aro.org, christian.koenig@....com,
alim.akhtar@...sung.com, manjun@...sung.com, nagaraju.s@...sung.com,
ih0206.lee@...sung.com, jehyung.lee@...sung.com
Cc: linux-arm-kernel@...ts.infradead.org, linux-media@...r.kernel.org,
devicetree@...r.kernel.org, linux-samsung-soc@...r.kernel.org,
linux-kernel@...r.kernel.org, dri-devel@...ts.freedesktop.org,
linaro-mm-sig@...ts.linaro.org, Himanshu Dewangan <h.dewangan@...sung.com>
Subject: [PATCH 22/29] media: mfc: Add H.264 encoder support with buffer and
QoS improvements
From: Nagaraju Siddineni <nagaraju.s@...sung.com>
- Integrat H.264 encoding.
- Allocate encoder‑specific context buffers and ROI memory.
- Add detection macro and broadened codec‑type validation for
QoS utilities.
- Introduce encoder‑aware QoS tables and refined weight calculations
(B‑frames, reference count).
- Update source‑queue cleanup, framerate fallback, and
timestamp‑delta handling.
- Make stride and source‑size helpers encoder‑aware; exposed B‑frame
detection utility.
- Expand context structures with encoder buffers, private fields,
ROI, and parameters.
- Add platform flags for encoder‑specific QoS steps and feature
support (e.g., RGB).
Signed-off-by: Nagaraju Siddineni <nagaraju.s@...sung.com>
Signed-off-by: Himanshu Dewangan <h.dewangan@...sung.com>
---
.../samsung/exynos-mfc/base/mfc_buf.c | 132 ++++++++++
.../samsung/exynos-mfc/base/mfc_buf.h | 3 +
.../samsung/exynos-mfc/base/mfc_common.h | 24 +-
.../samsung/exynos-mfc/base/mfc_data_struct.h | 231 ++++++++++++++++++
.../samsung/exynos-mfc/base/mfc_qos.c | 34 ++-
.../samsung/exynos-mfc/base/mfc_queue.c | 31 +++
.../samsung/exynos-mfc/base/mfc_queue.h | 2 +
.../exynos-mfc/base/mfc_rate_calculate.c | 30 ++-
.../exynos-mfc/base/mfc_rate_calculate.h | 8 +-
.../samsung/exynos-mfc/base/mfc_utils.c | 111 +++++++++
.../samsung/exynos-mfc/base/mfc_utils.h | 52 ++++
.../media/platform/samsung/exynos-mfc/mfc.c | 3 +
12 files changed, 654 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c b/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c
index 84f97ca230bb..0186fe3327f1 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c
@@ -132,6 +132,9 @@ int mfc_alloc_instance_context(struct mfc_core_ctx *core_ctx)
case MFC_REG_CODEC_FIMV4_DEC:
core_ctx->instance_ctx_buf.size = buf_size->other_dec_ctx;
break;
+ case MFC_REG_CODEC_H264_ENC:
+ core_ctx->instance_ctx_buf.size = buf_size->h264_enc_ctx;
+ break;
case MFC_REG_CODEC_AV1_DEC:
core_ctx->instance_ctx_buf.size = buf_size->av1_dec_ctx;
break;
@@ -248,6 +251,64 @@ static void __mfc_dec_calc_codec_buffer_size(struct mfc_core_ctx *core_ctx)
NUM_MPEG4_LF_BUF);
}
+static void __mfc_enc_calc_codec_buffer_size(struct mfc_core_ctx *core_ctx)
+{
+ struct mfc_ctx *ctx = core_ctx->ctx;
+ struct mfc_enc *enc;
+ unsigned int mb_width, mb_height;
+
+ enc = ctx->enc_priv;
+ enc->tmv_buffer_size = 0;
+
+ mb_width = WIDTH_MB(ctx->crop_width);
+ mb_height = HEIGHT_MB(ctx->crop_height);
+
+ /* default recon buffer size, it can be changed in case of 422, 10bit */
+ enc->luma_dpb_size =
+ ALIGN(ENC_LUMA_DPB_SIZE(ctx->crop_width, ctx->crop_height), SZ_64);
+ enc->chroma_dpb_size =
+ ALIGN(ENC_CHROMA_DPB_SIZE(ctx->crop_width, ctx->crop_height), SZ_64);
+
+ if (ctx->min_dpb_size[0] > enc->luma_dpb_size ||
+ ctx->min_dpb_size[1] > enc->chroma_dpb_size) {
+ mfc_debug(2,
+ "[MEMINFO] recon DPB size changed (Luma: %zu -> %d, Chroma %zu -> %d)\n",
+ enc->luma_dpb_size,
+ ctx->min_dpb_size[0],
+ enc->chroma_dpb_size,
+ ctx->min_dpb_size[1]);
+ enc->luma_dpb_size = ctx->min_dpb_size[0];
+ enc->chroma_dpb_size = ctx->min_dpb_size[1];
+ }
+
+ /* Codecs have different memory requirements */
+ switch (ctx->codec_mode) {
+ case MFC_REG_CODEC_H264_ENC:
+ enc->me_buffer_size =
+ ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), SZ_256);
+
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, SZ_256);
+ core_ctx->codec_buf.size =
+ ctx->scratch_buf_size + enc->tmv_buffer_size +
+ (ctx->dpb_count * (enc->luma_dpb_size +
+ enc->chroma_dpb_size + enc->me_buffer_size));
+ break;
+ default:
+ core_ctx->codec_buf.size = 0;
+ mfc_err("invalid codec type: %d\n", ctx->codec_mode);
+ break;
+ }
+
+ mfc_debug(2,
+ "[MEMINFO] scratch: %zu, TMV: %zu, (recon luma: %zu, chroma: %zu, me: %zu) x count %d\n",
+ ctx->scratch_buf_size,
+ enc->tmv_buffer_size,
+ enc->luma_dpb_size,
+ enc->chroma_dpb_size,
+ enc->me_buffer_size,
+ ctx->dpb_count);
+}
+
/* Allocate codec buffers */
int mfc_alloc_codec_buffers(struct mfc_core_ctx *core_ctx)
{
@@ -259,6 +320,8 @@ int mfc_alloc_codec_buffers(struct mfc_core_ctx *core_ctx)
if (ctx->type == MFCINST_DECODER) {
__mfc_dec_calc_codec_buffer_size(core_ctx);
+ } else if (ctx->type == MFCINST_ENCODER) {
+ __mfc_enc_calc_codec_buffer_size(core_ctx);
} else {
mfc_err("invalid type: %d\n", ctx->type);
return -EINVAL;
@@ -401,6 +464,75 @@ void mfc_release_dbg_info_buffer(struct mfc_core *core)
mfc_mem_special_buf_free(core->dev, &core->dbg_info_buf);
}
+/* Allocation buffer of ROI macroblock information */
+static int __mfc_alloc_enc_roi_buffer(struct mfc_core_ctx *core_ctx,
+ size_t size,
+ struct mfc_special_buf *roi_buf)
+{
+ struct mfc_core *core = core_ctx->core;
+ struct mfc_dev *dev = core->dev;
+
+ roi_buf->size = size;
+ roi_buf->buftype = MFCBUF_NORMAL;
+
+ if (!roi_buf->dma_buf) {
+ snprintf(roi_buf->name, MFC_NUM_SPECIAL_BUF_NAME, "ctx%d ROI", core_ctx->num);
+ if (mfc_mem_special_buf_alloc(dev, roi_buf)) {
+ mfc_err("[ROI] Allocating ROI buffer failed\n");
+ return -ENOMEM;
+ }
+ }
+ memset(roi_buf->vaddr, 0, roi_buf->size);
+
+ return 0;
+}
+
+/* Wrapper : allocation ROI buffers */
+int mfc_alloc_enc_roi_buffer(struct mfc_core_ctx *core_ctx)
+{
+ struct mfc_ctx *ctx = core_ctx->ctx;
+ struct mfc_enc *enc = ctx->enc_priv;
+ unsigned int mb_width, mb_height;
+ size_t size;
+ int i;
+
+ mb_width = WIDTH_MB(ctx->crop_width);
+ mb_height = HEIGHT_MB(ctx->crop_height);
+
+ switch (ctx->codec_mode) {
+ case MFC_REG_CODEC_H264_ENC:
+ size = ((((mb_width * (mb_height + 1) / 2) + 15) / 16) * 16) * 2;
+ break;
+ default:
+ mfc_debug(2,
+ "ROI not supported codec type(%d). Allocate with default size\n",
+ ctx->codec_mode);
+ size = mb_width * mb_height;
+ break;
+ }
+
+ for (i = 0; i < MFC_MAX_EXTRA_BUF; i++) {
+ if (__mfc_alloc_enc_roi_buffer(core_ctx, size, &enc->roi_buf[i]) < 0) {
+ mfc_err("[ROI] Allocating remapping buffer[%d] failed\n", i);
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+/* Release buffer of ROI macroblock information */
+void mfc_release_enc_roi_buffer(struct mfc_core_ctx *core_ctx)
+{
+ struct mfc_ctx *ctx = core_ctx->ctx;
+ struct mfc_enc *enc = ctx->enc_priv;
+ int i;
+
+ for (i = 0; i < MFC_MAX_EXTRA_BUF; i++)
+ if (enc->roi_buf[i].dma_buf)
+ mfc_mem_special_buf_free(ctx->dev, &enc->roi_buf[i]);
+}
+
/* Allocate firmware */
int mfc_alloc_firmware(struct mfc_core *core)
{
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.h b/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.h
index 6907cf6ac775..67bdfaed5dd6 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.h
@@ -26,6 +26,9 @@ void mfc_release_codec_buffers(struct mfc_core_ctx *core_ctx);
int mfc_alloc_scratch_buffer(struct mfc_core_ctx *core_ctx);
void mfc_release_scratch_buffer(struct mfc_core_ctx *core_ctx);
+int mfc_alloc_enc_roi_buffer(struct mfc_core_ctx *core_ctx);
+void mfc_release_enc_roi_buffer(struct mfc_core_ctx *core_ctx);
+
int mfc_alloc_firmware(struct mfc_core *core);
int mfc_load_firmware(struct mfc_core *core,
struct mfc_special_buf *fw_buf,
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h b/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h
index 5392c8566e42..bec6f88d5e44 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h
@@ -170,6 +170,9 @@
((ctx)->codec_mode == MFC_REG_CODEC_HEVC_DEC && \
(profile) == MFC_REG_D_PROFILE_MULTIVIEW_HEVC_MAIN)
+/* Encoder codec mode check */
+#define IS_H264_ENC(ctx) ((ctx)->codec_mode == MFC_REG_CODEC_H264_ENC)
+
#define CODEC_NOT_CODED(ctx) ({ \
typeof(ctx) _ctx = (ctx); \
(IS_MPEG4_DEC(_ctx) || IS_VC1_DEC(_ctx) || IS_VC1_RCV_DEC(_ctx) || \
@@ -217,7 +220,16 @@
})
#define CODEC_HAS_IDR(ctx) ({ \
typeof(ctx) _ctx = (ctx); \
- (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx) || IS_HEVC_DEC(_ctx)); \
+ (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx) || IS_HEVC_DEC(_ctx) || \
+ IS_H264_ENC(_ctx)); \
+})
+
+// Buffer container
+#define IS_BUFFER_BATCH_MODE(ctx) ((ctx)->batch_mode == 1)
+#define IS_NO_HEADER_GENERATE(ctx, p) ({ \
+ typeof(ctx) _ctx = (ctx); \
+ typeof(p) _p = (p); \
+ (_p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME); \
})
/*
@@ -313,6 +325,13 @@
(_fps >= 240)); \
})
+#define IS_MULTI_MODE_ENC_RES(ctx) ({ \
+ typeof(ctx) _ctx = (ctx); \
+ (IS_MULTI_MODE_RES(_ctx) || \
+ (OVER_UHD_RES(_ctx) && _ctx->operating_framerate >= 60000) || \
+ (OVER_UHD_RES(_ctx) && mfc_is_enc_bframe(_ctx))); \
+})
+
#define IS_BLACKBAR_OFF(ctx) ((ctx)->crop_height > 2160)
#define IS_SINGLE_FD(ctx, fmt) ((!(ctx)->rgb_bpp) && ((fmt)->mem_planes == 1))
@@ -404,6 +423,9 @@ static inline int mfc_core_get_pwr_ref_cnt(struct mfc_core *core)
static inline int mfc_core_get_clk_ref_cnt(struct mfc_core *core)
{
+ if (core->dev->pdata->support_hwacg == MFC_HWACG_HWFW_CTRL)
+ return 1;
+
return atomic_read(&core->clk_ref);
}
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h b/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h
index 6b93fe3ab138..6d34905a1cba 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h
@@ -505,6 +505,9 @@ struct mfc_ctx_buf_size {
size_t h264_dec_ctx;
size_t av1_dec_ctx;
size_t other_dec_ctx;
+ size_t h264_enc_ctx;
+ size_t hevc_enc_ctx;
+ size_t other_enc_ctx;
size_t dbg_info_buf;
};
@@ -711,6 +714,13 @@ struct mfc_bw_data {
};
struct mfc_bw_info {
+ struct mfc_bw_data bw_enc_h264;
+ struct mfc_bw_data bw_enc_hevc;
+ struct mfc_bw_data bw_enc_hevc_10bit;
+ struct mfc_bw_data bw_enc_vp8;
+ struct mfc_bw_data bw_enc_vp9;
+ struct mfc_bw_data bw_enc_vp9_10bit;
+ struct mfc_bw_data bw_enc_mpeg4;
struct mfc_bw_data bw_dec_h264;
struct mfc_bw_data bw_dec_hevc;
struct mfc_bw_data bw_dec_hevc_10bit;
@@ -734,6 +744,7 @@ struct mfc_qos {
unsigned int freq_mif;
unsigned int mo_value;
unsigned int mo_10bit_value;
+ unsigned int mo_uhd_enc60_value;
unsigned int time_fw;
unsigned int bts_scen_idx;
const char *name;
@@ -792,6 +803,7 @@ struct mfc_platdata {
/* Formats */
unsigned int support_10bit;
unsigned int support_422;
+ unsigned int support_rgb;
/* Resolution */
unsigned int support_check_res;
@@ -807,11 +819,26 @@ struct mfc_platdata {
struct mfc_feature black_bar;
struct mfc_feature color_aspect_dec;
struct mfc_feature static_info_dec;
+ struct mfc_feature color_aspect_enc;
+ struct mfc_feature static_info_enc;
struct mfc_feature vp9_stride_align;
struct mfc_feature mem_clear;
struct mfc_feature wait_fw_status;
+ struct mfc_feature average_qp;
+ struct mfc_feature mv_search_mode;
+ struct mfc_feature enc_idr_flag;
+ struct mfc_feature min_quality_mode;
+ struct mfc_feature enc_capability;
+ struct mfc_feature enc_ts_delta;
+ struct mfc_feature wfd_rc_mode;
+ struct mfc_feature max_i_frame_size;
struct mfc_feature hevc_pic_output_flag;
+ /* Encoder default parameter */
+ unsigned int enc_param_num;
+ unsigned int enc_param_addr[MFC_MAX_DEFAULT_PARAM];
+ unsigned int enc_param_val[MFC_MAX_DEFAULT_PARAM];
+
struct mfc_bw_info mfc_bw_info;
unsigned int dynamic_weight;
struct mfc_qos_weight qos_weight;
@@ -835,7 +862,14 @@ struct mfc_platdata {
unsigned int scheduler;
unsigned int pbs_num_prio;
+
+ unsigned int enc_rgb_csc_by_fw;
+ /* HWAPG */
+ unsigned int support_hwapg;
+ /* HWACG */
enum mfc_hwacg_type support_hwacg;
+
+ unsigned int support_enc_mode1;
unsigned int support_mv_hevc;
};
@@ -858,6 +892,7 @@ struct mfc_core_platdata {
unsigned int tsmux_masterid;
/* QoS */
unsigned int num_default_qos_steps;
+ unsigned int num_encoder_qos_steps;
unsigned int max_mb;
unsigned int max_hw_mb;
unsigned int mfc_freq_control;
@@ -994,6 +1029,9 @@ struct mfc_core_ops {
/* for DEC */
void (*instance_dpb_flush)(struct mfc_core *core, struct mfc_ctx *ctx);
int (*instance_init_buf)(struct mfc_core *core, struct mfc_ctx *ctx);
+ /* for ENC */
+ void (*instance_q_flush)(struct mfc_core *core, struct mfc_ctx *ctx);
+ void (*instance_finishing)(struct mfc_core *core, struct mfc_ctx *ctx);
};
struct dump_info {
@@ -1148,6 +1186,150 @@ struct mfc_core {
struct mfc_core_memlog memlog;
};
+/**
+ *
+ */
+struct mfc_h264_enc_params {
+ enum v4l2_mpeg_video_h264_profile profile;
+ u8 level;
+ u8 interlace;
+ u16 open_gop_size;
+ u8 open_gop;
+ u8 _8x8_transform;
+ s8 loop_filter_alpha;
+ s8 loop_filter_beta;
+ enum v4l2_mpeg_video_h264_loop_filter_mode loop_filter_mode;
+ enum v4l2_mpeg_video_h264_entropy_mode entropy_mode;
+ u8 rc_frame_qp;
+ u8 rc_min_qp;
+ u8 rc_max_qp;
+ u8 rc_min_qp_p;
+ u8 rc_max_qp_p;
+ u8 rc_min_qp_b;
+ u8 rc_max_qp_b;
+ u8 rc_mb_dark;
+ u8 rc_mb_smooth;
+ u8 rc_mb_static;
+ u8 rc_mb_activity;
+ u8 rc_p_frame_qp;
+ u8 rc_b_frame_qp;
+ u8 ar_vui;
+ u8 sei_gen_enable;
+ u8 sei_fp_curr_frame_0;
+
+ enum v4l2_mpeg_video_h264_vui_sar_idc ar_vui_idc;
+ u16 ext_sar_width;
+ u16 ext_sar_height;
+
+ enum v4l2_mpeg_video_h264_hierarchical_coding_type hier_qp_type;
+ u32 hier_bit_layer[7];
+ u8 hier_qp_layer[7];
+ u8 hier_qp_enable;
+ u8 num_hier_layer;
+ u8 hier_ref_type;
+ u8 enable_ltr;
+ u8 num_of_ltr;
+ u32 set_priority;
+ u32 base_priority;
+
+ enum v4l2_mpeg_video_h264_sei_fp_arrangement_type sei_fp_arrangement_type;
+ u32 fmo_enable;
+ u32 fmo_slice_map_type;
+ u32 fmo_slice_num_grp;
+ u32 fmo_run_length[4];
+ u32 fmo_sg_dir;
+ u32 fmo_sg_rate;
+ u32 aso_enable;
+ u32 aso_slice_order[8];
+
+ u32 prepend_sps_pps_to_idr;
+ u32 vui_enable;
+};
+
+/**
+ *
+ */
+struct mfc_enc_params {
+ enum v4l2_mpeg_video_multi_slice_mode slice_mode;
+ u32 slice_mb;
+ u32 slice_bit;
+ u32 slice_mb_row;
+
+ u32 gop_ctrl;
+ u32 gop_size;
+ u32 intra_refresh_mb;
+ u32 i_frm_ctrl_mode;
+ u32 i_frm_ctrl;
+
+ u8 pad;
+ u8 pad_luma;
+ u8 pad_cb;
+ u8 pad_cr;
+
+ u8 rc_mb; /* H.264: MFCv5, MPEG4/H.263: MFCv6 */
+ u8 rc_pvc;
+ u8 rc_frame;
+ u8 drop_control;
+ u32 rc_bitrate;
+ u32 rc_framerate;
+ u16 rc_reaction_coeff;
+ u16 rc_frame_delta; /* MFC6.1 Only */
+ u32 rc_framerate_res;
+ u32 max_i_frame_size; /* when RC_MODE is 5(CBR_I_LIMIT_WFD = CBR_BS) */
+
+ u32 config_qp;
+ u32 dynamic_qp;
+
+ u8 frame_tag;
+ u8 ratio_intra;
+ u8 num_b_frame; /* H.264, HEVC, MPEG4 */
+ u8 num_refs_for_p; /* H.264, HEVC, VP8, VP9 */
+ enum v4l2_mpeg_video_header_mode seq_hdr_mode;
+ enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
+ u16 vbv_buf_size;
+ u8 num_hier_max_layer;
+ u8 hier_bitrate_ctrl;
+ u8 weighted_enable;
+ u8 roi_enable;
+ u8 ivf_header_disable; /* VP8, VP9 */
+ u8 fixed_target_bit;
+ u8 min_quality_mode; /* H.264, HEVC when RC_MODE is 2(VBR) */
+ u8 wp_two_pass_enable;
+ u8 adaptive_gop_enable;
+
+ u32 check_color_range;
+ u32 color_range;
+ u32 colour_primaries;
+ u32 transfer_characteristics;
+ u32 matrix_coefficients;
+
+ u32 static_info_enable;
+ u32 max_pic_average_light;
+ u32 max_content_light;
+ u32 max_display_luminance;
+ u32 min_display_luminance;
+ u32 white_point;
+ u32 display_primaries_0;
+ u32 display_primaries_1;
+ u32 display_primaries_2;
+ u32 chroma_qp_offset_cb; /* H.264, HEVC */
+ u32 chroma_qp_offset_cr; /* H.264, HEVC */
+
+ u32 mv_search_mode;
+ u32 mv_hor_pos_l0;
+ u32 mv_hor_pos_l1;
+ u32 mv_ver_pos_l0;
+ u32 mv_ver_pos_l1;
+ u32 mv_hor_range;
+ u32 mv_ver_range;
+
+ u8 timing_info_enable; /* H.264, HEVC */
+
+ union {
+ struct mfc_h264_enc_params h264;
+ } codec;
+};
+
struct mfc_ctx_ctrl_val {
int has_new;
int val;
@@ -1234,6 +1416,14 @@ struct temporal_layer_info {
unsigned int temporal_layer_bitrate[VIDEO_MAX_TEMPORAL_LAYERS];
};
+struct mfc_enc_roi_info {
+ char *addr;
+ int size;
+ int upper_qp;
+ int lower_qp;
+ bool enable;
+};
+
struct mfc_user_shared_handle {
int fd;
struct dma_buf *dma_buf;
@@ -1379,6 +1569,43 @@ struct mfc_dec {
unsigned char frame_cnt;
};
+struct mfc_enc {
+ unsigned int dst_buf_size;
+ unsigned int header_size;
+
+ enum v4l2_mpeg_mfc51_video_frame_type frame_type;
+ enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type;
+
+ unsigned int idr_flag;
+
+ size_t luma_dpb_size;
+ size_t chroma_dpb_size;
+ size_t me_buffer_size;
+ size_t tmv_buffer_size;
+
+ unsigned int slice_mode;
+ unsigned int slice_size_mb;
+ unsigned int slice_size_bits;
+ unsigned int in_slice;
+ unsigned int buf_full;
+
+ int config_qp;
+
+ struct mfc_fmt *uncomp_fmt;
+
+ int fake_src;
+ int empty_data;
+
+ int roi_index;
+ struct mfc_special_buf roi_buf[MFC_MAX_EXTRA_BUF];
+ struct mfc_enc_roi_info roi_info[MFC_MAX_EXTRA_BUF];
+
+ struct mfc_enc_params params;
+
+ struct mfc_user_shared_handle sh_handle_svc;
+ struct mfc_user_shared_handle sh_handle_roi;
+};
+
struct mfc_resolution {
int width;
int height;
@@ -1414,6 +1641,7 @@ struct mfc_multi_view_buf_info {
struct mfc_ctx {
struct mfc_dev *dev;
struct mfc_dec *dec_priv;
+ struct mfc_enc *enc_priv;
int num;
int prio;
@@ -1542,6 +1770,9 @@ struct mfc_ctx {
dma_addr_t last_src_addr;
dma_addr_t last_dst_addr[MFC_MAX_PLANES];
+ /* buffer container */
+ int batch_mode;
+
bool mem_type_10bit;
unsigned long gdc_ready_buf_ino;
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c b/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c
index 9922c2396b94..40541e2d626f 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c
@@ -20,17 +20,25 @@
static inline int __mfc_core_get_qos_steps(struct mfc_core *core, int table_type)
{
- return core->core_pdata->num_default_qos_steps;
+ if (table_type == MFC_QOS_TABLE_TYPE_ENCODER)
+ return core->core_pdata->num_encoder_qos_steps;
+ else
+ return core->core_pdata->num_default_qos_steps;
}
static inline struct mfc_qos *__mfc_core_get_qos_table(struct mfc_core *core, int table_type)
{
- return core->core_pdata->default_qos_table;
+ if (table_type == MFC_QOS_TABLE_TYPE_ENCODER)
+ return core->core_pdata->encoder_qos_table;
+ else
+ return core->core_pdata->default_qos_table;
}
static inline unsigned long __mfc_qos_add_weight(struct mfc_ctx *ctx, unsigned long mb)
{
+ struct mfc_enc *enc = ctx->enc_priv;
struct mfc_dec *dec = ctx->dec_priv;
+ struct mfc_enc_params *p;
struct mfc_qos_weight *qos_weight = &ctx->dev->pdata->qos_weight;
u32 num_planes = ctx->dst_fmt->num_planes;
int weight = 1000;
@@ -39,6 +47,8 @@ static inline unsigned long __mfc_qos_add_weight(struct mfc_ctx *ctx, unsigned l
switch (ctx->codec_mode) {
case MFC_REG_CODEC_H264_DEC:
case MFC_REG_CODEC_H264_MVC_DEC:
+ case MFC_REG_CODEC_H264_ENC:
+ case MFC_REG_CODEC_H264_MVC_ENC:
weight = (weight * 100) / qos_weight->weight_h264_hevc;
mfc_ctx_debug(3, "[QoS] h264, hevc codec, weight: %d\n", weight / 10);
if (num_planes == 3) {
@@ -107,6 +117,16 @@ static inline unsigned long __mfc_qos_add_weight(struct mfc_ctx *ctx, unsigned l
mfc_ctx_err("[QoS] wrong codec_mode (%d), no weight\n", ctx->codec_mode);
}
+ if (enc) {
+ p = &enc->params;
+ if (mfc_is_enc_bframe(ctx)) {
+ weight = (weight * 100) / qos_weight->weight_bframe;
+ mfc_ctx_debug(3, "[QoS] B frame encoding, weight: %d\n", weight / 10);
+ } else if (IS_H264_ENC(ctx) && (p->num_refs_for_p >= 2)) {
+ weight = (weight * 100) / qos_weight->weight_num_of_ref;
+ mfc_ctx_debug(3, "[QoS] num of ref >= 2, weight: %d\n", weight / 10);
+ }
+ }
if (dec) {
if (dec->num_of_tile_over_4) {
weight = (weight * 100) / qos_weight->weight_num_of_tile;
@@ -223,7 +243,10 @@ void mfc_qos_get_portion(struct mfc_core *core, struct mfc_ctx *ctx)
if (!ctx->mfc_qos_portion)
return;
- table_type = MFC_QOS_TABLE_TYPE_DEFAULT;
+ if (ctx->type == MFCINST_ENCODER)
+ table_type = MFC_QOS_TABLE_TYPE_ENCODER;
+ else
+ table_type = MFC_QOS_TABLE_TYPE_DEFAULT;
num_qos_steps = __mfc_core_get_qos_steps(core, table_type);
qos_table = __mfc_core_get_qos_table(core, table_type);
@@ -390,7 +413,8 @@ bool mfc_qos_mb_calculate(struct mfc_core *core, struct mfc_core_ctx *core_ctx,
if (ctx->type == MFCINST_DECODER)
table_type = MFC_QOS_TABLE_TYPE_DEFAULT;
-
+ else
+ table_type = MFC_QOS_TABLE_TYPE_ENCODER;
num_qos_steps = __mfc_core_get_qos_steps(core, table_type);
if (atomic_read(&core->qos_req_cur)) {
@@ -652,6 +676,8 @@ void __mfc_qos_calculate(struct mfc_core *core, struct mfc_ctx *ctx, int delete)
if (dec_found)
table_type = MFC_QOS_TABLE_TYPE_DEFAULT;
+ else
+ table_type = MFC_QOS_TABLE_TYPE_ENCODER;
num_qos_steps = __mfc_core_get_qos_steps(core, table_type);
qos_table = __mfc_core_get_qos_table(core, table_type);
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c b/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c
index 6dc9bc7a1873..81e649bb4e1e 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c
@@ -539,6 +539,37 @@ void mfc_cleanup_queue(spinlock_t *plock, struct mfc_buf_queue *queue)
spin_unlock_irqrestore(plock, flags);
}
+void mfc_cleanup_enc_src_queue(struct mfc_core_ctx *core_ctx)
+{
+ struct mfc_ctx *ctx = core_ctx->ctx;
+ unsigned long flags;
+ struct mfc_buf *mfc_buf = NULL;
+ struct mfc_buf_queue *queue = &core_ctx->src_buf_queue;
+ int i;
+
+ spin_lock_irqsave(&ctx->buf_queue_lock, flags);
+
+ while (!list_empty(&queue->head)) {
+ mfc_buf = list_entry(queue->head.next, struct mfc_buf, list);
+
+ for (i = 0; i < mfc_buf->vb.vb2_buf.num_planes; i++) {
+ if (IS_BUFFER_BATCH_MODE(ctx))
+ mfc_bufcon_put_daddr(ctx, mfc_buf, i);
+ vb2_set_plane_payload(&mfc_buf->vb.vb2_buf, i, 0);
+ }
+
+ vb2_buffer_done(&mfc_buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ list_del(&mfc_buf->list);
+ queue->count--;
+ }
+
+ INIT_LIST_HEAD(&queue->head);
+ queue->count = 0;
+ ctx->batch_mode = 0;
+
+ spin_unlock_irqrestore(&ctx->buf_queue_lock, flags);
+}
+
void mfc_print_dpb_queue(struct mfc_core_ctx *core_ctx, struct mfc_dec *dec)
{
struct mfc_ctx *ctx = core_ctx->ctx;
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.h b/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.h
index 055e7a23a527..cfe889e0dcc9 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.h
@@ -145,6 +145,8 @@ void mfc_return_buf_to_ready_queue(struct mfc_ctx *ctx,
void mfc_cleanup_queue(spinlock_t *plock, struct mfc_buf_queue *queue);
+void mfc_cleanup_enc_src_queue(struct mfc_core_ctx *core_ctx);
+
void mfc_print_dpb_queue(struct mfc_core_ctx *core_ctx, struct mfc_dec *dec);
void mfc_print_dpb_queue_with_lock(struct mfc_core_ctx *core_ctx, struct mfc_dec *dec);
int mfc_get_available_dpb_count(struct mfc_core_ctx *core_ctx);
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.c b/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.c
index 94a555c900d7..c88101d1d1c1 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.c
@@ -293,6 +293,7 @@ static unsigned long __mfc_rate_get_fps_by_timestamp(struct mfc_ctx *ctx,
struct mfc_ts_control *ts,
struct timespec64 *time, int type)
{
+ struct list_head *head = &ts->ts_list;
struct mfc_timestamp *temp_ts;
int found;
int index = 0;
@@ -304,6 +305,13 @@ static unsigned long __mfc_rate_get_fps_by_timestamp(struct mfc_ctx *ctx,
unsigned long flags;
u64 current_time;
+ if (IS_BUFFER_BATCH_MODE(ctx)) {
+ if (ctx->dev->debugfs.debug_ts == 1)
+ mfc_ctx_info("[BUFCON][TS] Keep framerate if buffer batch mode is used, %ldfps\n",
+ ctx->framerate);
+ return ctx->framerate;
+ }
+
spin_lock_irqsave(&ts->ts_lock, flags);
if (list_empty(&ts->ts_list)) {
__mfc_rate_add_timestamp(ctx, ts, time, &ts->ts_list);
@@ -362,6 +370,19 @@ static unsigned long __mfc_rate_get_fps_by_timestamp(struct mfc_ctx *ctx,
spin_unlock_irqrestore(&ts->ts_lock, flags);
}
+ /* Calculation the last frame fps for drop control */
+ if (ctx->type == MFCINST_ENCODER) {
+ temp_ts = list_entry(head->prev, struct mfc_timestamp, list);
+ if (temp_ts->interval > USEC_PER_SEC) {
+ if (ts->ts_is_full)
+ mfc_ctx_info("[TS] ts interval(%d) couldn't over 1sec(1fps)\n",
+ temp_ts->interval);
+ ts->ts_last_interval = 0;
+ } else {
+ ts->ts_last_interval = temp_ts->interval;
+ }
+ }
+
if (!ts->ts_is_full) {
if (ctx->dev->debugfs.debug_ts == 1)
mfc_ctx_info("[TS] ts doesn't full, keep %ld fps\n", ctx->framerate);
@@ -581,7 +602,14 @@ int mfc_rate_check_perf_ctx(struct mfc_ctx *ctx, int max_runtime)
op_fps = ctx->operating_framerate;
if (op_fps == 0) {
- op_fps = ctx->src_q_framerate;
+ if (ctx->type == MFCINST_ENCODER && ctx->enc_priv->params.rc_framerate)
+ op_fps = ctx->enc_priv->params.rc_framerate;
+ else
+ /*
+ * In case of non-real-time, check the buffer queueing rate
+ * because the non-real-time is best effort scenario. (ex. video editing)
+ */
+ op_fps = ctx->src_q_framerate;
mfc_ctx_debug(2, "[PRIO][rt %d] use fps: %d\n", ctx->rt, op_fps);
}
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.h b/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.h
index 2452e6ee56dd..530ad6fed489 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_rate_calculate.h
@@ -45,6 +45,8 @@ static inline void mfc_rate_reset_framerate(struct mfc_ctx *ctx)
{
if (ctx->type == MFCINST_DECODER)
ctx->framerate = DEC_DEFAULT_FPS;
+ else if (ctx->type == MFCINST_ENCODER)
+ ctx->framerate = ENC_DEFAULT_FPS;
mfc_ctx_debug(3, "[QoS] reset ctx->framrate: %lu\n", ctx->framerate);
}
@@ -80,7 +82,11 @@ static inline unsigned long mfc_rate_get_rt_framerate(struct mfc_ctx *ctx, enum
framerate = ctx->operating_framerate;
- if (rt == MFC_RT_UNDEFINED || rt == MFC_NON_RT) {
+ if (rt == MFC_RT) {
+ if (framerate == 0 && ctx->type == MFCINST_ENCODER &&
+ ctx->enc_priv->params.rc_framerate)
+ framerate = ctx->enc_priv->params.rc_framerate;
+ } else if (rt == MFC_RT_UNDEFINED || rt == MFC_NON_RT) {
framerate = ctx->framerate;
} else {
if (ctx->src_ts.ts_is_full)
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c b/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c
index 83cdae3dee57..6dba87fb951b 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c
@@ -108,6 +108,59 @@ static void __mfc_set_dec_stride(struct mfc_ctx *ctx,
}
}
+static void __mfc_set_enc_stride(struct mfc_ctx *ctx,
+ struct mfc_raw_info *raw,
+ struct mfc_fmt *fmt)
+{
+ int i, y_stride, stride_align = 16;
+
+ y_stride = ctx->bytesperline[0];
+ if (!y_stride)
+ y_stride = ALIGN(ctx->img_width, stride_align);
+
+ for (i = 0; i < MFC_MAX_PLANES; i++) {
+ raw->stride[i] = 0;
+ raw->stride_2bits[i] = 0;
+ }
+
+ switch (fmt->fourcc) {
+ case V4L2_PIX_FMT_YUV420M:
+ case V4L2_PIX_FMT_YVU420M:
+ case V4L2_PIX_FMT_NV12MT_16X16:
+ case V4L2_PIX_FMT_NV12MT:
+ case V4L2_PIX_FMT_NV12M:
+ case V4L2_PIX_FMT_NV21M:
+ case V4L2_PIX_FMT_NV16M:
+ case V4L2_PIX_FMT_NV61M:
+ /* use user stride */
+ for (i = 0; i < ctx->src_fmt->num_planes; i++) {
+ raw->stride[i] = ctx->bytesperline[i];
+ if (!raw->stride[i])
+ raw->stride[i] = ALIGN(ctx->img_width, stride_align);
+ }
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_RGB32X:
+ case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_ARGB32:
+ case V4L2_PIX_FMT_RGB32:
+ raw->stride[0] = y_stride * (ctx->rgb_bpp / 8);
+ break;
+ default:
+ mfc_ctx_err("Invalid pixelformat : %s\n", fmt->name);
+ break;
+ }
+
+ for (i = 0; i < ctx->src_fmt->num_planes; i++) {
+ if ((raw->stride[i] % stride_align) != 0) {
+ mfc_ctx_err("[FRAME] Forced to change stride[%d] %d for %dbyte alignment\n",
+ i, raw->stride[i], stride_align);
+ raw->stride[i] = ALIGN(raw->stride[i], stride_align);
+ }
+ }
+}
+
void mfc_set_linear_stride_size(struct mfc_ctx *ctx, struct mfc_raw_info *raw, struct mfc_fmt *fmt)
{
/*
@@ -117,6 +170,8 @@ void mfc_set_linear_stride_size(struct mfc_ctx *ctx, struct mfc_raw_info *raw, s
*/
if (ctx->type == MFCINST_DECODER)
__mfc_set_dec_stride(ctx, raw, fmt);
+ else
+ __mfc_set_enc_stride(ctx, raw, fmt);
}
void mfc_dec_calc_dpb_size(struct mfc_ctx *ctx, struct mfc_raw_info *raw, struct mfc_fmt *fmt)
@@ -201,6 +256,62 @@ void mfc_dec_calc_dpb_size(struct mfc_ctx *ctx, struct mfc_raw_info *raw, struct
}
}
+void mfc_enc_calc_src_size(struct mfc_ctx *ctx)
+{
+ struct mfc_raw_info *raw;
+ int i, extra;
+
+ raw = &ctx->raw_buf;
+ raw->total_plane_size = 0;
+ extra = MFC_LINEAR_BUF_SIZE;
+
+ mfc_set_linear_stride_size(ctx, raw, ctx->src_fmt);
+
+ for (i = 0; i < raw->num_planes; i++) {
+ raw->plane_size[i] = 0;
+ raw->plane_size_2bits[i] = 0;
+ }
+
+ switch (ctx->src_fmt->fourcc) {
+ case V4L2_PIX_FMT_YUV420M:
+ case V4L2_PIX_FMT_YVU420M:
+ raw->plane_size[0] = raw->stride[0] * ALIGN(ctx->img_height, 16) + extra;
+ raw->plane_size[1] = raw->stride[1] * ALIGN(ctx->img_height, 16) / 2 + extra;
+ raw->plane_size[2] = raw->stride[2] * ALIGN(ctx->img_height, 16) / 2 + extra;
+ break;
+ case V4L2_PIX_FMT_NV12MT_16X16:
+ case V4L2_PIX_FMT_NV12M:
+ case V4L2_PIX_FMT_NV21M:
+ raw->plane_size[0] = raw->stride[0] * ALIGN(ctx->img_height, 16) + extra;
+ raw->plane_size[1] = raw->stride[1] * ALIGN(ctx->img_height, 16) / 2 + extra;
+ break;
+ case V4L2_PIX_FMT_NV16M:
+ case V4L2_PIX_FMT_NV61M:
+ raw->plane_size[0] = raw->stride[0] * ALIGN(ctx->img_height, 16) + extra;
+ raw->plane_size[1] = raw->stride[1] * ALIGN(ctx->img_height, 16) + extra;
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_RGB32X:
+ case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_ARGB32:
+ case V4L2_PIX_FMT_RGB32:
+ raw->plane_size[0] = raw->stride[0] * ctx->img_height;
+ break;
+ default:
+ mfc_ctx_err("Invalid pixel format(%d)\n", ctx->src_fmt->fourcc);
+ break;
+ }
+
+ for (i = 0; i < raw->num_planes; i++) {
+ raw->total_plane_size += raw->plane_size[i];
+ mfc_ctx_debug(2, "[FRAME] Plane[%d] size = %d, stride = %d\n",
+ i, raw->plane_size[i], raw->stride[i]);
+ }
+
+ mfc_ctx_debug(2, "[FRAME] total plane size: %d\n", raw->total_plane_size);
+}
+
void mfc_calc_base_addr(struct mfc_ctx *ctx, struct vb2_buffer *vb,
struct mfc_fmt *fmt)
{
diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.h b/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.h
index dedfb049e6fc..a127f330fe16 100644
--- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.h
+++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.h
@@ -212,10 +212,37 @@ static inline int mfc_check_mb_flag(struct mfc_buf *mfc_buf, enum mfc_mb_flag f)
return 0;
}
+static inline int mfc_is_enc_bframe(struct mfc_ctx *ctx)
+{
+ struct mfc_enc *enc;
+ struct mfc_enc_params *p;
+ int hier_qp_type = -EINVAL;
+ u8 num_hier_layer = 0;
+
+ if (ctx->type != MFCINST_ENCODER)
+ return 0;
+ enc = ctx->enc_priv;
+ if (!enc)
+ return 0;
+
+ p = &enc->params;
+ if (IS_H264_ENC(ctx)) {
+ num_hier_layer = p->codec.h264.num_hier_layer;
+ hier_qp_type = (int)p->codec.h264.hier_qp_type;
+ }
+ if (enc->params.num_b_frame ||
+ (num_hier_layer >= 2 &&
+ hier_qp_type == V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B))
+ return 1;
+
+ return 0;
+}
+
int mfc_check_vb_with_fmt(struct mfc_fmt *fmt, struct vb2_buffer *vb);
int mfc_check_resolution(struct mfc_ctx *ctx);
void mfc_set_linear_stride_size(struct mfc_ctx *ctx, struct mfc_raw_info *raw, struct mfc_fmt *fmt);
void mfc_dec_calc_dpb_size(struct mfc_ctx *ctx, struct mfc_raw_info *raw, struct mfc_fmt *fmt);
+void mfc_enc_calc_src_size(struct mfc_ctx *ctx);
void mfc_calc_base_addr(struct mfc_ctx *ctx, struct vb2_buffer *vb, struct mfc_fmt *fmt);
void mfc_set_view_buf_info(struct mfc_ctx *ctx, int mem_planes,
int num_fd_depth_map, int num_fd_sub_view_meta);
@@ -355,6 +382,31 @@ static inline void mfc_ctx_change_idle_mode(struct mfc_ctx *ctx,
ctx->idle_mode = idle_mode;
}
+static inline int mfc_enc_get_ts_delta(struct mfc_ctx *ctx)
+{
+ struct mfc_enc *enc = ctx->enc_priv;
+ struct mfc_enc_params *p = &enc->params;
+ int ts_delta = 0;
+
+ if (!ctx->src_ts.ts_last_interval) {
+ ts_delta = p->rc_framerate_res / p->rc_framerate;
+ mfc_ctx_debug(3, "[DFR] default delta: %d\n", ts_delta);
+ } else {
+ /*
+ * FRAME_DELTA specifies the amount of
+ * increment of frame modulo base time.
+ * - delta unit = framerate resolution / fps
+ * - fps = 1000000(usec per sec) / timestamp interval
+ * For the sophistication of calculation, we will divide later.
+ * Excluding H.263, resolution is fixed to 10000,
+ * so thie is also divided into pre-calculated 100.
+ * (Preventing both overflow and calculation duplication)
+ */
+ ts_delta = ctx->src_ts.ts_last_interval / 100;
+ }
+ return ts_delta;
+}
+
static inline void mfc_print_ctx_info(struct mfc_ctx *ctx)
{
struct mfc_fmt *codec = NULL;
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc.c b/drivers/media/platform/samsung/exynos-mfc/mfc.c
index 293a353c49fa..db17448eae13 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc.c
@@ -1128,6 +1128,9 @@ struct mfc_ctx_buf_size mfc_ctx_buf_size = {
.h264_dec_ctx = PAGE_ALIGN(0x200000), /* 1.6MB */
.av1_dec_ctx = PAGE_ALIGN(0x19000), /* 100KB */
.other_dec_ctx = PAGE_ALIGN(0xF000), /* 60KB */
+ .h264_enc_ctx = PAGE_ALIGN(0x19000), /* 100KB */
+ .hevc_enc_ctx = PAGE_ALIGN(0xC800), /* 50KB */
+ .other_enc_ctx = PAGE_ALIGN(0xC800), /* 50KB */
.dbg_info_buf = PAGE_ALIGN(0x1000), /* 4KB for DEBUG INFO */
};
--
2.34.1
Powered by blists - more mailing lists