From 86cdac94b77b9188884c4f2277ae439d3d506b25 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 30 Mar 2020 15:38:58 -0700 Subject: [PATCH] msm: vidc: enable timestamp reorder Enable timestamp reordering by using the calculated timestamps maintained in a sorted order and associate with output buffers. This would resolve the issue if the parser sends incorect timestamps. Change-Id: I870fd8ed25e05b8e86c677e79182e9c7785656a8 Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc.c | 10 +---- msm/vidc/msm_vidc_common.c | 85 ++++++++++++++++++++++++------------ msm/vidc/msm_vidc_common.h | 4 +- msm/vidc/msm_vidc_internal.h | 1 + 4 files changed, 63 insertions(+), 37 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 60fadec7452d..d05f29cf3b63 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -454,7 +454,6 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; - u64 timestamp_us = 0; if (!inst || !b || !valid_v4l2_buffer(b, inst)) { d_vpr_e("%s: invalid params, %pK %pK\n", @@ -495,13 +494,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } } - if (is_decode_session(inst) && b->type == OUTPUT_MPLANE) { - timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + - b->timestamp.tv_usec); - b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = DEFAULT_FPS << 16; - msm_comm_fetch_framerate(inst, timestamp_us, - &b->m.planes[0].reserved[MSM_VIDC_FRAMERATE]); - } + if (is_decode_session(inst) && b->type == OUTPUT_MPLANE) + msm_comm_fetch_ts_framerate(inst, b); return rc; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index aa0c47d323cd..30ce2038098c 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7188,6 +7188,7 @@ void msm_comm_release_timestamps(struct msm_vidc_inst *inst) int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) { struct msm_vidc_timestamps *entry, *node, *prev = NULL; + struct msm_vidc_timestamps *duplicate; int count = 0; int rc = 0; bool inserted = false; @@ -7199,22 +7200,25 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) } mutex_lock(&inst->timestamps.lock); + duplicate = NULL; list_for_each_entry(node, &inst->timestamps.list, list) { count++; - /* Skip adding duplicate entries */ - if (node->timestamp_us == timestamp_us) { - s_vpr_e(inst->sid, "%s: skip ts duplicate entry %lld\n", - __func__, node->timestamp_us); - goto unlock; - } + if (node->timestamp_us == timestamp_us) + duplicate = node; } - /* Maintain a sliding window of size 32 */ + /* Maintain a sliding window of size 64 */ entry = NULL; - if (count >= TIMESTAMPS_WINDOW_SIZE) { + if (count >= VIDEO_MAX_FRAME) { entry = list_first_entry(&inst->timestamps.list, struct msm_vidc_timestamps, list); - list_del_init(&entry->list); + if (!entry->is_valid) { + list_del_init(&entry->list); + } else { + s_vpr_e(inst->sid, "%s: first entry still valid %d\n", + __func__, count); + entry = NULL; + } } if (!entry) { entry = kzalloc(sizeof(*entry), GFP_KERNEL); @@ -7225,8 +7229,18 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) goto unlock; } } + + if (duplicate) { + entry->timestamp_us = duplicate->timestamp_us; + entry->framerate = duplicate->framerate; + entry->is_valid = true; + /* add entry next to duplicate */ + list_add(&entry->list, &duplicate->list); + goto unlock; + } entry->timestamp_us = timestamp_us; entry->framerate = DEFAULT_FPS << 16; + entry->is_valid = true; /* add new entry into the list in sorted order */ prev = NULL; @@ -7247,7 +7261,6 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) prev = node; } - /* inserted will be false if list is empty */ if (!inserted) list_add_tail(&entry->list, &inst->timestamps.list); @@ -7311,36 +7324,54 @@ u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst) return max_framerate; } -int msm_comm_fetch_framerate(struct msm_vidc_inst *inst, - u64 timestamp_us, u32 *framerate) +int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, + struct v4l2_buffer *b) { struct msm_vidc_timestamps *node; - bool found_fps = false; - u32 count = 0; int rc = 0; + bool invalidate_extra = false; + u32 input_tag = 0, input_tag2 = 0; - if (!inst || !framerate) { + if (!inst || !b) { d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } + input_tag = b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1]; + input_tag2 = b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2]; + + /* nothing to do for flushed buffers */ + if (!input_tag) + return 0; + + /* set default framerate */ + b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = DEFAULT_FPS << 16; + + /* to handle interlace, 2 input buffers and 1 output buffer*/ + if (input_tag2 && input_tag2 != input_tag) + invalidate_extra = true; + mutex_lock(&inst->timestamps.lock); list_for_each_entry(node, &inst->timestamps.list, list) { - count++; - if (timestamp_us == node->timestamp_us) { - *framerate = node->framerate; - found_fps = true; - break; + if (!node->is_valid) + continue; + + if (invalidate_extra) { + node->is_valid = false; + invalidate_extra = false; + continue; } + + /* do not update is_valid flag for subframe buffer */ + if (!(b->flags & HAL_BUFFERFLAG_ENDOFSUBFRAME)) + node->is_valid = false; + + b->timestamp.tv_sec = node->timestamp_us / 1000000ull; + b->timestamp.tv_usec = node->timestamp_us % 1000000ull; + b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = node->framerate; + break; } mutex_unlock(&inst->timestamps.lock); - - if (!found_fps) { - if (!inst->flush_timestamps) - s_vpr_e(inst->sid, "%s:ts %lld not found,listsize %d\n", - __func__, timestamp_us, count); - rc = -EINVAL; - } return rc; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 234d0c58be95..22c9666caa16 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -332,9 +332,9 @@ void msm_comm_clear_window_data(struct msm_vidc_inst *inst); void msm_comm_release_window_data(struct msm_vidc_inst *inst); int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, uint32_t capture_rate, uint32_t cvp_rate); +int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, + struct v4l2_buffer *b); int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us); -int msm_comm_fetch_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, - u32 *framerate); void msm_comm_release_timestamps(struct msm_vidc_inst *inst); u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst); u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 1ecea42a6521..caba423c583f 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -236,6 +236,7 @@ struct msm_vidc_timestamps { struct list_head list; u64 timestamp_us; u32 framerate; + bool is_valid; }; enum efuse_purpose {