msm: vidc: Add support for runtime input CR
Clients send input buffer Compression Ratio through V4L2
buffer. Driver makes use of it while voting for bus BW.
CRs-Fixed: 2012520
Change-Id: I88da9396e98c2e081d1e16c3b1445b14c0ad4528
Signed-off-by: Praneeth Paladugu <ppaladug@codeaurora.org>
diff --git a/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c b/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
index a7b1852..1eaec58 100644
--- a/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
+++ b/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
@@ -565,32 +565,21 @@
*/
/* Encoder Parameters */
- enum hal_video_codec standard;
- int width, height, fps;
- enum hal_uncompressed_format dpb_color_format;
- enum hal_uncompressed_format original_color_format;
+ int width, height, fps, dpb_bpp, lcu_per_frame, lcu_size,
+ vertical_tile_width, colocated_bytes_per_lcu, bitrate,
+ ref_overlap_bw_factor;
+ enum hal_uncompressed_format dpb_color_format, original_color_format;
bool dpb_compression_enabled, original_compression_enabled,
- two_stage_encoding, low_power, rotation, cropping_or_scaling;
+ work_mode_1, low_power, rotation, cropping_or_scaling,
+ b_frames_enabled = false;
fp_t dpb_compression_factor, original_compression_factor,
- qsmmu_bw_overhead_factor;
- bool b_frames_enabled;
-
- /* Derived Parameters */
- int lcu_size;
- enum gop {
- GOP_IBBP,
- GOP_IPPP,
- } gop;
- unsigned long bitrate;
- fp_t bins_to_bit_factor, chroma_luma_factor_dpb, one_frame_bw_dpb,
- chroma_luma_factor_original, one_frame_bw_original,
- line_buffer_size_per_lcu, line_buffer_size, line_buffer_bw,
- bw_increase_p, bw_increase_b;
- int collocated_mv_per_lcu, max_transaction_size,
- search_window_size_vertical_p, search_window_factor_p,
- search_window_factor_bw_p,
- search_window_size_vertical_b, search_window_factor_b,
- search_window_factor_bw_b;
+ input_compression_factor, qsmmu_bw_overhead_factor,
+ ref_y_bw_factor, ref_cb_cr_bw_factor, ten_bpc_bpp_factor,
+ bw_for_1x_8bpc, dpb_bw_for_1x, ref_cb_cr_read,
+ bins_to_bit_factor, ref_y_read, ten_bpc_packing_factor,
+ dpb_write_factor, ref_overlap_bw;
+ fp_t integer_part, frac_part;
+ unsigned long ret = 0;
/* Output paramaters */
struct {
@@ -599,27 +588,41 @@
original_write, dpb_read, dpb_write, total;
} ddr = {0};
- unsigned long ret = 0;
- fp_t integer_part, frac_part;
/* Encoder Parameters setup */
+ ten_bpc_packing_factor = FP(1, 67, 1000);
+ ten_bpc_bpp_factor = FP(1, 1, 4);
+ rotation = false;
+ cropping_or_scaling = false;
+ vertical_tile_width = 960;
+ ref_y_bw_factor = FP(1, 30, 100);
+ ref_cb_cr_bw_factor = FP(1, 50, 100);
+ dpb_write_factor = FP(1, 8, 100);
- standard = d->codec;
+
+ /* Derived Parameters */
+ lcu_size = d->lcu_size;
+ fps = d->fps;
+ b_frames_enabled = d->b_frames_enabled;
width = max(d->input_width, BASELINE_DIMENSIONS.width);
height = max(d->input_height, BASELINE_DIMENSIONS.height);
+ bitrate = __lut(width, height, fps)->bitrate;
+ lcu_per_frame = DIV_ROUND_UP(width, lcu_size) *
+ DIV_ROUND_UP(height, lcu_size);
dpb_color_format = HAL_COLOR_FORMAT_NV12_UBWC;
original_color_format = d->num_formats >= 1 ?
d->color_formats[0] : HAL_UNUSED_COLOR;
- fps = d->fps;
+ dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX;
dpb_compression_enabled = __ubwc(dpb_color_format);
original_compression_enabled = __ubwc(original_color_format);
- two_stage_encoding = false;
+ work_mode_1 = d->work_mode == VIDC_WORK_MODE_1;
low_power = d->power_mode == VIDC_POWER_LOW;
- b_frames_enabled = false;
+ bins_to_bit_factor = work_mode_1 ?
+ FP_INT(0) : FP_INT(4);
/*
* Convert Q16 number into Integer and Fractional part upto 2 places.
@@ -636,96 +639,84 @@
dpb_compression_factor = FP(integer_part, frac_part, 100);
- original_compression_factor = dpb_compression_factor;
+ integer_part = d->input_cr >> 16;
+ frac_part =
+ ((d->input_cr - (integer_part * 65536)) * 100) >> 16;
- rotation = false;
- cropping_or_scaling = false;
+ input_compression_factor = FP(integer_part, frac_part, 100);
- /* Derived Parameters */
- lcu_size = 16;
- gop = b_frames_enabled ? GOP_IBBP : GOP_IPPP;
- bitrate = __lut(width, height, fps)->bitrate;
- bins_to_bit_factor = FP(1, 6, 10);
+ original_compression_factor =
+ original_compression_enabled ? d->use_dpb_read ?
+ dpb_compression_factor : input_compression_factor :
+ FP_ONE;
- /*
- * FIXME: Minor color format related hack: a lot of the derived params
- * depend on the YUV bitdepth as a variable. However, we don't have
- * appropriate enums defined yet (hence no support). As a result omit
- * a lot of the checks (which should look like the snippet below) in
- * favour of hardcoding.
- * dpb_color_format == YUV420 ? 0.5 :
- * dpb_color_format == YUV422 ? 1.0 : 2.0
- * Similar hacks are annotated inline in code with the string "CF hack"
- * for documentation purposes.
- */
- chroma_luma_factor_dpb = FP(0, 1, 2);
- one_frame_bw_dpb = fp_mult(FP_ONE + chroma_luma_factor_dpb,
- fp_div(FP_INT(width * height * fps),
- FP_INT(1000 * 1000)));
-
- chroma_luma_factor_original = FP(0, 1, 2); /* XXX: CF hack */
- one_frame_bw_original = fp_mult(FP_ONE + chroma_luma_factor_original,
- fp_div(FP_INT(width * height * fps),
- FP_INT(1000 * 1000)));
-
- line_buffer_size_per_lcu = FP_ZERO;
- if (lcu_size == 16)
- line_buffer_size_per_lcu = FP_INT(128) + fp_mult(FP_INT(256),
- FP_ONE /*XXX: CF hack */);
- else
- line_buffer_size_per_lcu = FP_INT(192) + fp_mult(FP_INT(512),
- FP_ONE /*XXX: CF hack */);
-
- line_buffer_size = fp_div(
- fp_mult(FP_INT(width / lcu_size),
- line_buffer_size_per_lcu),
- FP_INT(1024));
- line_buffer_bw = fp_mult(line_buffer_size,
- fp_div(FP_INT((height / lcu_size /
- (two_stage_encoding ? 2 : 1) - 1) * fps),
- FP_INT(1000)));
-
- collocated_mv_per_lcu = lcu_size == 16 ? 16 : 64;
- max_transaction_size = 256;
-
- search_window_size_vertical_p = low_power ? 32 :
- b_frames_enabled ? 80 :
- width > 2048 ? 64 : 48;
- search_window_factor_p = search_window_size_vertical_p * 2 / lcu_size;
- search_window_factor_bw_p = !two_stage_encoding ?
- search_window_size_vertical_p * 2 / lcu_size + 1 :
- (search_window_size_vertical_p * 2 / lcu_size + 2) / 2;
- bw_increase_p = fp_mult(one_frame_bw_dpb,
- FP_INT(search_window_factor_bw_p - 1) / 3);
-
- search_window_size_vertical_b = 48;
- search_window_factor_b = search_window_size_vertical_b * 2 / lcu_size;
- search_window_factor_bw_b = !two_stage_encoding ?
- search_window_size_vertical_b * 2 / lcu_size + 1 :
- (search_window_size_vertical_b * 2 / lcu_size + 2) / 2;
- bw_increase_b = fp_mult(one_frame_bw_dpb,
- FP_INT((search_window_factor_bw_b - 1) / 3));
-
- /* Output parameters for DDR */
ddr.vsp_read = fp_mult(fp_div(FP_INT(bitrate), FP_INT(8)),
bins_to_bit_factor);
ddr.vsp_write = ddr.vsp_read + fp_div(FP_INT(bitrate), FP_INT(8));
- ddr.collocated_read = fp_div(FP_INT(DIV_ROUND_UP(width, lcu_size) *
- DIV_ROUND_UP(height, lcu_size) *
- collocated_mv_per_lcu * fps), FP_INT(1000 * 1000));
+ colocated_bytes_per_lcu = lcu_size == 16 ? 16 :
+ lcu_size == 32 ? 64 : 256;
+
+ ddr.collocated_read = FP_INT(lcu_per_frame *
+ colocated_bytes_per_lcu * fps / bps(1));
+
ddr.collocated_write = ddr.collocated_read;
+ ddr.line_buffer_read = FP_INT(16 * lcu_per_frame * fps / bps(1));
+
ddr.line_buffer_write = ddr.line_buffer_read;
- ddr.original_read = fp_div(one_frame_bw_original,
- original_compression_factor);
+ bw_for_1x_8bpc = fp_div(FP_INT(width * height), FP_INT(32 * 8));
+
+ bw_for_1x_8bpc = fp_mult(bw_for_1x_8bpc,
+ fp_div(FP_INT(256 * 30), FP_INT(1000 * 1000)));
+
+ dpb_bw_for_1x = dpb_bpp == 8 ? bw_for_1x_8bpc :
+ fp_mult(bw_for_1x_8bpc, fp_mult(ten_bpc_packing_factor,
+ ten_bpc_bpp_factor));
+
+ ddr.original_read = fp_div(fp_mult(FP(1, 50, 100), dpb_bw_for_1x),
+ input_compression_factor);
+
ddr.original_write = FP_ZERO;
- ddr.dpb_read = FP_ZERO;
+ ref_y_bw_factor =
+ width == vertical_tile_width ? FP_INT(1) : ref_y_bw_factor;
- ddr.dpb_read = fp_div(ddr.dpb_read, dpb_compression_factor);
- ddr.dpb_write = fp_div(one_frame_bw_dpb, dpb_compression_factor);
+ ref_y_read = fp_mult(ref_y_bw_factor, dpb_bw_for_1x);
+
+ ref_y_read = fp_div(ref_y_read, dpb_compression_factor);
+
+ ref_y_read =
+ b_frames_enabled ? fp_mult(ref_y_read, FP_INT(2)) : ref_y_read;
+
+ ref_cb_cr_read = fp_mult(ref_cb_cr_bw_factor, dpb_bw_for_1x);
+
+ ref_cb_cr_read = fp_div(ref_cb_cr_read, dpb_compression_factor);
+
+ ref_cb_cr_read =
+ b_frames_enabled ? fp_mult(ref_cb_cr_read, FP_INT(2)) :
+ ref_cb_cr_read;
+
+ ref_cb_cr_read = fp_div(ref_cb_cr_read, FP_INT(2));
+
+ ddr.dpb_write = fp_mult(dpb_write_factor, dpb_bw_for_1x);
+
+ ddr.dpb_write = fp_mult(ddr.dpb_write, FP(1, 50, 100));
+
+ ddr.dpb_write = fp_div(ddr.dpb_write, input_compression_factor);
+
+ ref_overlap_bw_factor =
+ width <= vertical_tile_width ? FP_INT(0) : FP_INT(1);
+
+ ref_overlap_bw = fp_mult(ddr.dpb_write, ref_overlap_bw_factor);
+
+ ref_overlap_bw = fp_div(ref_overlap_bw, dpb_write_factor);
+
+ ref_overlap_bw = fp_mult(ref_overlap_bw,
+ (dpb_write_factor - FP_INT(1)));
+
+ ddr.dpb_read = ref_y_read + ref_cb_cr_read + ref_overlap_bw;
ddr.total = ddr.vsp_read + ddr.vsp_write +
ddr.collocated_read + ddr.collocated_write +
@@ -739,7 +730,6 @@
if (debug) {
struct dump dump[] = {
{"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC},
- {"standard", "%#x", standard},
{"width", "%d", width},
{"height", "%d", height},
{"DPB format", "%#x", dpb_color_format},
@@ -748,8 +738,8 @@
{"DPB compression enable", "%d", dpb_compression_enabled},
{"original compression enable", "%d",
original_compression_enabled},
- {"two stage encoding", "%d", two_stage_encoding},
{"low power mode", "%d", low_power},
+ {"Work Mode", "%d", work_mode_1},
{"DPB compression factor", DUMP_FP_FMT,
dpb_compression_factor},
{"original compression factor", DUMP_FP_FMT,
@@ -759,44 +749,21 @@
{"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC},
{"LCU size", "%d", lcu_size},
- {"GOB pattern", "%d", gop},
{"bitrate (Mbit/sec)", "%lu", bitrate},
{"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor},
- {"B-frames enabled", "%d", b_frames_enabled},
- {"search window size vertical (B)", "%d",
- search_window_size_vertical_b},
- {"search window factor (B)", "%d", search_window_factor_b},
- {"search window factor BW (B)", "%d",
- search_window_factor_bw_b},
- {"bw increase (MB/s) (B)", DUMP_FP_FMT, bw_increase_b},
- {"search window size vertical (P)", "%d",
- search_window_size_vertical_p},
- {"search window factor (P)", "%d", search_window_factor_p},
- {"search window factor BW (P)", "%d",
- search_window_factor_bw_p},
- {"bw increase (MB/s) (P)", DUMP_FP_FMT, bw_increase_p},
- {"chroma/luma factor DPB", DUMP_FP_FMT,
- chroma_luma_factor_dpb},
- {"one frame BW DPB (MB/s)", DUMP_FP_FMT, one_frame_bw_dpb},
- {"chroma/Luma factor original", DUMP_FP_FMT,
- chroma_luma_factor_original},
- {"one frame BW original (MB/s)", DUMP_FP_FMT,
- one_frame_bw_original},
- {"line buffer size per LCU", DUMP_FP_FMT,
- line_buffer_size_per_lcu},
- {"line buffer size (KB)", DUMP_FP_FMT, line_buffer_size},
- {"line buffer BW (MB/s)", DUMP_FP_FMT, line_buffer_bw},
- {"collocated MVs per LCU", "%d", collocated_mv_per_lcu},
{"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC},
+ {"ref_y_read", DUMP_FP_FMT, ref_y_read},
+ {"ref_cb_cr_read", DUMP_FP_FMT, ref_cb_cr_read},
+ {"ref_overlap_bw", DUMP_FP_FMT, ref_overlap_bw},
{"VSP read", DUMP_FP_FMT, ddr.vsp_read},
- {"VSP read", DUMP_FP_FMT, ddr.vsp_write},
+ {"VSP write", DUMP_FP_FMT, ddr.vsp_write},
{"collocated read", DUMP_FP_FMT, ddr.collocated_read},
- {"collocated read", DUMP_FP_FMT, ddr.collocated_write},
+ {"collocated write", DUMP_FP_FMT, ddr.collocated_write},
{"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read},
- {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_write},
+ {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write},
{"original read", DUMP_FP_FMT, ddr.original_read},
- {"original read", DUMP_FP_FMT, ddr.original_write},
+ {"original write", DUMP_FP_FMT, ddr.original_write},
{"DPB read", DUMP_FP_FMT, ddr.dpb_read},
{"DPB write", DUMP_FP_FMT, ddr.dpb_write},
};
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index e5d1576..a08f282 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1140,6 +1140,12 @@
buffreq->buffer[10].buffer_type =
HAL_BUFFER_INTERNAL_PERSIST_1;
break;
+ case HFI_BUFFER_COMMON_INTERNAL_RECON:
+ memcpy(&buffreq->buffer[11], hfi_buf_req,
+ sizeof(struct hfi_buffer_requirements));
+ buffreq->buffer[11].buffer_type =
+ HAL_BUFFER_INTERNAL_RECON;
+ break;
default:
dprintk(VIDC_ERR,
"hal_process_sess_get_prop_buf_req: bad_buffer_type: %d\n",
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index bc4b280..de45678 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -2362,6 +2362,7 @@
rc = -EINVAL;
goto exit;
}
+ inst->clk_data.opb_fourcc = f->fmt.pix_mp.pixelformat;
memcpy(&inst->fmts[fmt->type], fmt,
sizeof(struct msm_vidc_format));
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 1b931ee..854aa0a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -442,6 +442,7 @@
struct msm_vidc_inst *inst = instance;
int rc = 0, i = 0;
struct buf_queue *q = NULL;
+ u32 cr = 0;
if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n",
@@ -453,8 +454,16 @@
b->m.planes[i].m.fd = b->m.planes[i].reserved[0];
b->m.planes[i].data_offset = b->m.planes[i].reserved[1];
}
+
msm_comm_qbuf_cache_operations(inst, b);
+ /* Compression ratio is valid only for Encoder YUV buffers. */
+ if (inst->session_type == MSM_VIDC_ENCODER &&
+ b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ cr = b->m.planes[0].reserved[2];
+ msm_comm_update_input_cr(inst, b->index, cr);
+ }
+
q = msm_comm_get_vb2q(inst, b->type);
if (!q) {
dprintk(VIDC_ERR,
@@ -712,7 +721,6 @@
rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
bufreq->buffer_count_actual, HAL_BUFFER_INPUT);
}
-
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
buffer_type = msm_comm_get_hal_output_buffer(inst);
@@ -1494,6 +1502,7 @@
INIT_MSM_VIDC_LIST(&inst->scratchbufs);
INIT_MSM_VIDC_LIST(&inst->freqs);
+ INIT_MSM_VIDC_LIST(&inst->input_crs);
INIT_MSM_VIDC_LIST(&inst->persistbufs);
INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
INIT_MSM_VIDC_LIST(&inst->outputbufs);
@@ -1605,6 +1614,8 @@
DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
+ DEINIT_MSM_VIDC_LIST(&inst->freqs);
+ DEINIT_MSM_VIDC_LIST(&inst->input_crs);
kfree(inst);
inst = NULL;
@@ -1634,6 +1645,8 @@
msm_comm_free_freq_table(inst);
+ msm_comm_free_input_cr_table(inst);
+
if (msm_comm_release_scratch_buffers(inst, false))
dprintk(VIDC_ERR,
"Failed to release scratch buffers\n");
@@ -1699,6 +1712,8 @@
DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
+ DEINIT_MSM_VIDC_LIST(&inst->freqs);
+ DEINIT_MSM_VIDC_LIST(&inst->input_crs);
mutex_destroy(&inst->sync_lock);
mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 6b09a54..ba14ea9 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -19,6 +19,9 @@
#define MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR (1 << 16)
#define MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR (4 << 16)
+#define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16)
+#define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16)
+
static inline unsigned long int get_ubwc_compression_ratio(
struct ubwc_cr_stats_info_type ubwc_stats_info)
{
@@ -90,36 +93,56 @@
mutex_unlock(&inst->reconbufs.lock);
}
-static int fill_recon_stats(struct msm_vidc_inst *inst,
+static int fill_dynamic_stats(struct msm_vidc_inst *inst,
struct vidc_bus_vote_data *vote_data)
{
- struct recon_buf *binfo;
- u32 CR = 0, min_cf = MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR,
- max_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR;
+ struct recon_buf *binfo, *nextb;
+ struct vidc_input_cr_data *temp, *next;
+ u32 min_cf = 0, max_cf = 0;
+ u32 min_input_cr = 0, max_input_cr = 0, min_cr = 0, max_cr = 0;
mutex_lock(&inst->reconbufs.lock);
- list_for_each_entry(binfo, &inst->reconbufs.list, list) {
- CR = max(CR, binfo->CR);
+ list_for_each_entry_safe(binfo, nextb, &inst->reconbufs.list, list) {
+ min_cr = min(min_cr, binfo->CR);
+ max_cr = max(max_cr, binfo->CR);
min_cf = min(min_cf, binfo->CF);
max_cf = max(max_cf, binfo->CF);
}
mutex_unlock(&inst->reconbufs.lock);
+ mutex_lock(&inst->input_crs.lock);
+ list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) {
+ min_input_cr = min(min_input_cr, temp->input_cr);
+ max_input_cr = max(max_input_cr, temp->input_cr);
+ }
+ mutex_unlock(&inst->input_crs.lock);
+
/* Sanitize CF values from HW . */
max_cf = min_t(u32, max_cf, MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR);
min_cf = max_t(u32, min_cf, MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR);
+ max_cr = min_t(u32, max_cr, MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO);
+ min_cr = max_t(u32, min_cr, MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO);
+ max_input_cr = min_t(u32,
+ max_input_cr, MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO);
+ min_input_cr = max_t(u32,
+ min_input_cr, MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO);
- vote_data->compression_ratio = CR;
+ vote_data->compression_ratio = min_cr;
vote_data->complexity_factor = max_cf;
+ vote_data->input_cr = min_input_cr;
vote_data->use_dpb_read = false;
+
+ /* Check if driver can vote for lower bus BW */
if (inst->clk_data.load <= inst->clk_data.load_norm) {
+ vote_data->compression_ratio = max_cr;
vote_data->complexity_factor = min_cf;
+ vote_data->input_cr = max_input_cr;
vote_data->use_dpb_read = true;
}
- dprintk(VIDC_DBG,
- "Compression Ratio = %d Complexity Factor = %d\n",
- vote_data->compression_ratio,
+ dprintk(VIDC_PROF,
+ "Input CR = %d Recon CR = %d Complexity Factor = %d\n",
+ vote_data->input_cr, vote_data->compression_ratio,
vote_data->complexity_factor);
return 0;
@@ -198,6 +221,9 @@
max(inst->prop.height[CAPTURE_PORT],
inst->prop.height[OUTPUT_PORT]);
vote_data[i].lcu_size = codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
+ vote_data[i].b_frames_enabled =
+ msm_comm_g_ctrl_for_id(inst,
+ V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES) != 0;
if (inst->clk_data.operating_rate)
vote_data[i].fps =
@@ -227,7 +253,7 @@
vote_data[i].num_formats = 2;
}
vote_data[i].work_mode = inst->clk_data.work_mode;
- fill_recon_stats(inst, &vote_data[i]);
+ fill_dynamic_stats(inst, &vote_data[i]);
if (core->resources.sys_cache_res_set)
vote_data[i].use_sys_cache = true;
@@ -356,10 +382,15 @@
if (!found) {
temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+ if (!temp) {
+ dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__);
+ goto exit;
+ }
temp->freq = freq;
temp->device_addr = device_addr;
list_add_tail(&temp->list, &inst->freqs.list);
}
+exit:
mutex_unlock(&inst->freqs.lock);
}
@@ -415,6 +446,48 @@
mutex_unlock(&inst->freqs.lock);
}
+void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst)
+{
+ struct vidc_input_cr_data *temp, *next;
+
+ mutex_lock(&inst->input_crs.lock);
+ list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) {
+ list_del(&temp->list);
+ kfree(temp);
+ }
+ INIT_LIST_HEAD(&inst->input_crs.list);
+ mutex_unlock(&inst->input_crs.lock);
+}
+
+void msm_comm_update_input_cr(struct msm_vidc_inst *inst,
+ u32 index, u32 cr)
+{
+ struct vidc_input_cr_data *temp, *next;
+ bool found = false;
+
+ mutex_lock(&inst->input_crs.lock);
+ list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) {
+ if (temp->index == index) {
+ temp->input_cr = cr;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+ if (!temp) {
+ dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__);
+ goto exit;
+ }
+ temp->index = index;
+ temp->input_cr = cr;
+ list_add_tail(&temp->list, &inst->input_crs.list);
+ }
+exit:
+ mutex_unlock(&inst->input_crs.lock);
+}
+
static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core)
{
struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.h b/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
index 705cb7c..707f034 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
@@ -33,6 +33,9 @@
int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst);
void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst,
u32 device_addr);
+void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst);
+void msm_comm_update_input_cr(struct msm_vidc_inst *inst, u32 index,
+ u32 cr);
void update_recon_stats(struct msm_vidc_inst *inst,
struct recon_stats_type *recon_stats);
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 48afa0b..f5793d4 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -4769,8 +4769,7 @@
return 0;
}
- if (!list_empty(&inst->reconbufs.list))
- msm_comm_release_recon_buffers(inst);
+ msm_comm_release_recon_buffers(inst);
for (i = 0; i < internal_buf->buffer_count_actual; i++) {
binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 6511029..57dfd52 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -144,6 +144,12 @@
unsigned long freq;
};
+struct vidc_input_cr_data {
+ struct list_head list;
+ u32 index;
+ u32 input_cr;
+};
+
struct recon_buf {
struct list_head list;
u32 buffer_index;
@@ -327,6 +333,7 @@
struct msm_vidc_format fmts[MAX_PORT_NUM];
struct buf_queue bufq[MAX_PORT_NUM];
struct msm_vidc_list freqs;
+ struct msm_vidc_list input_crs;
struct msm_vidc_list scratchbufs;
struct msm_vidc_list persistbufs;
struct msm_vidc_list pending_getpropq;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index fbd3b02..e854b43 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1345,11 +1345,13 @@
int output_height, output_width;
int compression_ratio;
int complexity_factor;
+ int input_cr;
bool use_dpb_read;
unsigned int lcu_size;
enum msm_vidc_power_mode power_mode;
enum hal_work_mode work_mode;
bool use_sys_cache;
+ bool b_frames_enabled;
};
struct vidc_clk_scale_data {