Commit 61ae84b5 authored by Julien Isorce's avatar Julien Isorce

v4l2: add support for multi-planar V4L2 API

This api is in linux kernel since version 2.6.39,
and present in all version 3.

The commit that adds the API in master branch of the
linux kernel source is:
https://github.com/torvalds/linux/commit/f8f3914cf922f5f9e1d60e9e10f6fb92742907ad

v4l2 doc: "Some devices require data for each input
or output video frame to be placed in discontiguous
memory buffers"

There are newer structures 'struct v4l2_pix_format_mplane'
and 'struct v4l2_plane'.
So the pixel format is not setup with the same API when using
multi-planar.

Also for gst-v4l2, one of the difference is that in GstV4l2Meta
there are now one mem pointer for each maped plane.

When not using multi-planar, this commit takes care of keeping
the same code path than previously. So that the 2 cases are
in two different blocks triggered from V4L2_TYPE_IS_MULTIPLANAR.

Fixes bug https://bugzilla.gnome.org/show_bug.cgi?id=712754
parent 0d55724a
This diff is collapsed.
......@@ -74,7 +74,17 @@ struct _GstV4l2BufferPoolClass
struct _GstV4l2Meta {
GstMeta meta;
gpointer mem;
/* VIDEO_MAX_PLANES is defined to 8 in videodev2.h
* whereas GST_VIDEO_MAX_PLANES is defined to 4 in
* video-format.h so lets use the minimum */
/* only useful in GST_V4L2_IO_MMAP case.
* it contains address at which the mapping
* was placed for each v4l2 plane */
gpointer mem[GST_VIDEO_MAX_PLANES];
/* plane info for multi-planar buffers */
struct v4l2_plane vplanes[GST_VIDEO_MAX_PLANES];
/* video buffer info */
struct v4l2_buffer vbuffer;
};
......
This diff is collapsed.
......@@ -118,10 +118,22 @@ struct _GstV4l2Object {
struct v4l2_fmtdesc *fmtdesc;
GstVideoInfo info;
guint32 bytesperline;
/* only used if the device supports MPLANE
* nb planes is meaning of v4l2 planes
* the gstreamer equivalent is gst_buffer_n_memory
*/
gint n_v4l2_planes;
guint32 bytesperline[GST_VIDEO_MAX_PLANES];
guint32 sizeimage;
GstClockTime duration;
/* if the MPLANE device support both contiguous and non contiguous
* it allows to select which one we want. But we prefered_non_contiguous
* non contiguous mode.
*/
gboolean prefered_non_contiguous;
/* wanted mode */
GstV4l2IOMode req_mode;
......
......@@ -525,13 +525,43 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
/* do we need to be a capture device? */
if (GST_IS_V4L2SRC (v4l2object->element) &&
!(v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
!(v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_VIDEO_CAPTURE_MPLANE)))
goto not_capture;
if (GST_IS_V4L2SINK (v4l2object->element) &&
!(v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT))
!(v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_OUTPUT |
V4L2_CAP_VIDEO_OUTPUT_MPLANE)))
goto not_output;
/* when calling gst_v4l2_object_new the user decides the initial type
* so adjust it if multi-planar is supported
* the driver should make it exclusive. So the driver should
* not support both MPLANE and non-PLANE.
* Because even when using MPLANE it still possibles to use it
* in a contiguous manner. In this case the first v4l2 plane
* contains all the gst planes.
*/
switch (v4l2object->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE) {
GST_DEBUG ("adjust type to multi-planar output");
v4l2object->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
}
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) {
/* FIXME: for now it's an untested case so just put a warning */
GST_WARNING ("untested V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE");
GST_DEBUG ("adjust type to multi-planar capture");
v4l2object->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
}
break;
default:
break;
}
/* create enumerations, posts errors. */
if (!gst_v4l2_fill_lists (v4l2object))
goto error;
......@@ -542,7 +572,8 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
pollfd.fd = v4l2object->video_fd;
gst_poll_add_fd (v4l2object->poll, &pollfd);
if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|| v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
gst_poll_fd_ctl_read (v4l2object->poll, &pollfd, TRUE);
else
gst_poll_fd_ctl_write (v4l2object->poll, &pollfd, TRUE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment