From patchwork Mon Dec 20 11:37:24 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 420061 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBKBc77M028629 for ; Mon, 20 Dec 2010 11:38:10 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932085Ab0LTLiD (ORCPT ); Mon, 20 Dec 2010 06:38:03 -0500 Received: from perceval.ideasonboard.com ([95.142.166.194]:51317 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757365Ab0LTLiA (ORCPT ); Mon, 20 Dec 2010 06:38:00 -0500 Received: from localhost.localdomain (unknown [87.66.44.208]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A3F2C35CE6; Mon, 20 Dec 2010 11:37:39 +0000 (UTC) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: sakari.ailus@maxwell.research.nokia.com Subject: [RFC/PATCH v5 12/13] v4l: v4l2_subdev userspace frame interval API Date: Mon, 20 Dec 2010 12:37:24 +0100 Message-Id: <1292845045-7945-13-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.2.2 In-Reply-To: <1292845045-7945-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1292845045-7945-1-git-send-email-laurent.pinchart@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Mon, 20 Dec 2010 11:38:10 +0000 (UTC) diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index 538f8fe..4af3c2e 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl @@ -89,7 +89,9 @@ VIDIOC_SUBDEV_ENUM_FRAME_SIZE"> VIDIOC_SUBDEV_ENUM_MBUS_CODE"> VIDIOC_SUBDEV_G_FMT"> +VIDIOC_SUBDEV_G_FRAME_INTERVAL"> VIDIOC_SUBDEV_S_FMT"> +VIDIOC_SUBDEV_S_FRAME_INTERVAL"> VIDIOC_TRY_ENCODER_CMD"> VIDIOC_TRY_EXT_CTRLS"> VIDIOC_TRY_FMT"> @@ -190,6 +192,8 @@ v4l2_sliced_vbi_cap"> v4l2_sliced_vbi_data"> v4l2_sliced_vbi_format"> +v4l2_subdev_frame_interval"> +v4l2_subdev_frame_interval_enum"> v4l2_subdev_frame_size_enum"> v4l2_subdev_format"> v4l2_subdev_mbus_code_enum"> @@ -325,10 +329,12 @@ + + diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml index 695e3bf..e6225e0 100644 --- a/Documentation/DocBook/v4l/v4l2.xml +++ b/Documentation/DocBook/v4l/v4l2.xml @@ -478,9 +478,11 @@ and discussions on the V4L mailing list. &sub-reqbufs; &sub-s-hw-freq-seek; &sub-streamon; + &sub-subdev-enum-frame-interval; &sub-subdev-enum-frame-size; &sub-subdev-enum-mbus-code; &sub-subdev-g-fmt; + &sub-subdev-g-frame-interval; &sub-subscribe-event; &sub-mmap; diff --git a/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml new file mode 100644 index 0000000..bcea9d49 --- /dev/null +++ b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml @@ -0,0 +1,146 @@ + + + ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL + &manvol; + + + + VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL + Enumerate frame intervals + + + + + + int ioctl + int fd + int request + struct v4l2_subdev_frame_interval_enum * + argp + + + + + + Arguments + + + + fd + + &fd; + + + + request + + VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL + + + + argp + + + + + + + + + Description + + This ioctl lets applications enumerate available frame intervals on a + given sub-device pad. Frame intervals only makes sense for sub-devices that + can control the frame period on their own. This includes, for instance, + image sensors and TV tuners. + + For the common use case of image sensors, the frame intervals + available on the sub-device output pad depend on the frame format and size + on the same pad. Applications must thus specify the desired format and size + when enumerating frame intervals. + + To enumerate frame intervals applications initialize the + index, pad, + code, width and + height fields of + &v4l2-subdev-frame-interval-enum; and call the + VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL ioctl with a pointer + to this structure. Drivers fill the rest of the structure or return + an &EINVAL; if one of the input fields is invalid. All frame intervals are + enumerable by beginning at index zero and incrementing by one until + EINVAL is returned. + + Available frame intervals may depend on the current 'try' formats + at other pads of the sub-device, as well as on the current active links. See + &VIDIOC-SUBDEV-G-FMT; for more information about the try formats. + + Sub-devices that support the frame interval enumeration ioctl should + implemented it on a single pad only. Its behaviour when supported on + multiple pads of the same sub-device is not defined. + + + struct <structname>v4l2_subdev_frame_interval_enum</structname> + + &cs-str; + + + __u32 + index + Number of the format in the enumeration, set by the + application. + + + __u32 + pad + Pad number as reported by the media controller API. + + + __u32 + code + The media bus format code, as defined in + . + + + __u32 + width + Frame width, in pixels. + + + __u32 + height + Frame height, in pixels. + + + &v4l2-fract; + interval + Period, in seconds, between consecutive video frames. + + + __u32 + reserved[9] + Reserved for future extensions. Applications and drivers must + set the array to zero. + + + +
+
+ + + &return-value; + + + + EINVAL + + The &v4l2-subdev-frame-interval-enum; + pad references a non-existing pad, one of + the code, width + or height fields are invalid for the given + pad or the index field is out of bounds. + + + + + +
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml new file mode 100644 index 0000000..1d0e0e1 --- /dev/null +++ b/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml @@ -0,0 +1,135 @@ + + + ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL + &manvol; + + + + VIDIOC_SUBDEV_G_FRAME_INTERVAL + VIDIOC_SUBDEV_S_FRAME_INTERVAL + Get or set the frame interval on a subdev pad + + + + + + int ioctl + int fd + int request + struct v4l2_subdev_frame_interval *argp + + + + + + + Arguments + + + + fd + + &fd; + + + + request + + VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL + + + + argp + + + + + + + + + Description + + These ioctls are used to get and set the frame interval at specific + subdev pads in the image pipeline. The frame interval only makes sense for + sub-devices that can control the frame period on their own. This includes, + for instance, image sensors and TV tuners. Sub-devices that don't support + frame intervals must not implement these ioctls. + + To retrieve the current frame interval applications set the + pad field of a &v4l2-subdev-frame-interval; to + the desired pad number as reported by the media controller API. When they + call the VIDIOC_SUBDEV_G_FRAME_INTERVAL ioctl with a + pointer to this structure the driver fills the members of the + interval field. + + To change the current frame interval applications set both the + pad field and all members of the + interval field. When they call the + VIDIOC_SUBDEV_S_FRAME_INTERVAL ioctl with a pointer to + this structure the driver verifies the requested interval, adjusts it based + on the hardware capabilities and configures the device. Upon return the + &v4l2-subdev-frame-interval; contains the current frame interval as would be + returned by a VIDIOC_SUBDEV_G_FRAME_INTERVAL call. + + + Drivers must not return an error solely because the requested interval + doesn't match the device capabilities. They must instead modify the interval + to match what the hardware can provide. The modified interval should be as + close as possible to the original request. + + Sub-devices that support the frame interval ioctls should implement + them on a single pad only. Their behaviour when supported on multiple pads + of the same sub-device is not defined. + + + struct <structname>v4l2_subdev_frame_interval</structname> + + &cs-str; + + + __u32 + pad + Pad number as reported by the media controller API. + + + &v4l2-fract; + interval + Period, in seconds, between consecutive video frames. + + + __u32 + reserved[5] + Reserved for future extensions. Applications and drivers must + set the array to zero. + + + +
+
+ + + &return-value; + + + + EBUSY + + The frame interval can't be changed because the pad is currently + busy. This can be caused, for instance, by an active video stream on + the pad. The ioctl must not be retried without performing another + action to fix the problem first. Only returned by + VIDIOC_SUBDEV_S_FRAME_INTERVAL + + + + EINVAL + + The &v4l2-subdev-frame-interval; pad + references a non-existing pad, or the pad doesn't support frame + intervals. + + + + +
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index 679062d..8f9001c 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c @@ -234,6 +234,22 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh, fse); } + + case VIDIOC_SUBDEV_G_FRAME_INTERVAL: + return v4l2_subdev_call(sd, video, g_frame_interval, arg); + + case VIDIOC_SUBDEV_S_FRAME_INTERVAL: + return v4l2_subdev_call(sd, video, s_frame_interval, arg); + + case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { + struct v4l2_subdev_frame_interval_enum *fie = arg; + + if (fie->pad >= sd->entity.num_pads) + return -EINVAL; + + return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh, + fie); + } #endif default: return -ENOIOCTLCMD; diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h index 039c6e4..7af0c34 100644 --- a/include/linux/v4l2-subdev.h +++ b/include/linux/v4l2-subdev.h @@ -80,11 +80,47 @@ struct v4l2_subdev_frame_size_enum { __u32 reserved[9]; }; +/** + * struct v4l2_subdev_frame_interval - Pad-level frame rate + * @pad: pad number, as reported by the media API + * @interval: frame interval in seconds + */ +struct v4l2_subdev_frame_interval { + __u32 pad; + struct v4l2_fract interval; + __u32 reserved[5]; +}; + +/** + * struct v4l2_subdev_frame_interval_enum - Frame interval enumeration + * @pad: pad number, as reported by the media API + * @index: frame interval index during enumeration + * @code: format code (from enum v4l2_mbus_pixelcode) + * @width: frame width in pixels + * @height: frame height in pixels + * @interval: frame interval in seconds + */ +struct v4l2_subdev_frame_interval_enum { + __u32 index; + __u32 pad; + __u32 code; + __u32 width; + __u32 height; + struct v4l2_fract interval; + __u32 reserved[9]; +}; + #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) #define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) +#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \ + _IOWR('V', 21, struct v4l2_subdev_frame_interval) +#define VIDIOC_SUBDEV_S_FRAME_INTERVAL \ + _IOWR('V', 22, struct v4l2_subdev_frame_interval) #define VIDIOC_SUBDEV_ENUM_MBUS_CODE \ _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum) #define VIDIOC_SUBDEV_ENUM_FRAME_SIZE \ _IOWR('V', 74, struct v4l2_subdev_frame_size_enum) +#define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \ + _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) #endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index f5611c2..9c8bcd3 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -281,6 +281,10 @@ struct v4l2_subdev_video_ops { int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); + int (*g_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *interval); + int (*s_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *interval); int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); int (*enum_dv_presets) (struct v4l2_subdev *sd, @@ -431,6 +435,9 @@ struct v4l2_subdev_pad_ops { int (*enum_frame_size)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse); + int (*enum_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_frame_interval_enum *fie); int (*get_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *format); int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,