From patchwork Fri May 6 10:53:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 9031731 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0D100BF29F for ; Fri, 6 May 2016 10:56:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E3D5B20390 for ; Fri, 6 May 2016 10:56:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BE19F20389 for ; Fri, 6 May 2016 10:56:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758277AbcEFK4o (ORCPT ); Fri, 6 May 2016 06:56:44 -0400 Received: from mga14.intel.com ([192.55.52.115]:1297 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758106AbcEFK4l (ORCPT ); Fri, 6 May 2016 06:56:41 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP; 06 May 2016 03:56:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,586,1455004800"; d="scan'208";a="947527833" Received: from paasikivi.fi.intel.com ([10.237.72.42]) by orsmga001.jf.intel.com with ESMTP; 06 May 2016 03:56:37 -0700 Received: from nauris.fi.intel.com (nauris.localdomain [192.168.240.2]) by paasikivi.fi.intel.com (Postfix) with ESMTP id A9DBC20DCE; Fri, 6 May 2016 13:56:35 +0300 (EEST) Received: by nauris.fi.intel.com (Postfix, from userid 1000) id E1E60201D1; Fri, 6 May 2016 13:53:36 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl, mchehab@osg.samsung.com, Laurent Pinchart Subject: [RFC 10/22] v4l: Support the request API in format operations Date: Fri, 6 May 2016 13:53:19 +0300 Message-Id: <1462532011-15527-11-git-send-email-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1462532011-15527-1-git-send-email-sakari.ailus@linux.intel.com> References: <1462532011-15527-1-git-send-email-sakari.ailus@linux.intel.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Laurent Pinchart Store the formats in per-entity request data. The get and set format operations are completely handled by the V4L2 core with help of the try format driver operation. Signed-off-by: Laurent Pinchart --- drivers/media/v4l2-core/v4l2-ioctl.c | 121 +++++++++++++++++++++++++++++++++++ include/media/v4l2-dev.h | 13 ++++ 2 files changed, 134 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index bf15580..533fac6 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1355,6 +1355,119 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, return ret; } +#if defined(CONFIG_MEDIA_CONTROLLER) +static void vdev_request_data_release(struct media_entity_request_data *data) +{ + struct video_device_request_data *vdata = + to_video_device_request_data(data); + + kfree(vdata); +} + +static int vdev_request_format(struct video_device *vdev, unsigned int req_id, + struct media_device_request **_req, + struct v4l2_pix_format_mplane **_fmt) +{ + struct media_entity_request_data *data; + struct video_device_request_data *vdata; + struct media_device_request *req; + + if (!vdev->v4l2_dev || !vdev->v4l2_dev->mdev) + return -EINVAL; + + req = media_device_request_find(vdev->v4l2_dev->mdev, req_id); + if (!req) + return -EINVAL; + + *_req = req; + + data = media_device_request_get_entity_data(req, &vdev->entity); + if (data) { + vdata = to_video_device_request_data(data); + *_fmt = &vdata->format; + return 0; + } + + vdata = kzalloc(sizeof(*vdata), GFP_KERNEL); + if (!vdata) { + media_device_request_put(req); + return -ENOMEM; + } + + vdata->data.release = vdev_request_data_release; + + media_device_request_set_entity_data(req, &vdev->entity, &vdata->data); + + *_fmt = &vdata->format; + return 0; +} + +static int v4l_g_req_mplane_fmt(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct video_device *vdev = video_devdata(file); + struct v4l2_pix_format_mplane *format; + struct media_device_request *req; + int ret; + + ret = vdev_request_format(vdev, fmt->fmt.pix_mp.request, + &req, &format); + if (ret < 0) + return ret; + + fmt->fmt.pix_mp = *format; + media_device_request_put(req); + return 0; +} + +static int v4l_s_req_mplane_fmt(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, + struct v4l2_format *fmt) +{ + int (*try_op)(struct file *file, void *fh, struct v4l2_format *fmt); + struct video_device *vdev = video_devdata(file); + struct v4l2_pix_format_mplane *format; + struct media_device_request *req; + int ret; + + if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + try_op = ops->vidioc_try_fmt_vid_cap_mplane; + else + try_op = ops->vidioc_try_fmt_vid_out_mplane; + + if (unlikely(!try_op)) + return -ENOSYS; + + ret = try_op(file, fh, fmt); + if (ret < 0) + return ret; + + ret = vdev_request_format(vdev, fmt->fmt.pix_mp.request, + &req, &format); + if (ret < 0) + return ret; + + *format = fmt->fmt.pix_mp; + media_device_request_put(req); + return 0; +} +#else +static int v4l_g_req_mplane_fmt(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, + struct v4l2_format *fmt) +{ + return -ENOSYS; +} + +static int v4l_s_req_mplane_fmt(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, + struct v4l2_format *fmt) +{ + return -ENOSYS; +} +#endif + static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { @@ -1402,6 +1515,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane)) break; + if (p->fmt.pix_mp.request) + return v4l_g_req_mplane_fmt(ops, file, fh, p); return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay)) @@ -1426,6 +1541,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane)) break; + if (p->fmt.pix_mp.request) + return v4l_g_req_mplane_fmt(ops, file, fh, p); return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg); case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay)) @@ -1480,6 +1597,8 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane)) break; CLEAR_AFTER_FIELD(p, fmt.pix_mp); + if (p->fmt.pix_mp.request) + return v4l_s_req_mplane_fmt(ops, file, fh, p); return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay)) @@ -1508,6 +1627,8 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane)) break; CLEAR_AFTER_FIELD(p, fmt.pix_mp); + if (p->fmt.pix_mp.request) + return v4l_s_req_mplane_fmt(ops, file, fh, p); return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay)) diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 25a3190..19c7702 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -238,4 +238,17 @@ static inline int video_is_registered(struct video_device *vdev) return test_bit(V4L2_FL_REGISTERED, &vdev->flags); } +#if defined(CONFIG_MEDIA_CONTROLLER) +struct video_device_request_data { + struct media_entity_request_data data; + struct v4l2_pix_format_mplane format; +}; + +static inline struct video_device_request_data * +to_video_device_request_data(struct media_entity_request_data *data) +{ + return container_of(data, struct video_device_request_data, data); +} +#endif + #endif /* _V4L2_DEV_H */