media: venus: dec: populate properly timestamps and flags for capture buffers
authorStanimir Varbanov <stanimir.varbanov@linaro.org>
Thu, 27 Jun 2019 15:59:11 +0000 (12:59 -0300)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Mon, 5 Aug 2019 13:57:51 +0000 (10:57 -0300)
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>
drivers/media/platform/qcom/venus/core.h
drivers/media/platform/qcom/venus/helpers.c
drivers/media/platform/qcom/venus/helpers.h
drivers/media/platform/qcom/venus/vdec.c

index 1a28ca07cd845c43607b183beb6cc2cb2bd961ba..959eaa550f4e45beee4ab2bd821f30485048d9f8 100644 (file)
@@ -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;
index c948c4e809b58c633330c7030bd6fc9fb8d7089b..1ad96c25ab09a6243d958a1739e7184c52f5d33e 100644 (file)
@@ -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;
index 486598d52811787ad17988e32f44420a577852d1..01f411b12f813fc8d4ecacb6a75d1be92aabe081 100644 (file)
@@ -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
index 336d49132d19c134d9ca1f83a5de0924290eed27..0b7d65db5cdc3da9d4e891680540232e01f18f65 100644 (file)
@@ -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);