video: driver: add support for timestamp reorder
Added support for timestamp reorder. It is default disabled. Change-Id: I51a6fc785860081b651fc67f443132cb2675b9fd Signed-off-by: Govindaraj Rajagopal <quic_grajagop@quicinc.com>
这个提交包含在:
@@ -381,6 +381,11 @@ static struct msm_platform_inst_capability instance_data_diwali_v0[] = {
|
|||||||
{0},
|
{0},
|
||||||
NULL, msm_vidc_set_u32},
|
NULL, msm_vidc_set_u32},
|
||||||
|
|
||||||
|
{TS_REORDER, DEC, H264|HEVC,
|
||||||
|
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||||
|
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||||
|
V4L2_CID_MPEG_VIDC_TS_REORDER},
|
||||||
|
|
||||||
{HFLIP, ENC, CODECS_ALL,
|
{HFLIP, ENC, CODECS_ALL,
|
||||||
V4L2_MPEG_MSM_VIDC_DISABLE,
|
V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||||
V4L2_MPEG_MSM_VIDC_ENABLE,
|
V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||||
|
@@ -262,6 +262,11 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
|||||||
{0},
|
{0},
|
||||||
NULL, msm_vidc_set_u32},
|
NULL, msm_vidc_set_u32},
|
||||||
|
|
||||||
|
{TS_REORDER, DEC, H264|HEVC,
|
||||||
|
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||||
|
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||||
|
V4L2_CID_MPEG_VIDC_TS_REORDER},
|
||||||
|
|
||||||
{HFLIP, ENC, CODECS_ALL,
|
{HFLIP, ENC, CODECS_ALL,
|
||||||
V4L2_MPEG_MSM_VIDC_DISABLE,
|
V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||||
V4L2_MPEG_MSM_VIDC_ENABLE,
|
V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||||
|
@@ -67,6 +67,12 @@ static inline is_output_meta_buffer(enum msm_vidc_buffer_type buffer_type)
|
|||||||
return buffer_type == MSM_VIDC_BUF_OUTPUT_META;
|
return buffer_type == MSM_VIDC_BUF_OUTPUT_META;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline is_ts_reorder_allowed(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
return !!(inst->capabilities->cap[TS_REORDER].value &&
|
||||||
|
is_decode_session(inst) && !is_image_session(inst));
|
||||||
|
}
|
||||||
|
|
||||||
static inline is_scaling_enabled(struct msm_vidc_inst *inst)
|
static inline is_scaling_enabled(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
return inst->crop.left != inst->compose.left ||
|
return inst->crop.left != inst->compose.left ||
|
||||||
@@ -428,6 +434,10 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp);
|
|||||||
int msm_vidc_set_auto_framerate(struct msm_vidc_inst *inst, u64 timestamp);
|
int msm_vidc_set_auto_framerate(struct msm_vidc_inst *inst, u64 timestamp);
|
||||||
int msm_vidc_calc_window_avg_framerate(struct msm_vidc_inst *inst);
|
int msm_vidc_calc_window_avg_framerate(struct msm_vidc_inst *inst);
|
||||||
int msm_vidc_flush_ts(struct msm_vidc_inst *inst);
|
int msm_vidc_flush_ts(struct msm_vidc_inst *inst);
|
||||||
|
int msm_vidc_ts_reorder_insert_timestamp(struct msm_vidc_inst *inst, u64 timestamp);
|
||||||
|
int msm_vidc_ts_reorder_remove_timestamp(struct msm_vidc_inst *inst, u64 timestamp);
|
||||||
|
int msm_vidc_ts_reorder_get_first_timestamp(struct msm_vidc_inst *inst, u64 *timestamp);
|
||||||
|
int msm_vidc_ts_reorder_flush(struct msm_vidc_inst *inst);
|
||||||
const char *buf_name(enum msm_vidc_buffer_type type);
|
const char *buf_name(enum msm_vidc_buffer_type type);
|
||||||
void msm_vidc_free_capabililty_list(struct msm_vidc_inst *inst,
|
void msm_vidc_free_capabililty_list(struct msm_vidc_inst *inst,
|
||||||
enum msm_vidc_ctrl_list_type list_type);
|
enum msm_vidc_ctrl_list_type list_type);
|
||||||
|
@@ -118,6 +118,7 @@ struct msm_vidc_inst {
|
|||||||
struct msm_vidc_mappings_info mappings;
|
struct msm_vidc_mappings_info mappings;
|
||||||
struct msm_vidc_allocations_info allocations;
|
struct msm_vidc_allocations_info allocations;
|
||||||
struct msm_vidc_timestamps timestamps;
|
struct msm_vidc_timestamps timestamps;
|
||||||
|
struct msm_vidc_timestamps ts_reorder; /* list of struct msm_vidc_timestamp */
|
||||||
bool subscribed_input_psc;
|
bool subscribed_input_psc;
|
||||||
bool subscribed_output_psc;
|
bool subscribed_output_psc;
|
||||||
bool subscribed_input_prop;
|
bool subscribed_input_prop;
|
||||||
|
@@ -363,6 +363,7 @@ enum msm_vidc_inst_capability_type {
|
|||||||
MB_CYCLES_FW,
|
MB_CYCLES_FW,
|
||||||
MB_CYCLES_FW_VPP,
|
MB_CYCLES_FW_VPP,
|
||||||
SECURE_MODE,
|
SECURE_MODE,
|
||||||
|
TS_REORDER,
|
||||||
HFLIP,
|
HFLIP,
|
||||||
VFLIP,
|
VFLIP,
|
||||||
ROTATION,
|
ROTATION,
|
||||||
|
@@ -1610,6 +1610,10 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
rc = msm_vidc_ts_reorder_flush(inst);
|
||||||
|
if (rc)
|
||||||
|
goto error;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@@ -840,6 +840,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
|
|||||||
}
|
}
|
||||||
INIT_LIST_HEAD(&inst->response_works);
|
INIT_LIST_HEAD(&inst->response_works);
|
||||||
INIT_LIST_HEAD(&inst->timestamps.list);
|
INIT_LIST_HEAD(&inst->timestamps.list);
|
||||||
|
INIT_LIST_HEAD(&inst->ts_reorder.list);
|
||||||
INIT_LIST_HEAD(&inst->buffers.input.list);
|
INIT_LIST_HEAD(&inst->buffers.input.list);
|
||||||
INIT_LIST_HEAD(&inst->buffers.input_meta.list);
|
INIT_LIST_HEAD(&inst->buffers.input_meta.list);
|
||||||
INIT_LIST_HEAD(&inst->buffers.output.list);
|
INIT_LIST_HEAD(&inst->buffers.output.list);
|
||||||
|
@@ -81,6 +81,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
|
|||||||
{MB_CYCLES_FW, "MB_CYCLES_FW" },
|
{MB_CYCLES_FW, "MB_CYCLES_FW" },
|
||||||
{MB_CYCLES_FW_VPP, "MB_CYCLES_FW_VPP" },
|
{MB_CYCLES_FW_VPP, "MB_CYCLES_FW_VPP" },
|
||||||
{SECURE_MODE, "SECURE_MODE" },
|
{SECURE_MODE, "SECURE_MODE" },
|
||||||
|
{TS_REORDER, "TS_REORDER" },
|
||||||
{HFLIP, "HFLIP" },
|
{HFLIP, "HFLIP" },
|
||||||
{VFLIP, "VFLIP" },
|
{VFLIP, "VFLIP" },
|
||||||
{ROTATION, "ROTATION" },
|
{ROTATION, "ROTATION" },
|
||||||
@@ -2404,6 +2405,102 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int msm_vidc_ts_reorder_insert_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
|
||||||
|
{
|
||||||
|
struct msm_vidc_timestamp *ts;
|
||||||
|
|
||||||
|
if (!inst) {
|
||||||
|
d_vpr_e("%s: Invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate ts from pool */
|
||||||
|
ts = msm_memory_alloc(inst, MSM_MEM_POOL_TIMESTAMP);
|
||||||
|
if (!ts) {
|
||||||
|
i_vpr_e(inst, "%s: ts alloc failed\n", __func__);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize ts node */
|
||||||
|
INIT_LIST_HEAD(&ts->sort.list);
|
||||||
|
ts->sort.val = timestamp;
|
||||||
|
inst->ts_reorder.count++;
|
||||||
|
list_add_tail(&ts->sort.list, &inst->ts_reorder.list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_vidc_ts_reorder_remove_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
|
||||||
|
{
|
||||||
|
struct msm_vidc_timestamp *ts, *temp;
|
||||||
|
|
||||||
|
if (!inst) {
|
||||||
|
d_vpr_e("%s: Invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove matching node */
|
||||||
|
list_for_each_entry_safe(ts, temp, &inst->ts_reorder.list, sort.list) {
|
||||||
|
if (ts->sort.val == timestamp) {
|
||||||
|
list_del_init(&ts->sort.list);
|
||||||
|
inst->ts_reorder.count--;
|
||||||
|
msm_memory_free(inst, ts);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_vidc_ts_reorder_get_first_timestamp(struct msm_vidc_inst *inst, u64 *timestamp)
|
||||||
|
{
|
||||||
|
struct msm_vidc_timestamp *ts;
|
||||||
|
|
||||||
|
if (!inst || !timestamp) {
|
||||||
|
d_vpr_e("%s: Invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if list empty */
|
||||||
|
if (list_empty(&inst->ts_reorder.list)) {
|
||||||
|
i_vpr_e(inst, "%s: list empty. ts %lld\n", __func__, timestamp);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get 1st node from reorder list */
|
||||||
|
ts = list_first_entry(&inst->ts_reorder.list,
|
||||||
|
struct msm_vidc_timestamp, sort.list);
|
||||||
|
list_del_init(&ts->sort.list);
|
||||||
|
|
||||||
|
/* copy timestamp */
|
||||||
|
*timestamp = ts->sort.val;
|
||||||
|
|
||||||
|
inst->ts_reorder.count--;
|
||||||
|
msm_memory_free(inst, ts);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_vidc_ts_reorder_flush(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
struct msm_vidc_timestamp *temp, *ts = NULL;
|
||||||
|
|
||||||
|
if (!inst) {
|
||||||
|
d_vpr_e("%s: Invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flush all entries */
|
||||||
|
list_for_each_entry_safe(ts, temp, &inst->ts_reorder.list, sort.list) {
|
||||||
|
i_vpr_l(inst, "%s: flushing ts: val %lld\n", __func__, ts->sort.val);
|
||||||
|
list_del(&ts->sort.list);
|
||||||
|
msm_memory_free(inst, ts);
|
||||||
|
}
|
||||||
|
inst->ts_reorder.count = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int msm_vidc_get_delayed_unmap(struct msm_vidc_inst *inst, struct msm_vidc_map *map)
|
int msm_vidc_get_delayed_unmap(struct msm_vidc_inst *inst, struct msm_vidc_map *map)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -3094,6 +3191,13 @@ static int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buf
|
|||||||
meta->attr |= MSM_VIDC_ATTR_QUEUED;
|
meta->attr |= MSM_VIDC_ATTR_QUEUED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* insert timestamp for ts_reorder enable case */
|
||||||
|
if (is_ts_reorder_allowed(inst) && is_input_buffer(buf->type)) {
|
||||||
|
rc = msm_vidc_ts_reorder_insert_timestamp(inst, buf->timestamp);
|
||||||
|
if (rc)
|
||||||
|
i_vpr_e(inst, "%s: insert timestamp failed\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_input_buffer(buf->type))
|
if (is_input_buffer(buf->type))
|
||||||
inst->power.buffer_counter++;
|
inst->power.buffer_counter++;
|
||||||
|
|
||||||
@@ -5019,6 +5123,13 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
|
|||||||
msm_memory_free(inst, ts);
|
msm_memory_free(inst, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(ts, dummy_ts, &inst->ts_reorder.list, sort.list) {
|
||||||
|
i_vpr_e(inst, "%s: removing reorder ts: val %lld\n",
|
||||||
|
__func__, ts->sort.val);
|
||||||
|
list_del(&ts->sort.list);
|
||||||
|
msm_memory_free(inst, ts);
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(dbuf, dummy_dbuf, &inst->dmabuf_tracker, list) {
|
list_for_each_entry_safe(dbuf, dummy_dbuf, &inst->dmabuf_tracker, list) {
|
||||||
i_vpr_e(inst, "%s: removing dma_buf %#x, refcount %u\n",
|
i_vpr_e(inst, "%s: removing dma_buf %#x, refcount %u\n",
|
||||||
__func__, dbuf->dmabuf, dbuf->refcount);
|
__func__, dbuf->dmabuf, dbuf->refcount);
|
||||||
|
@@ -755,6 +755,13 @@ static int handle_input_buffer(struct msm_vidc_inst *inst,
|
|||||||
buf->flags = 0;
|
buf->flags = 0;
|
||||||
buf->flags = get_driver_buffer_flags(inst, buffer->flags);
|
buf->flags = get_driver_buffer_flags(inst, buffer->flags);
|
||||||
|
|
||||||
|
/* handle ts_reorder for no_output prop attached input buffer */
|
||||||
|
if (is_ts_reorder_allowed(inst) && inst->hfi_frame_info.no_output) {
|
||||||
|
i_vpr_h(inst, "%s: received no_output buffer. remove timestamp %lld\n",
|
||||||
|
__func__, buf->timestamp);
|
||||||
|
msm_vidc_ts_reorder_remove_timestamp(inst, buf->timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
print_vidc_buffer(VIDC_HIGH, "high", "dqbuf", inst, buf);
|
print_vidc_buffer(VIDC_HIGH, "high", "dqbuf", inst, buf);
|
||||||
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_EBD);
|
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_EBD);
|
||||||
|
|
||||||
@@ -886,6 +893,10 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
|||||||
if (!is_image_session(inst) && is_decode_session(inst) && buf->data_size)
|
if (!is_image_session(inst) && is_decode_session(inst) && buf->data_size)
|
||||||
msm_vidc_update_timestamp(inst, buf->timestamp);
|
msm_vidc_update_timestamp(inst, buf->timestamp);
|
||||||
|
|
||||||
|
/* update output buffer timestamp, if ts_reorder is enabled */
|
||||||
|
if (is_ts_reorder_allowed(inst) && buf->data_size)
|
||||||
|
msm_vidc_ts_reorder_get_first_timestamp(inst, &buf->timestamp);
|
||||||
|
|
||||||
print_vidc_buffer(VIDC_HIGH, "high", "dqbuf", inst, buf);
|
print_vidc_buffer(VIDC_HIGH, "high", "dqbuf", inst, buf);
|
||||||
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_FBD);
|
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_FBD);
|
||||||
|
|
||||||
|
@@ -189,6 +189,8 @@ enum v4l2_mpeg_video_av1_tier {
|
|||||||
V4L2_MPEG_VIDEO_AV1_TIER_MAIN = 0,
|
V4L2_MPEG_VIDEO_AV1_TIER_MAIN = 0,
|
||||||
V4L2_MPEG_VIDEO_AV1_TIER_HIGH = 1,
|
V4L2_MPEG_VIDEO_AV1_TIER_HIGH = 1,
|
||||||
};
|
};
|
||||||
|
/* Decoder Timestamp Reorder control */
|
||||||
|
#define V4L2_CID_MPEG_VIDC_TS_REORDER (V4L2_CID_MPEG_VIDC_BASE + 0x34)
|
||||||
|
|
||||||
/* Deprecate below controls once availble in gki and gsi bionic header */
|
/* Deprecate below controls once availble in gki and gsi bionic header */
|
||||||
#ifndef V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID
|
#ifndef V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID
|
||||||
|
在新工单中引用
屏蔽一个用户