From patchwork Fri May 8 06:21:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dikshita Agarwal X-Patchwork-Id: 11535651 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BC17E15AB for ; Fri, 8 May 2020 06:22:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A2B3020870 for ; Fri, 8 May 2020 06:22:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726048AbgEHGWM (ORCPT ); Fri, 8 May 2020 02:22:12 -0400 Received: from alexa-out-blr-01.qualcomm.com ([103.229.18.197]:18276 "EHLO alexa-out-blr-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725897AbgEHGWL (ORCPT ); Fri, 8 May 2020 02:22:11 -0400 Received: from ironmsg01-blr.qualcomm.com ([10.86.208.130]) by alexa-out-blr-01.qualcomm.com with ESMTP/TLS/AES256-SHA; 08 May 2020 11:52:06 +0530 Received: from dikshita-linux.qualcomm.com ([10.204.65.237]) by ironmsg01-blr.qualcomm.com with ESMTP; 08 May 2020 11:51:54 +0530 Received: by dikshita-linux.qualcomm.com (Postfix, from userid 347544) id 030C03AD3; Fri, 8 May 2020 11:51:52 +0530 (IST) From: Dikshita Agarwal To: linux-media@vger.kernel.org, stanimir.varbanov@linaro.org Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, vgarodia@codeaurora.org, majja@codeaurora.org, jdas@codeaurora.org, Dikshita Agarwal Subject: [RFC PATCH 1/3] Register for media device Date: Fri, 8 May 2020 11:51:28 +0530 Message-Id: <1588918890-673-2-git-send-email-dikshita@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1588918890-673-1-git-send-email-dikshita@codeaurora.org> References: <1588918890-673-1-git-send-email-dikshita@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Change-Id: I5a9629d562ef80560361d777da79ff06c3e00131 Signed-off-by: Dikshita Agarwal --- drivers/media/platform/Kconfig | 2 +- drivers/media/platform/qcom/venus/core.h | 33 ++++++ drivers/media/platform/qcom/venus/helpers.c | 172 ++++++++++++++++++++++++++++ drivers/media/platform/qcom/venus/helpers.h | 15 +++ drivers/media/platform/qcom/venus/venc.c | 36 ++++++ 5 files changed, 257 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index ca3cb4f..a51f76e 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 + depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER 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 922cb7e..91ff08d 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -74,6 +74,37 @@ struct venus_caps { }; /** + * struct venus_media - per-device context + * @source: &struct media_entity pointer with the source entity + * Used only when the M2M device is registered via + * v4l2_m2m_unregister_media_controller(). + * @source_pad: &struct media_pad with the source pad. + * Used only when the M2M device is registered via + * v4l2_m2m_unregister_media_controller(). + * @sink: &struct media_entity pointer with the sink entity + * Used only when the M2M device is registered via + * v4l2_m2m_unregister_media_controller(). + * @sink_pad: &struct media_pad with the sink pad. + * Used only when the M2M device is registered via + * v4l2_m2m_unregister_media_controller(). + * @proc: &struct media_entity pointer with the M2M device itself. + * @proc_pads: &struct media_pad with the @proc pads. + * Used only when the M2M device is registered via + * v4l2_m2m_unregister_media_controller(). + * @intf_devnode: &struct media_intf devnode pointer with the interface + * with controls the M2M device. + */ +struct venus_media { + struct media_entity *source; + struct media_pad source_pad; + struct media_entity sink; + struct media_pad sink_pad; + struct media_entity proc; + struct media_pad proc_pads[2]; + struct media_intf_devnode *intf_devnode; +}; + +/** * struct venus_core - holds core parameters valid for all instances * * @base: IO memory base address @@ -118,6 +149,8 @@ struct venus_core { struct video_device *vdev_dec; struct video_device *vdev_enc; struct v4l2_device v4l2_dev; + struct media_device m_dev; + struct venus_media *media; const struct venus_resources *res; struct device *dev; struct device *dev_dec; diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 1ad96c2..2c766cd 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -1378,3 +1378,175 @@ int venus_helper_power_enable(struct venus_core *core, u32 session_type, return 0; } EXPORT_SYMBOL_GPL(venus_helper_power_enable); + +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) +{ + struct media_entity *entity; + struct media_pad *pads; + char *name; + unsigned int len; + int num_pads; + int ret; + + switch (type) { + case MEM2MEM_ENT_TYPE_SOURCE: + entity = media->source; + pads = &media->source_pad; + pads[0].flags = MEDIA_PAD_FL_SOURCE; + num_pads = 1; + break; + case MEM2MEM_ENT_TYPE_SINK: + entity = &media->sink; + pads = &media->sink_pad; + pads[0].flags = MEDIA_PAD_FL_SINK; + num_pads = 1; + break; + case MEM2MEM_ENT_TYPE_PROC: + entity = &media->proc; + pads = media->proc_pads; + pads[0].flags = MEDIA_PAD_FL_SINK; + pads[1].flags = MEDIA_PAD_FL_SOURCE; + num_pads = 2; + break; + default: + return -EINVAL; + } + + entity->obj_type = MEDIA_ENTITY_TYPE_BASE; + if (type != MEM2MEM_ENT_TYPE_PROC) { + entity->info.dev.major = VIDEO_MAJOR; + entity->info.dev.minor = vdev->minor; + } + len = strlen(vdev->name) + 2 + strlen(venus_helper_entity_name[type]); + name = kmalloc(len, GFP_KERNEL); + if (!name) + return -ENOMEM; + snprintf(name, len, "%s-%s", vdev->name, venus_helper_entity_name[type]); + entity->name = name; + entity->function = function; + + ret = media_entity_pads_init(entity, num_pads, pads); + if (ret) + return ret; + ret = media_device_register_entity(mdev, entity); + if (ret) + return ret; + + return 0; +} + +int venus_helper_register_media_controller(struct venus_media *media, + struct video_device *vdev, int function) +{ + struct media_device *mdev = vdev->v4l2_dev->mdev; + struct media_link *link; + int ret; + v4l2_err(vdev, "1.\n"); + if (!mdev) + return 0; + v4l2_err(vdev, "2.\n"); + /* A memory-to-memory device consists in two + * DMA engine and one video processing entities. + * The DMA engine entities are linked to a V4L interface + */ + + /* Create the three entities with their pads */ + media->source = &vdev->entity; + ret = venus_helper_register_entity(mdev, media, + MEM2MEM_ENT_TYPE_SOURCE, vdev, MEDIA_ENT_F_IO_V4L); + if (ret) { + v4l2_err(vdev, "3_error.\n"); + return ret; + } + v4l2_err(vdev, "3 pass.\n"); + ret = venus_helper_register_entity(mdev, media, + MEM2MEM_ENT_TYPE_PROC, vdev, function); + if (ret){ + v4l2_err(vdev, "4 error.\n"); + goto err_rel_entity0; + } + v4l2_err(vdev, "4 pass.\n"); + ret = venus_helper_register_entity(mdev, media, + MEM2MEM_ENT_TYPE_SINK, vdev, MEDIA_ENT_F_IO_V4L); + if (ret) + goto err_rel_entity1; + v4l2_err(vdev, "5 pass.\n"); + /* Connect the three entities */ + ret = media_create_pad_link(media->source, 0, &media->proc, 1, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (ret) + goto err_rel_entity2; + v4l2_err(vdev, "6 pass.\n"); + ret = media_create_pad_link(&media->proc, 0, &media->sink, 0, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (ret) + goto err_rm_links0; + v4l2_err(vdev, "7 pass.\n"); + /* Create video interface */ + media->intf_devnode = media_devnode_create(mdev, + MEDIA_INTF_T_V4L_VIDEO, 0, + VIDEO_MAJOR, vdev->minor); + if (!media->intf_devnode) { + ret = -ENOMEM; + goto err_rm_links1; + } + v4l2_err(vdev, "8 pass.\n"); + /* Connect the two DMA engines to the interface */ + link = media_create_intf_link(media->source, + &media->intf_devnode->intf, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (!link) { + ret = -ENOMEM; + goto err_rm_devnode; + } + + link = media_create_intf_link(&media->sink, + &media->intf_devnode->intf, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (!link) { + ret = -ENOMEM; + goto err_rm_intf_link; + } + return 0; + +err_rm_intf_link: + media_remove_intf_links(&media->intf_devnode->intf); +err_rm_devnode: + media_devnode_remove(media->intf_devnode); +err_rm_links1: + media_entity_remove_links(&media->sink); +err_rm_links0: + media_entity_remove_links(&media->proc); + media_entity_remove_links(media->source); +err_rel_entity2: + media_device_unregister_entity(&media->proc); + kfree(media->proc.name); +err_rel_entity1: + media_device_unregister_entity(&media->sink); + kfree(media->sink.name); +err_rel_entity0: + media_device_unregister_entity(media->source); + kfree(media->source->name); + return ret; + return 0; +} +EXPORT_SYMBOL_GPL(venus_helper_register_media_controller); + +void venus_helper_unregister_media_controller(struct venus_media *media) +{ + media_remove_intf_links(&media->intf_devnode->intf); + media_devnode_remove(media->intf_devnode); + + media_entity_remove_links(media->source); + media_entity_remove_links(&media->sink); + media_entity_remove_links(&media->proc); + media_device_unregister_entity(media->source); + media_device_unregister_entity(&media->sink); + media_device_unregister_entity(&media->proc); + kfree(media->source->name); + kfree(media->sink.name); + kfree(media->proc.name); +} +EXPORT_SYMBOL_GPL(venus_helper_unregister_media_controller); diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 01f411b..ca4db82 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -11,6 +11,18 @@ struct venus_inst; struct venus_core; +enum venus_helper_entity_type { + MEM2MEM_ENT_TYPE_SOURCE, + MEM2MEM_ENT_TYPE_SINK, + MEM2MEM_ENT_TYPE_PROC +}; + +static const char * const venus_helper_entity_name[] = { + "source", + "sink", + "proc" +}; + bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt); struct vb2_v4l2_buffer *venus_helper_find_buf(struct venus_inst *inst, unsigned int type, u32 idx); @@ -64,4 +76,7 @@ int venus_helper_power_enable(struct venus_core *core, u32 session_type, 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); +int venus_helper_register_media_controller(struct venus_media *media, + struct video_device *vdev, int function); +void venus_helper_unregister_media_controller(struct venus_media *media); #endif diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 30028ce..f57542f 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -22,6 +22,17 @@ #include "venc.h" #define NUM_B_FRAMES_MAX 4 +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device mdev; +#endif +static int venc_request_validate(struct media_request *req) +{ + return vb2_request_validate(req); +} +static const struct media_device_ops venus_m2m_media_ops = { + .req_validate = venc_request_validate, + .req_queue = v4l2_m2m_request_queue, +}; /* * Three resons to keep MPLANE formats (despite that the number of planes @@ -1287,8 +1298,33 @@ static int venc_probe(struct platform_device *pdev) video_set_drvdata(vdev, core); pm_runtime_enable(dev); +#ifdef CONFIG_MEDIA_CONTROLLER + core->m_dev.dev = &pdev->dev; + strscpy(core->m_dev.model, "media_enc", sizeof(core->m_dev.model)); + media_device_init(&core->m_dev); + core->m_dev.ops = &venus_m2m_media_ops; + core->v4l2_dev.mdev = &core->m_dev; + core->media = kzalloc(sizeof *core->media, GFP_KERNEL); + if (!core->media) + return ERR_PTR(-ENOMEM); + ret = venus_helper_register_media_controller(core->media, + core->vdev_enc, + MEDIA_ENT_F_PROC_VIDEO_ENCODER); + if (ret) { + v4l2_err(core->vdev_enc, "Failed to init mem2mem media controller for enc\n"); + goto err_vdev_release; + } + + ret = media_device_register(&core->m_dev); + if (ret) { + //v4l2_err(&core->m_dev, "Failed to register mem2mem media device\n"); + goto err_unreg_m2m; + } +#endif return 0; +err_unreg_m2m: + venus_helper_unregister_media_controller(core->media); err_vdev_release: video_device_release(vdev); return ret; From patchwork Fri May 8 06:21:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dikshita Agarwal X-Patchwork-Id: 11535665 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 157E11862 for ; Fri, 8 May 2020 06:23:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB16221655 for ; Fri, 8 May 2020 06:23:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726325AbgEHGXC (ORCPT ); Fri, 8 May 2020 02:23:02 -0400 Received: from alexa-out-blr-01.qualcomm.com ([103.229.18.197]:20314 "EHLO alexa-out-blr-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725897AbgEHGXC (ORCPT ); Fri, 8 May 2020 02:23:02 -0400 Received: from ironmsg01-blr.qualcomm.com ([10.86.208.130]) by alexa-out-blr-01.qualcomm.com with ESMTP/TLS/AES256-SHA; 08 May 2020 11:52:06 +0530 Received: from dikshita-linux.qualcomm.com ([10.204.65.237]) by ironmsg01-blr.qualcomm.com with ESMTP; 08 May 2020 11:51:55 +0530 Received: by dikshita-linux.qualcomm.com (Postfix, from userid 347544) id 670163AD3; Fri, 8 May 2020 11:51:54 +0530 (IST) From: Dikshita Agarwal To: linux-media@vger.kernel.org, stanimir.varbanov@linaro.org Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, vgarodia@codeaurora.org, majja@codeaurora.org, jdas@codeaurora.org, Dikshita Agarwal Subject: [RFC PATCH 2/3] Enable Request API for output buffers Date: Fri, 8 May 2020 11:51:29 +0530 Message-Id: <1588918890-673-3-git-send-email-dikshita@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1588918890-673-1-git-send-email-dikshita@codeaurora.org> References: <1588918890-673-1-git-send-email-dikshita@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Change-Id: Ic09179f503bf7d4bb41522fb70207728405cc7b3 Signed-off-by: Dikshita Agarwal --- 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 #include #include +#include +#include #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 #include #include +#include /* * 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 From patchwork Fri May 8 06:21:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dikshita Agarwal X-Patchwork-Id: 11535653 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1BBA592A for ; Fri, 8 May 2020 06:22:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0E26020870 for ; Fri, 8 May 2020 06:22:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727802AbgEHGWQ (ORCPT ); Fri, 8 May 2020 02:22:16 -0400 Received: from alexa-out-blr-01.qualcomm.com ([103.229.18.197]:18276 "EHLO alexa-out-blr-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727118AbgEHGWO (ORCPT ); Fri, 8 May 2020 02:22:14 -0400 Received: from ironmsg01-blr.qualcomm.com ([10.86.208.130]) by alexa-out-blr-01.qualcomm.com with ESMTP/TLS/AES256-SHA; 08 May 2020 11:52:06 +0530 Received: from dikshita-linux.qualcomm.com ([10.204.65.237]) by ironmsg01-blr.qualcomm.com with ESMTP; 08 May 2020 11:51:57 +0530 Received: by dikshita-linux.qualcomm.com (Postfix, from userid 347544) id 221CD3AD3; Fri, 8 May 2020 11:51:56 +0530 (IST) From: Dikshita Agarwal To: linux-media@vger.kernel.org, stanimir.varbanov@linaro.org Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, vgarodia@codeaurora.org, majja@codeaurora.org, jdas@codeaurora.org, Dikshita Agarwal Subject: [PATCH 3/3] Enable Request API for Capture Buffers Date: Fri, 8 May 2020 11:51:30 +0530 Message-Id: <1588918890-673-4-git-send-email-dikshita@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1588918890-673-1-git-send-email-dikshita@codeaurora.org> References: <1588918890-673-1-git-send-email-dikshita@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org - Removed restrictions from V4l2 Framework to allow request APIs on Capture buffers. Change-Id: I9ba37e948eed027344ba2ceb7eb1ff117793ae31 Signed-off-by: Dikshita Agarwal --- drivers/media/common/videobuf2/videobuf2-v4l2.c | 4 +--- drivers/media/platform/qcom/venus/helpers.c | 2 +- drivers/media/platform/qcom/venus/venc.c | 6 ++++-- drivers/media/v4l2-core/v4l2-mem2mem.c | 17 +++++++++++------ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 5a9ba38..00f6970 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -424,9 +424,7 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md * It's easy to forget this callback, but is it important to correctly * validate the 'field' value at QBUF time. */ - if (WARN_ON((q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || - q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && - !q->ops->buf_out_validate)) + if (WARN_ON(!q->ops->buf_out_validate)) return -EINVAL; if (b->request_fd < 0) { diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index c966c24..a27e9bf 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -609,7 +609,7 @@ 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) + if(req) { ret = v4l2_ctrl_request_setup(req, &inst->ctrl_handler); if (ret) diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 599cfae..10a07bc 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1085,8 +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); + //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); } @@ -1146,6 +1146,8 @@ 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->supports_requests = 1; + dst_vq->requires_requests = 1; dst_vq->lock = src_vq->lock; ret = vb2_queue_init(dst_vq); if (ret) { diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 19937dd..ffacb29 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -493,12 +493,12 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, int ret; vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); - if (!V4L2_TYPE_IS_OUTPUT(vq->type) && + /*if (!V4L2_TYPE_IS_OUTPUT(vq->type) && (buf->flags & V4L2_BUF_FLAG_REQUEST_FD)) { dprintk("%s: requests cannot be used with capture buffers\n", __func__); return -EPERM; - } + }*/ ret = vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf); if (!ret && !(buf->flags & V4L2_BUF_FLAG_IN_REQUEST)) v4l2_m2m_try_schedule(m2m_ctx); @@ -1019,10 +1019,15 @@ void v4l2_m2m_request_queue(struct media_request *req) if (vb2_request_object_is_buffer(obj)) { /* Sanity checks */ vb = container_of(obj, struct vb2_buffer, req_obj); - WARN_ON(!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)); - m2m_ctx_obj = container_of(vb->vb2_queue, - struct v4l2_m2m_ctx, - out_q_ctx.q); + //WARN_ON(!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)); + if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) + m2m_ctx_obj = container_of(vb->vb2_queue, + struct v4l2_m2m_ctx, + out_q_ctx.q); + else + m2m_ctx_obj = container_of(vb->vb2_queue, + struct v4l2_m2m_ctx, + cap_q_ctx.q); WARN_ON(m2m_ctx && m2m_ctx_obj != m2m_ctx); m2m_ctx = m2m_ctx_obj; }