Change-Id: Ic09179f503bf7d4bb41522fb70207728405cc7b3
Signed-off-by: Dikshita Agarwal <diksh...@codeaurora.org>
---
 drivers/media/platform/Kconfig                 |  2 +-
 drivers/media/platform/qcom/venus/core.h       |  3 ++
 drivers/media/platform/qcom/venus/helpers.c    | 75 +++++++++++++++++++++++++-
 drivers/media/platform/qcom/venus/venc.c       | 25 ++++++++-
 drivers/media/platform/qcom/venus/venc_ctrls.c | 61 ++++++++++++++++++++-
 drivers/media/v4l2-core/v4l2-ctrls.c           | 10 ++++
 include/media/v4l2-ctrls.h                     |  1 +
 include/media/venus-ctrls.h                    | 22 ++++++++
 8 files changed, 195 insertions(+), 4 deletions(-)
 create mode 100644 include/media/venus-ctrls.h

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index a51f76e..064b57b 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -481,7 +481,7 @@ config VIDEO_TI_VPE_DEBUG
 
 config VIDEO_QCOM_VENUS
        tristate "Qualcomm Venus V4L2 encoder/decoder driver"
-       depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER
+       depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER && 
MEDIA_CONTROLLER_REQUEST_API
        depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
        select QCOM_MDT_LOADER if ARCH_QCOM
        select QCOM_SCM if ARCH_QCOM
diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 91ff08d..9535d33 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -11,6 +11,8 @@
 #include <media/videobuf2-v4l2.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
+#include <linux/time.h>
+#include <linux/timer.h>
 
 #include "hfi.h"
 
@@ -320,6 +322,7 @@ struct venus_ts_metadata {
 struct venus_inst {
        struct list_head list;
        struct mutex lock;
+       struct mutex req_lock;
        struct venus_core *core;
        struct list_head dpbbufs;
        struct list_head internalbufs;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 2c766cd..c966c24 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -27,6 +27,63 @@ struct intbuf {
        unsigned long attrs;
 };
 
+int venus_ctrl_request_process(struct media_request *req)
+{
+       struct v4l2_ext_control control;
+       struct v4l2_ext_controls controls;
+       int ret = 0;
+       //struct media_device mdev = inst->core->m_dev;
+
+       struct media_request_object *obj;
+       struct v4l2_ctrl_handler *parent_hdl, *hdl;
+       struct venus_inst *inst;
+       struct v4l2_ctrl *ctrl;
+       struct v4l2_ctrl_ref *ref;
+       unsigned int count;
+       list_for_each_entry(obj, &req->objects, list) {
+               struct vb2_buffer *vb;
+
+               if (vb2_request_object_is_buffer(obj)) {
+                       vb = container_of(obj, struct vb2_buffer, req_obj);
+                       inst = vb2_get_drv_priv(vb->vb2_queue);
+                       //struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
+                       break;
+               }
+       }
+
+       if (!inst) {
+               pr_debug("No buffer was provided with the request\n");
+               return -ENOENT;
+       }
+       struct video_device *vdev = inst->core->vdev_enc;
+       count = vb2_request_buffer_cnt(req);
+       if (!count) {
+               pr_debug("No buffer was provided with the request\n");
+               return -ENOENT;
+       } else if (count > 1) {
+               pr_debug("More than one buffer was provided with the 
request\n");
+               return -EINVAL;
+       }
+
+       parent_hdl = &inst->ctrl_handler;
+
+       hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl);
+       if (!hdl) {
+               pr_debug( "Missing control handler\n");
+               return -ENOENT;
+       }
+
+       ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl,
+                                              
V4L2_CID_MPEG_VIDEO_VENUS_METADATA);
+
+       pr_debug("venus_ctrl_request_process ctrl id %d index 
%d",ctrl->id,ctrl->p_new.p_metadata->index);
+       return ret;
+}
+
+static int venus_helper_register_entity(struct media_device *mdev,
+       struct venus_media *media, enum venus_helper_entity_type type,
+       struct video_device *vdev, int function);
+
 bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt)
 {
        struct venus_core *core = inst->core;
@@ -522,7 +579,10 @@ void venus_helper_get_ts_metadata(struct venus_inst *inst, 
u64 timestamp_us,
        unsigned int type = vb->type;
        struct hfi_frame_data fdata;
        int ret;
-
+       struct media_request *req;
+       u64 ts,ts_ms;
+       struct timespec tv;
+       req = vb->req_obj.req;
        memset(&fdata, 0, sizeof(fdata));
        fdata.alloc_len = buf->size;
        fdata.device_addr = buf->dma_addr;
@@ -549,7 +609,20 @@ void venus_helper_get_ts_metadata(struct venus_inst *inst, 
u64 timestamp_us,
                fdata.filled_len = 0;
                fdata.offset = 0;
        }
+       if(req && type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+       {
+               ret = v4l2_ctrl_request_setup(req, &inst->ctrl_handler);
+               if (ret)
+                       pr_debug("v4l2_ctrl_request_setup retunred error");
+               ret = venus_ctrl_request_process(req);
+       }
 
+       pr_debug("buf type %d buf index 
%d",fdata.buffer_type,vbuf->vb2_buf.index);
+       if(type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               getnstimeofday(&tv);
+               ts = (tv.tv_sec * 1000000) + (tv.tv_nsec / 1000);
+               pr_debug("ETB: BUF %d queued at tv sec %ld ts ns %ld ts usec 
%lld",vbuf->vb2_buf.index,tv.tv_sec,tv.tv_nsec,ts);
+       }
        ret = hfi_session_process_buf(inst, &fdata);
        if (ret)
                return ret;
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index f57542f..599cfae 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -1031,6 +1031,21 @@ static int venc_start_streaming(struct vb2_queue *q, 
unsigned int count)
        return ret;
 }
 
+static int venc_buf_out_validate(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+       vbuf->field = V4L2_FIELD_NONE;
+       return 0;
+}
+
+static void venc_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &inst->ctrl_handler);
+}
+
 static const struct vb2_ops venc_vb2_ops = {
        .queue_setup = venc_queue_setup,
        .buf_init = venus_helper_vb2_buf_init,
@@ -1038,6 +1053,8 @@ static int venc_start_streaming(struct vb2_queue *q, 
unsigned int count)
        .start_streaming = venc_start_streaming,
        .stop_streaming = venus_helper_vb2_stop_streaming,
        .buf_queue = venus_helper_vb2_buf_queue,
+       .buf_out_validate       = venc_buf_out_validate,
+       .buf_request_complete   = venc_buf_request_complete,
 };
 
 static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type,
@@ -1068,7 +1085,8 @@ static void venc_buf_done(struct venus_inst *inst, 
unsigned int buf_type,
        } else {
                vbuf->sequence = inst->sequence_out++;
        }
-
+       if (buf_type == HFI_BUFFER_INPUT)
+               v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, 
&inst->ctrl_handler);
        v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
 }
 
@@ -1109,6 +1127,9 @@ static int m2m_queue_init(void *priv, struct vb2_queue 
*src_vq,
        src_vq->allow_zero_bytesused = 1;
        src_vq->min_buffers_needed = 1;
        src_vq->dev = inst->core->dev;
+       src_vq->supports_requests = 1;
+       src_vq->requires_requests = 1;
+       src_vq->lock = &inst->req_lock;
        if (inst->core->res->hfi_version == HFI_VERSION_1XX)
                src_vq->bidirectional = 1;
        ret = vb2_queue_init(src_vq);
@@ -1125,6 +1146,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue 
*src_vq,
        dst_vq->allow_zero_bytesused = 1;
        dst_vq->min_buffers_needed = 1;
        dst_vq->dev = inst->core->dev;
+       dst_vq->lock = src_vq->lock;
        ret = vb2_queue_init(dst_vq);
        if (ret) {
                vb2_queue_release(src_vq);
@@ -1163,6 +1185,7 @@ static int venc_open(struct file *file)
        INIT_LIST_HEAD(&inst->internalbufs);
        INIT_LIST_HEAD(&inst->list);
        mutex_init(&inst->lock);
+       mutex_init(&inst->req_lock);
 
        inst->core = core;
        inst->session_type = VIDC_SESSION_TYPE_ENC;
diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c 
b/drivers/media/platform/qcom/venus/venc_ctrls.c
index 877c0b3..02921b5 100644
--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
+++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
@@ -199,6 +199,12 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
                }
                mutex_unlock(&inst->lock);
                break;
+       case V4L2_CID_MPEG_VIDEO_VENUS_METADATA: {
+               unsigned int i;
+               const struct v4l2_ctrl_venus_metadata *metadata = 
ctrl->p_new.p_metadata;
+               pr_debug("%s: VENUS_METADATA p_new set index %d \n", 
__func__,metadata->index);
+               break;
+               }
        default:
                return -EINVAL;
        }
@@ -206,15 +212,66 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
        return 0;
 }
 
+static int venc_op_try_ctrl(struct v4l2_ctrl *ctrl)
+{
+       switch (ctrl->id) {
+       case V4L2_CID_MPEG_VIDEO_VENUS_METADATA: {
+               break;
+       }
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+static void meta_type_init(const struct v4l2_ctrl *ctrl, u32 idx,
+                          union v4l2_ctrl_ptr ptr)
+{
+}
+
+static bool meta_type_equal(const struct v4l2_ctrl *ctrl, u32 idx,
+                           union v4l2_ctrl_ptr ptr1,
+                           union v4l2_ctrl_ptr ptr2)
+{
+       return true;
+}
+
+static void meta_type_log(const struct v4l2_ctrl *ctrl)
+{
+}
+
+static int meta_type_validate(const struct v4l2_ctrl *ctrl, u32 idx,
+                             union v4l2_ctrl_ptr ptr)
+{
+       return 0;
+}
+
 static const struct v4l2_ctrl_ops venc_ctrl_ops = {
        .s_ctrl = venc_op_s_ctrl,
+       .try_ctrl = venc_op_try_ctrl,
+};
+
+static const struct v4l2_ctrl_type_ops venus_meta_type_ops = {
+       .equal = meta_type_equal,
+       .init = meta_type_init,
+       .log = meta_type_log,
+       .validate = meta_type_validate,
+};
+
+static const struct v4l2_ctrl_config venus_meta_cfg = {
+       .name = "Venus codec metadata",
+       .type = V4L2_CTRL_TYPE_VENUS_METADATA,
+       .ops = &venc_ctrl_ops,
+       .id = V4L2_CID_MPEG_VIDEO_VENUS_METADATA,
+       .flags = V4L2_CTRL_FLAG_EXECUTE_ON_WRITE,
+       .elem_size = sizeof(struct v4l2_ctrl_venus_metadata),
+       .type_ops = &venus_meta_type_ops,
 };
 
 int venc_ctrl_init(struct venus_inst *inst)
 {
        int ret;
 
-       ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 30);
+       ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 30+1);
        if (ret)
                return ret;
 
@@ -351,6 +408,8 @@ int venc_ctrl_init(struct venus_inst *inst)
        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
                          V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
 
+       v4l2_ctrl_new_custom(&inst->ctrl_handler, &venus_meta_cfg, NULL);
+
        ret = inst->ctrl_handler.error;
        if (ret)
                goto err;
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index cd84dbb..9f7f024 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -892,6 +892,7 @@ const char *v4l2_ctrl_get_name(u32 id)
        case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:            return "MPEG-2 
Slice Parameters";
        case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION:            return "MPEG-2 
Quantization Matrices";
        case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:                   return "FWHT 
Stateless Parameters";
+       case V4L2_CID_MPEG_VIDEO_VENUS_METADATA:                return "Venus 
codec metadata";
        case V4L2_CID_FWHT_I_FRAME_QP:                          return "FWHT 
I-Frame QP Value";
        case V4L2_CID_FWHT_P_FRAME_QP:                          return "FWHT 
P-Frame QP Value";
 
@@ -1357,6 +1358,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum 
v4l2_ctrl_type *type,
        case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
                *type = V4L2_CTRL_TYPE_FWHT_PARAMS;
                break;
+       case V4L2_CID_MPEG_VIDEO_VENUS_METADATA:
+               *type = V4L2_CTRL_TYPE_VENUS_METADATA;
+               break;
        case V4L2_CID_MPEG_VIDEO_H264_SPS:
                *type = V4L2_CTRL_TYPE_H264_SPS;
                break;
@@ -1820,6 +1824,9 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 
idx,
                        return -ERANGE;
                return 0;
 
+       case V4L2_CTRL_TYPE_VENUS_METADATA:
+               return 0;
+               
        default:
                return std_validate_compound(ctrl, idx, ptr);
        }
@@ -2403,6 +2410,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct 
v4l2_ctrl_handler *hdl,
        case V4L2_CTRL_TYPE_FWHT_PARAMS:
                elem_size = sizeof(struct v4l2_ctrl_fwht_params);
                break;
+       case V4L2_CTRL_TYPE_VENUS_METADATA:
+               elem_size = sizeof(struct v4l2_ctrl_venus_metadata);
+               break;
        case V4L2_CTRL_TYPE_H264_SPS:
                elem_size = sizeof(struct v4l2_ctrl_h264_sps);
                break;
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 570ff4b..c66b797 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -12,6 +12,7 @@
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
 #include <media/media-request.h>
+#include <media/venus-ctrls.h>
 
 /*
  * Include the stateless codec compound control definitions.
diff --git a/include/media/venus-ctrls.h b/include/media/venus-ctrls.h
new file mode 100644
index 0000000..9179ef0
--- /dev/null
+++ b/include/media/venus-ctrls.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+Copyright (c) 2020, The Linux Foundation. All rights reserved. */
+/*
+ * These are custom (compound) controls for Venus codec driver.
+ *
+ * It turns out that these structs are not stable yet and will undergo
+ * more changes. So keep them private until they are stable and ready to
+ * become part of the official public API.
+ */
+
+#ifndef _VENUS_CTRLS_H_
+#define _VENUS_CTRLS_H_
+
+#define V4L2_CTRL_TYPE_VENUS_METADATA          0x0107
+#define V4L2_CID_MPEG_VIDEO_VENUS_METADATA     (V4L2_CID_MPEG_BASE + 293)
+
+struct v4l2_ctrl_venus_metadata {
+       unsigned int index;
+//     __u8 rawdata[16];
+};
+
+#endif
\ No newline at end of file
-- 
1.9.1

Reply via email to