mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 23:24:22 -04:00
msm: vidc: Add window based bitrate check in decoder
In decoder, window based bitrate check will help identify usecases where, input bitrate exceeds hw capabilities. CRs-Fixed: 2497423 Change-Id: Ic68bd66584ed84382ba03777d39775d08278a8a0 Signed-off-by: Qiwei Liu <qiweil@codeaurora.org> Signed-off-by: Chinmay Sawarkar <chinmays@codeaurora.org>
This commit is contained in:
parent
5a31d042fe
commit
15f3510a38
11 changed files with 134 additions and 14 deletions
|
|
@ -2387,7 +2387,7 @@ static int venus_hfi_session_init(void *device, void *session_id,
|
|||
s->device = dev;
|
||||
s->codec = codec_type;
|
||||
s->domain = session_type;
|
||||
dprintk(VIDC_HIGH,
|
||||
dprintk(VIDC_HIGH|VIDC_PERF,
|
||||
"%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n",
|
||||
__func__, session_id, s, s->codec, s->domain);
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
|
|||
(struct hfi_frame_size *) data_ptr;
|
||||
event_notify.width = frame_sz->width;
|
||||
event_notify.height = frame_sz->height;
|
||||
dprintk(VIDC_HIGH, "height: %d width: %d\n",
|
||||
dprintk(VIDC_HIGH|VIDC_PERF,
|
||||
"height: %d width: %d\n",
|
||||
frame_sz->height, frame_sz->width);
|
||||
data_ptr +=
|
||||
sizeof(struct hfi_frame_size);
|
||||
|
|
@ -173,7 +174,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
|
|||
(struct hfi_profile_level *) data_ptr;
|
||||
event_notify.profile = profile_level->profile;
|
||||
event_notify.level = profile_level->level;
|
||||
dprintk(VIDC_HIGH, "profile: %d level: %d\n",
|
||||
dprintk(VIDC_HIGH|VIDC_PERF,
|
||||
"profile: %d level: %d\n",
|
||||
profile_level->profile,
|
||||
profile_level->level);
|
||||
data_ptr +=
|
||||
|
|
@ -209,7 +211,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
|
|||
MSM_VIDC_BIT_DEPTH_10;
|
||||
else
|
||||
event_notify.bit_depth = luma_bit_depth;
|
||||
dprintk(VIDC_HIGH,
|
||||
dprintk(VIDC_HIGH|VIDC_PERF,
|
||||
"bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n",
|
||||
event_notify.bit_depth, luma_bit_depth,
|
||||
chroma_bit_depth);
|
||||
|
|
@ -224,7 +226,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
|
|||
pic_struct = (struct hfi_pic_struct *) data_ptr;
|
||||
event_notify.pic_struct =
|
||||
pic_struct->progressive_only;
|
||||
dprintk(VIDC_HIGH,
|
||||
dprintk(VIDC_HIGH|VIDC_PERF,
|
||||
"Progressive only flag: %d\n",
|
||||
pic_struct->progressive_only);
|
||||
data_ptr +=
|
||||
|
|
@ -253,7 +255,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
|
|||
data_ptr = data_ptr + sizeof(u32);
|
||||
entropy_mode = *(u32 *)data_ptr;
|
||||
event_notify.entropy_mode = entropy_mode;
|
||||
dprintk(VIDC_HIGH,
|
||||
dprintk(VIDC_HIGH|VIDC_PERF,
|
||||
"Entropy Mode: 0x%x\n", entropy_mode);
|
||||
data_ptr +=
|
||||
sizeof(u32);
|
||||
|
|
@ -269,7 +271,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
|
|||
data_ptr;
|
||||
event_notify.capture_buf_count =
|
||||
buf_req->buffer_count_min;
|
||||
dprintk(VIDC_HIGH,
|
||||
dprintk(VIDC_HIGH|VIDC_PERF,
|
||||
"Capture Count : 0x%x\n",
|
||||
event_notify.capture_buf_count);
|
||||
data_ptr +=
|
||||
|
|
|
|||
|
|
@ -920,7 +920,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
|
|||
*/
|
||||
if (inst->batch.enable)
|
||||
inst->batch.enable = is_batching_allowed(inst);
|
||||
dprintk(VIDC_HIGH, "%s: batching %s for inst %pK (%#x)\n",
|
||||
dprintk(VIDC_HIGH|VIDC_PERF, "%s: batching %s for inst %pK (%#x)\n",
|
||||
__func__, inst->batch.enable ? "enabled" : "disabled",
|
||||
inst, hash32_ptr(inst->session));
|
||||
|
||||
|
|
@ -1524,6 +1524,7 @@ void *msm_vidc_open(int core_id, int session_type)
|
|||
INIT_MSM_VIDC_LIST(&inst->eosbufs);
|
||||
INIT_MSM_VIDC_LIST(&inst->etb_data);
|
||||
INIT_MSM_VIDC_LIST(&inst->fbd_data);
|
||||
INIT_MSM_VIDC_LIST(&inst->window_data);
|
||||
|
||||
INIT_DELAYED_WORK(&inst->batch_work, msm_vidc_batch_handler);
|
||||
kref_init(&inst->kref);
|
||||
|
|
@ -1638,6 +1639,7 @@ fail_bufq_capture:
|
|||
DEINIT_MSM_VIDC_LIST(&inst->input_crs);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->etb_data);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->window_data);
|
||||
|
||||
kfree(inst);
|
||||
inst = NULL;
|
||||
|
|
@ -1709,6 +1711,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
|
|||
dprintk(VIDC_ERR,
|
||||
"Failed to release mark_data buffers\n");
|
||||
|
||||
msm_comm_release_window_data(inst);
|
||||
|
||||
msm_comm_release_eos_buffers(inst);
|
||||
|
||||
if (msm_comm_release_dpb_only_buffers(inst, true))
|
||||
|
|
@ -1769,6 +1773,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
|
|||
DEINIT_MSM_VIDC_LIST(&inst->input_crs);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->etb_data);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
|
||||
DEINIT_MSM_VIDC_LIST(&inst->window_data);
|
||||
|
||||
mutex_destroy(&inst->sync_lock);
|
||||
mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
|
||||
|
|
|
|||
|
|
@ -1780,7 +1780,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id)
|
|||
out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt;
|
||||
inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt;
|
||||
dprintk(VIDC_PERF,
|
||||
"inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s %lu\n",
|
||||
"inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %u %s %s %lu\n",
|
||||
inst,
|
||||
inp_f->fmt.pix_mp.width,
|
||||
inp_f->fmt.pix_mp.height,
|
||||
|
|
@ -1790,6 +1790,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id)
|
|||
inst->session_type == MSM_VIDC_ENCODER ? "ENC" : "DEC",
|
||||
inst->clk_data.work_mode == HFI_WORKMODE_1 ?
|
||||
"WORK_MODE_1" : "WORK_MODE_2",
|
||||
inst->clk_data.work_route,
|
||||
inst->flags & VIDC_LOW_POWER ? "LP" : "HQ",
|
||||
inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime",
|
||||
inst->clk_data.min_freq);
|
||||
|
|
|
|||
|
|
@ -1729,6 +1729,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
|
|||
|
||||
inst->profile = event_notify->profile;
|
||||
inst->level = event_notify->level;
|
||||
inst->entropy_mode = event_notify->entropy_mode;
|
||||
inst->prop.crop_info.left =
|
||||
event_notify->crop_data.left;
|
||||
inst->prop.crop_info.top =
|
||||
|
|
@ -1795,7 +1796,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
|
|||
/* decide batching as configuration changed */
|
||||
if (inst->batch.enable)
|
||||
inst->batch.enable = is_batching_allowed(inst);
|
||||
dprintk(VIDC_HIGH, "%s: %x : batching %s\n",
|
||||
dprintk(VIDC_HIGH|VIDC_PERF, "%s: %x : batching %s\n",
|
||||
__func__, hash32_ptr(inst->session),
|
||||
inst->batch.enable ? "enabled" : "disabled");
|
||||
|
||||
|
|
@ -2095,6 +2096,9 @@ static void handle_session_flush(enum hal_command_response cmd, void *data)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
if (flush_type == HAL_FLUSH_ALL)
|
||||
msm_comm_release_window_data(inst);
|
||||
|
||||
dprintk(VIDC_HIGH,
|
||||
"Notify flush complete, flush_type: %x\n", flush_type);
|
||||
v4l2_event_queue_fh(&inst->event_handler, &flush_event);
|
||||
|
|
@ -4306,6 +4310,10 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst,
|
|||
mbuf->flags |= MSM_VIDC_FLAG_QUEUED;
|
||||
msm_vidc_debugfs_update(inst, e);
|
||||
|
||||
if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE &&
|
||||
is_decode_session(inst))
|
||||
rc = msm_comm_check_window_bitrate(inst, &frame_data);
|
||||
|
||||
err_bad_input:
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -4450,7 +4458,7 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst,
|
|||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);
|
||||
|
||||
print_vidc_buffer(VIDC_HIGH, "qbuf in rbr", inst, mbuf);
|
||||
print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf in rbr", inst, mbuf);
|
||||
rc = msm_comm_qbuf_to_hfi(inst, mbuf);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc);
|
||||
|
|
@ -4487,7 +4495,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
|
|||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);
|
||||
|
||||
print_vidc_buffer(VIDC_HIGH, "qbuf", inst, mbuf);
|
||||
print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf", inst, mbuf);
|
||||
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
|
||||
if (ctrl->val)
|
||||
rc = msm_comm_qbuf_superframe_to_hfi(inst, mbuf);
|
||||
|
|
@ -4572,7 +4580,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst,
|
|||
if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING)
|
||||
goto loop_end;
|
||||
|
||||
print_vidc_buffer(VIDC_HIGH, "batch-qbuf", inst, buf);
|
||||
print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "batch-qbuf", inst, buf);
|
||||
rc = msm_comm_qbuf_to_hfi(inst, buf);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: Failed batch qbuf to hfi: %d\n",
|
||||
|
|
@ -4614,7 +4622,8 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst,
|
|||
|
||||
if (inst->state != MSM_VIDC_START_DONE) {
|
||||
mbuf->flags |= MSM_VIDC_FLAG_DEFERRED;
|
||||
print_vidc_buffer(VIDC_HIGH, "qbuf deferred", inst, mbuf);
|
||||
print_vidc_buffer(VIDC_HIGH|VIDC_PERF,
|
||||
"qbuf deferred", inst, mbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6170,6 +6179,10 @@ void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst,
|
|||
{
|
||||
if (!(tag & msm_vidc_debug) || !inst || !vb2)
|
||||
return;
|
||||
if ((tag & VIDC_PERF) &&
|
||||
!(tag & VIDC_HIGH) &&
|
||||
(inst->session_type != MSM_VIDC_DECODER))
|
||||
return;
|
||||
|
||||
if (vb2->num_planes == 1)
|
||||
dprintk(tag,
|
||||
|
|
@ -7195,3 +7208,80 @@ bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core)
|
|||
}
|
||||
return overload;
|
||||
}
|
||||
|
||||
int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst,
|
||||
struct vidc_frame_data *frame_data)
|
||||
{
|
||||
struct msm_vidc_window_data *pdata, *next;
|
||||
u32 bitrate, max_br, window_size;
|
||||
int buf_cnt = 1, fps, window_start;
|
||||
|
||||
if (!inst || !inst->core || !frame_data) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!inst->core->resources.avsync_window_size)
|
||||
return 0;
|
||||
|
||||
fps = inst->clk_data.frame_rate >> 16;
|
||||
max_br = MAX_BITRATE_DECODER_CAVLC;
|
||||
if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC)
|
||||
max_br = inst->clk_data.work_mode == HFI_WORKMODE_2 ?
|
||||
MAX_BITRATE_DECODER_2STAGE_CABAC :
|
||||
MAX_BITRATE_DECODER_1STAGE_CABAC;
|
||||
window_size = inst->core->resources.avsync_window_size * fps;
|
||||
window_size = DIV_ROUND_UP(window_size, 1000);
|
||||
|
||||
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bitrate = pdata->frame_size = frame_data->filled_len;
|
||||
window_start = pdata->etb_count = inst->count.etb;
|
||||
|
||||
mutex_lock(&inst->window_data.lock);
|
||||
list_add(&pdata->list, &inst->window_data.list);
|
||||
list_for_each_entry_safe_continue(pdata, next,
|
||||
&inst->window_data.list, list) {
|
||||
if (buf_cnt < window_size) {
|
||||
bitrate += pdata->frame_size;
|
||||
window_start = pdata->etb_count;
|
||||
buf_cnt++;
|
||||
} else {
|
||||
list_del(&pdata->list);
|
||||
kfree(pdata);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->window_data.lock);
|
||||
|
||||
bitrate = DIV_ROUND_UP(((u64)bitrate * 8 * fps), window_size);
|
||||
if (bitrate > max_br) {
|
||||
dprintk(VIDC_PERF,
|
||||
"Unsupported bitrate %u max %u, window size %u [%u,%u]",
|
||||
bitrate, max_br, window_size,
|
||||
window_start, inst->count.etb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msm_comm_release_window_data(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_vidc_window_data *pdata, *next;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params %pK\n",
|
||||
__func__, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&inst->window_data.lock);
|
||||
list_for_each_entry_safe(pdata, next, &inst->window_data.list, list) {
|
||||
list_del(&pdata->list);
|
||||
kfree(pdata);
|
||||
}
|
||||
mutex_unlock(&inst->window_data.lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
#define CBR_MB_LIMIT (((1280+15)/16)*((720+15)/16)*30)
|
||||
#define CBR_VFR_MB_LIMIT (((640+15)/16)*((480+15)/16)*30)
|
||||
#define V4L2_CID_MPEG_VIDEO_UNKNOWN (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF)
|
||||
#define MAX_BITRATE_DECODER_CAVLC 220000000
|
||||
#define MAX_BITRATE_DECODER_2STAGE_CABAC 200000000
|
||||
#define MAX_BITRATE_DECODER_1STAGE_CABAC 70000000
|
||||
|
||||
struct vb2_buf_entry {
|
||||
struct list_head list;
|
||||
|
|
@ -307,4 +310,7 @@ int msm_comm_set_extradata(struct msm_vidc_inst *inst, uint32_t extradata_id,
|
|||
uint32_t value);
|
||||
bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core);
|
||||
void msm_vidc_batch_handler(struct work_struct *work);
|
||||
int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst,
|
||||
struct vidc_frame_data *frame_data);
|
||||
void msm_comm_release_window_data(struct msm_vidc_inst *inst);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ static inline char *get_debug_level_str(int level)
|
|||
switch (level) {
|
||||
case VIDC_ERR:
|
||||
return "err";
|
||||
case VIDC_HIGH|VIDC_PERF:
|
||||
case VIDC_HIGH:
|
||||
return "high";
|
||||
case VIDC_LOW:
|
||||
|
|
|
|||
|
|
@ -206,6 +206,12 @@ struct msm_vidc_buf_data {
|
|||
u32 filled_length;
|
||||
};
|
||||
|
||||
struct msm_vidc_window_data {
|
||||
struct list_head list;
|
||||
u32 frame_size;
|
||||
u32 etb_count;
|
||||
};
|
||||
|
||||
struct msm_vidc_common_data {
|
||||
char key[128];
|
||||
int value;
|
||||
|
|
@ -493,6 +499,7 @@ struct msm_vidc_inst {
|
|||
struct msm_vidc_list cvpbufs;
|
||||
struct msm_vidc_list etb_data;
|
||||
struct msm_vidc_list fbd_data;
|
||||
struct msm_vidc_list window_data;
|
||||
struct buffer_requirements buff_req;
|
||||
struct vidc_frame_data superframe_data[VIDC_SUPERFRAME_MAX];
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
|
@ -520,6 +527,7 @@ struct msm_vidc_inst {
|
|||
u32 colour_space;
|
||||
u32 profile;
|
||||
u32 level;
|
||||
u32 entropy_mode;
|
||||
u32 rc_type;
|
||||
u32 hybrid_hp;
|
||||
u32 layer_bitrate;
|
||||
|
|
|
|||
|
|
@ -627,6 +627,10 @@ static struct msm_vidc_common_data kona_common_data[] = {
|
|||
.key = "qcom,fw-vpp-cycles",
|
||||
.value = 44156,
|
||||
},
|
||||
{
|
||||
.key = "qcom,avsync-window-size",
|
||||
.value = 40,
|
||||
},
|
||||
};
|
||||
|
||||
static struct msm_vidc_common_data sm6150_common_data[] = {
|
||||
|
|
|
|||
|
|
@ -835,6 +835,8 @@ int read_platform_resources_from_drv_data(
|
|||
"qcom,fw-cycles");
|
||||
res->fw_vpp_cycles = find_key_value(platform_data,
|
||||
"qcom,fw-vpp-cycles");
|
||||
res->avsync_window_size = find_key_value(platform_data,
|
||||
"qcom,avsync-window-size");
|
||||
|
||||
res->csc_coeff_data = &platform_data->csc_data;
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ struct msm_vidc_platform_resources {
|
|||
uint32_t vpu_ver;
|
||||
uint32_t fw_cycles;
|
||||
uint32_t fw_vpp_cycles;
|
||||
uint32_t avsync_window_size;
|
||||
struct msm_vidc_ubwc_config_data *ubwc_config;
|
||||
uint32_t clk_freq_threshold;
|
||||
struct cx_ipeak_client *cx_ipeak_context;
|
||||
|
|
|
|||
Loading…
Reference in a new issue