From 1dcfc5752d5acaa5f07c0ec51649c92d835bfc7a Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 6 Jun 2019 17:19:57 -0700 Subject: [PATCH] msm: vidc: decide batching while configuration driver returns min buffer count to client which includes extra buffers count which is required for batching even though batching may be disabled in start_streaming() later. So decide batching in set format (configuration) to avoid adding extra buffers count to reduce memory usage in non-batching cases. Change-Id: I147f7aaf928074a23c9dcda2dbf69a744cec382d Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vdec.c | 28 ++++++++------------ msm/vidc/msm_vidc.c | 21 ++++++++++++++- msm/vidc/msm_vidc_buffer_calculations.c | 33 ++++++++++++++++++++--- msm/vidc/msm_vidc_buffer_calculations.h | 4 ++- msm/vidc/msm_vidc_common.c | 35 +++++++++++++++++++++++-- msm/vidc/msm_vidc_common.h | 2 ++ 6 files changed, 99 insertions(+), 24 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 2819203d62898..34a1e235fc9be 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -652,6 +652,16 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); } + /* + * if batching enabled previously then you may chose + * to disable it based on recent configuration changes. + * if batching already disabled do not enable it again + * as sufficient extra buffers (required for batch mode + * on both ports) may not have been updated to client. + */ + if (inst->batch.enable) + inst->batch.enable = is_batching_allowed(inst); + err_invalid_fmt: return rc; } @@ -773,24 +783,8 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) inst->clk_data.frame_rate = (DEFAULT_FPS << 16); inst->clk_data.operating_rate = (DEFAULT_FPS << 16); if (core->resources.decode_batching) { - struct msm_vidc_inst *temp; - - inst->batch.size = MAX_DEC_BATCH_SIZE; inst->batch.enable = true; - - mutex_lock(&core->lock); - list_for_each_entry(temp, &core->instances, list) { - if (temp != inst && - temp->state != MSM_VIDC_CORE_INVALID && - is_decode_session(temp) && - !is_thumbnail_session(temp)) { - inst->batch.enable = false; - dprintk(VIDC_HIGH, - "Disable decode-batching in multi sessions\n"); - break; - } - } - mutex_unlock(&core->lock); + inst->batch.size = MAX_DEC_BATCH_SIZE; } inst->buff_req.buffer[1].buffer_type = HAL_BUFFER_INPUT; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 3fc9233a6db55..9264190be82eb 100755 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -19,6 +19,7 @@ #include "vidc_hfi_helper.h" #include "vidc_hfi_api.h" #include "msm_vidc_clocks.h" +#include "msm_vidc_buffer_calculations.h" #include #define MAX_EVENTS 30 @@ -913,7 +914,15 @@ static inline int start_streaming(struct msm_vidc_inst *inst) } } - inst->batch.enable = is_batching_allowed(inst); + /* + * if batching enabled previously then you may chose + * to disable it based on recent configuration changes. + * if batching already disabled do not enable it again + * as sufficient extra buffers (required for batch mode + * on both ports) may not have been updated to client. + */ + if (inst->batch.enable) + inst->batch.enable = is_batching_allowed(inst); dprintk(VIDC_HIGH, "%s: batching %s for inst %pK (%#x)\n", __func__, inst->batch.enable ? "enabled" : "disabled", inst, hash32_ptr(inst->session)); @@ -1433,12 +1442,22 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, inst->level); break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: + rc = msm_vidc_calculate_output_buffer_count(inst); + if (rc) { + dprintk(VIDC_ERR, "g_min: input failed\n", __func__); + break; + } ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_OUTPUT, ctrl->val); break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: + rc = msm_vidc_calculate_input_buffer_count(inst); + if (rc) { + dprintk(VIDC_ERR, "g_min: output failed\n", __func__); + break; + } ctrl->val = inst->fmts[INPUT_PORT].count_min_host; dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_INPUT, ctrl->val); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 231e9ec82a9f0..29a3e4aa4d3b6 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -591,16 +591,15 @@ void msm_vidc_init_buffer_size_calculators(struct msm_vidc_inst *inst) msm_vidc_calculate_internal_buffer_sizes; } -int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) +int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) { struct msm_vidc_format *fmt; int extra_buff_count = 0; - u32 codec, input_min_count = 4, output_min_count = 4; + u32 input_min_count = 4; if (!is_decode_session(inst) && !is_encode_session(inst)) return 0; - codec = get_v4l2_codec(inst); /* * Update input buff counts * Extradata uses same count as input port @@ -621,6 +620,19 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) __func__, hash32_ptr(inst->session), fmt->count_min, fmt->count_min_host, fmt->count_actual); + return 0; +} + +int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) +{ + struct msm_vidc_format *fmt; + int extra_buff_count = 0; + u32 codec, output_min_count = 4; + + if (!is_decode_session(inst) && !is_encode_session(inst)) + return 0; + + codec = get_v4l2_codec(inst); /* Update output buff count: Changes for decoder based on codec */ if (is_decode_session(inst)) { switch (codec) { @@ -654,6 +666,21 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) return 0; } + +int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst) +{ + int rc; + + rc = msm_vidc_calculate_input_buffer_count(inst); + if (rc) + return rc; + rc = msm_vidc_calculate_output_buffer_count(inst); + if (rc) + return rc; + + return rc; +} + u32 msm_vidc_set_buffer_count_for_thumbnail(struct msm_vidc_inst *inst) { struct msm_vidc_format *fmt; diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 29fe98c606f52..5ba979b7937d6 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -25,7 +25,9 @@ struct msm_vidc_enc_buff_size_calculators { }; void msm_vidc_init_buffer_size_calculators(struct msm_vidc_inst *inst); -int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst); +int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst); +int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst); +int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst); int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type); u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 01335cdaba456..6cb6736dee66d 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -725,6 +725,36 @@ enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst) return HAL_VIDEO_DECODER_PRIMARY; } +bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags) +{ + bool single = true; + struct msm_vidc_core *core; + struct msm_vidc_inst *temp; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return false; + } + core = inst->core; + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + /* ignore invalid session */ + if (temp->state == MSM_VIDC_CORE_INVALID) + continue; + if ((ignore_flags & VIDC_THUMBNAIL) && + is_thumbnail_session(temp)) + continue; + if (temp != inst) { + single = false; + break; + } + } + mutex_unlock(&core->lock); + + return single; +} + static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) { int input_port_mbs, output_port_mbs; @@ -2783,6 +2813,7 @@ static bool is_thermal_permissible(struct msm_vidc_core *core) bool is_batching_allowed(struct msm_vidc_inst *inst) { u32 op_pixelformat, fps, maxmbs, maxfps; + u32 ignore_flags = VIDC_THUMBNAIL; if (!inst || !inst->core) return false; @@ -2794,7 +2825,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) maxmbs = inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME].max; maxfps = inst->capability.cap[CAP_BATCH_MAX_FPS].max; - return (inst->batch.enable && + return (is_single_session(inst, ignore_flags) && is_decode_session(inst) && !is_thumbnail_session(inst) && !inst->clk_data.low_latency_mode && @@ -3150,7 +3181,7 @@ static int msm_comm_session_init(int flipped_state, goto exit; } - rc = msm_vidc_init_buffer_count(inst); + rc = msm_vidc_calculate_buffer_counts(inst); if (rc) { dprintk(VIDC_ERR, "Failed to initialize buff counts\n"); goto exit; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 7135d20436ef2..7e18a095936c2 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -130,6 +130,8 @@ static inline int msm_comm_s_ctrl(struct msm_vidc_inst *inst, { return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl); } + +bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags); bool is_batching_allowed(struct msm_vidc_inst *inst); enum hal_buffer get_hal_buffer_type(unsigned int type, unsigned int plane_num);