From 1e55de3d4ae5c0b331ebaf08f7548c8d236094cd Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 9 Dec 2021 15:41:45 +0530 Subject: [PATCH] video: driver: add support for timestamp reorder Added support for timestamp reorder. It is default disabled. Change-Id: I51a6fc785860081b651fc67f443132cb2675b9fd Signed-off-by: Govindaraj Rajagopal --- driver/platform/diwali/src/msm_vidc_diwali.c | 5 + driver/platform/waipio/src/msm_vidc_waipio.c | 5 + driver/vidc/inc/msm_vidc_driver.h | 10 ++ driver/vidc/inc/msm_vidc_inst.h | 1 + driver/vidc/inc/msm_vidc_internal.h | 1 + driver/vidc/src/msm_vdec.c | 4 + driver/vidc/src/msm_vidc.c | 1 + driver/vidc/src/msm_vidc_driver.c | 111 ++++++++++++++++++ driver/vidc/src/venus_hfi_response.c | 11 ++ .../uapi/vidc/media/v4l2_vidc_extensions.h | 2 + 10 files changed, 151 insertions(+) diff --git a/driver/platform/diwali/src/msm_vidc_diwali.c b/driver/platform/diwali/src/msm_vidc_diwali.c index dee054a645..b912fda01b 100644 --- a/driver/platform/diwali/src/msm_vidc_diwali.c +++ b/driver/platform/diwali/src/msm_vidc_diwali.c @@ -381,6 +381,11 @@ static struct msm_platform_inst_capability instance_data_diwali_v0[] = { {0}, 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, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE, diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index b00ae7eafa..aa1d545763 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -262,6 +262,11 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { {0}, 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, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE, diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index db2322d171..572de0f39e 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -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; } +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) { 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_calc_window_avg_framerate(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); void msm_vidc_free_capabililty_list(struct msm_vidc_inst *inst, enum msm_vidc_ctrl_list_type list_type); diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index b18727c21f..7ed3096e03 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -118,6 +118,7 @@ struct msm_vidc_inst { struct msm_vidc_mappings_info mappings; struct msm_vidc_allocations_info allocations; struct msm_vidc_timestamps timestamps; + struct msm_vidc_timestamps ts_reorder; /* list of struct msm_vidc_timestamp */ bool subscribed_input_psc; bool subscribed_output_psc; bool subscribed_input_prop; diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index ef93c33351..b152ba2a43 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -363,6 +363,7 @@ enum msm_vidc_inst_capability_type { MB_CYCLES_FW, MB_CYCLES_FW_VPP, SECURE_MODE, + TS_REORDER, HFLIP, VFLIP, ROTATION, diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index 23ef1cd286..0cebe69d1b 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -1610,6 +1610,10 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst) if (rc) goto error; + rc = msm_vidc_ts_reorder_flush(inst); + if (rc) + goto error; + return 0; error: diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index d25e812415..0223d0d9d8 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -840,6 +840,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) } INIT_LIST_HEAD(&inst->response_works); 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_meta.list); INIT_LIST_HEAD(&inst->buffers.output.list); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index c0a6c68f23..50c9db53d2 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -81,6 +81,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = { {MB_CYCLES_FW, "MB_CYCLES_FW" }, {MB_CYCLES_FW_VPP, "MB_CYCLES_FW_VPP" }, {SECURE_MODE, "SECURE_MODE" }, + {TS_REORDER, "TS_REORDER" }, {HFLIP, "HFLIP" }, {VFLIP, "VFLIP" }, {ROTATION, "ROTATION" }, @@ -2404,6 +2405,102 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp) 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 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; } + /* 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)) inst->power.buffer_counter++; @@ -5019,6 +5123,13 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst) 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) { i_vpr_e(inst, "%s: removing dma_buf %#x, refcount %u\n", __func__, dbuf->dmabuf, dbuf->refcount); diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index 6dbadc76d3..e7aa6a32c7 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -755,6 +755,13 @@ static int handle_input_buffer(struct msm_vidc_inst *inst, buf->flags = 0; 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); 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) 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); msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_FBD); diff --git a/include/uapi/vidc/media/v4l2_vidc_extensions.h b/include/uapi/vidc/media/v4l2_vidc_extensions.h index 36f4785168..6a6b0858b5 100644 --- a/include/uapi/vidc/media/v4l2_vidc_extensions.h +++ b/include/uapi/vidc/media/v4l2_vidc_extensions.h @@ -189,6 +189,8 @@ enum v4l2_mpeg_video_av1_tier { V4L2_MPEG_VIDEO_AV1_TIER_MAIN = 0, 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 */ #ifndef V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID