aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanimir Varbanov <stanimir.varbanov@linaro.org>2019-06-27 12:59:11 -0300
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-08-05 10:57:51 -0300
commitd42974e438feebda372fe4a39d7761cc596abc57 (patch)
tree4db9b340f272811f950955bec6ca4ec96fd500d5
parent059790467bf4a75441615c69e5efd2b4bac3cba4 (diff)
media: venus: dec: populate properly timestamps and flags for capture buffers
Cache flags, timestamps and timecode structure of OUTPUT buffers in per-instance structure array and fill correctly the same when the CAPTURE buffers are done. This will make v4l2-compliance decoder streaming test happy. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r--drivers/media/platform/qcom/venus/core.h9
-rw-r--r--drivers/media/platform/qcom/venus/helpers.c54
-rw-r--r--drivers/media/platform/qcom/venus/helpers.h2
-rw-r--r--drivers/media/platform/qcom/venus/vdec.c2
4 files changed, 67 insertions, 0 deletions
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 1a28ca07cd84..959eaa550f4e 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -220,6 +220,14 @@ enum venus_dec_state {
VENUS_DEC_STATE_DRC = 7
};
+struct venus_ts_metadata {
+ bool used;
+ u64 ts_ns;
+ u64 ts_us;
+ u32 flags;
+ struct v4l2_timecode tc;
+};
+
/**
* struct venus_inst - holds per instance parameters
*
@@ -304,6 +312,7 @@ struct venus_inst {
wait_queue_head_t reconf_wait;
unsigned int subscriptions;
int buf_count;
+ struct venus_ts_metadata tss[VIDEO_MAX_FRAME];
u64 fps;
struct v4l2_fract timeperframe;
const struct venus_format *fmt_out;
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index c948c4e809b5..1ad96c25ab09 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -463,6 +463,57 @@ static void return_buf_error(struct venus_inst *inst,
v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
}
+static void
+put_ts_metadata(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+ struct vb2_buffer *vb = &vbuf->vb2_buf;
+ unsigned int i;
+ int slot = -1;
+ u64 ts_us = vb->timestamp;
+
+ for (i = 0; i < ARRAY_SIZE(inst->tss); i++) {
+ if (!inst->tss[i].used) {
+ slot = i;
+ break;
+ }
+ }
+
+ if (slot == -1) {
+ dev_dbg(inst->core->dev, "%s: no free slot\n", __func__);
+ return;
+ }
+
+ do_div(ts_us, NSEC_PER_USEC);
+
+ inst->tss[slot].used = true;
+ inst->tss[slot].flags = vbuf->flags;
+ inst->tss[slot].tc = vbuf->timecode;
+ inst->tss[slot].ts_us = ts_us;
+ inst->tss[slot].ts_ns = vb->timestamp;
+}
+
+void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,
+ struct vb2_v4l2_buffer *vbuf)
+{
+ struct vb2_buffer *vb = &vbuf->vb2_buf;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) {
+ if (!inst->tss[i].used)
+ continue;
+
+ if (inst->tss[i].ts_us != timestamp_us)
+ continue;
+
+ inst->tss[i].used = false;
+ vbuf->flags |= inst->tss[i].flags;
+ vbuf->timecode = inst->tss[i].tc;
+ vb->timestamp = inst->tss[i].ts_ns;
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_ts_metadata);
+
static int
session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
{
@@ -487,6 +538,9 @@ session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len)
fdata.flags |= HFI_BUFFERFLAG_EOS;
+
+ if (inst->session_type == VIDC_SESSION_TYPE_DEC)
+ put_ts_metadata(inst, vbuf);
} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (inst->session_type == VIDC_SESSION_TYPE_ENC)
fdata.buffer_type = HFI_BUFFER_OUTPUT;
diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h
index 486598d52811..01f411b12f81 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -62,4 +62,6 @@ int venus_helper_unregister_bufs(struct venus_inst *inst);
int venus_helper_load_scale_clocks(struct venus_core *core);
int venus_helper_process_initial_cap_bufs(struct venus_inst *inst);
int venus_helper_process_initial_out_bufs(struct venus_inst *inst);
+void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,
+ struct vb2_v4l2_buffer *vbuf);
#endif
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 336d49132d19..0b7d65db5cdc 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1135,6 +1135,8 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
vbuf->sequence = inst->sequence_out++;
}
+ venus_helper_get_ts_metadata(inst, timestamp_us, vbuf);
+
if (hfi_flags & HFI_BUFFERFLAG_READONLY)
venus_helper_acquire_buf_ref(vbuf);