linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tomasz Stanislawski <t.stanislaws@samsung.com>
To: Tomasz Stanislawski <t.stanislaws@samsung.com>
Cc: linaro-mm-sig@lists.linaro.org, linux-media@vger.kernel.org,
	sumit.semwal@ti.com, jesse.barker@linaro.org, rob@ti.com,
	daniel@ffwll.ch, m.szyprowski@samsung.com,
	kyungmin.park@samsung.com, hverkuil@xs4all.nl,
	laurent.pinchart@ideasonboard.com, pawel@osciak.com
Subject: Re: [PATCH 05/10] v4l: add buffer exporting via dmabuf
Date: Thu, 26 Jan 2012 10:48:23 +0100	[thread overview]
Message-ID: <4F212167.9090607@samsung.com> (raw)
In-Reply-To: <1327326675-8431-6-git-send-email-t.stanislaws@samsung.com>

Hi Everyone,

I would like to present a simple test application used for testing 
DMABUF support in V4L2. It is used to show how support for DMABUF may 
look like in V4L2.

The test application creates a simple pipeline between two V4L2 devices. 
One of them is a capture device. The second one is an output device.

The buffers are exchanged using DMABUF mechanism. The application takes 
additional argument to setup capture's size and rotation and compose 
window on output device (controlled using VIDIOC_S_CROP).

The application was tested on s5p-tv as output and s5p-fimc as capture.
It is written in GNU99 standard

Regards,
Tomasz Stanislawski

----


#include <errno.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <math.h>
#include <poll.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

#define ERRSTR strerror(errno)

#define BYE_ON(cond, ...) \
do { \
	if (cond) { \
		int errsv = errno; \
		fprintf(stderr, "ERROR(%s:%d) : ", \
			__FILE__, __LINE__); \
		errno = errsv; \
		fprintf(stderr,  __VA_ARGS__); \
		abort(); \
	} \
} while(0)

#define BUFFER_CNT	5

int main(int argc, char *argv[])
{
	int ret;

	BYE_ON(argc < 3, "bad args:\n\t%s input-node output-node "
		"[w,h,rot] [left,top,w,h]\n", argv[0]);

	int f_in, f_out;

	f_in = open(argv[1], O_RDWR);
	BYE_ON(f_in < 0, "open failed: %s\n", ERRSTR);

	f_out = open(argv[2], O_RDWR);
	BYE_ON(f_out < 0, "open failed: %s\n", ERRSTR);

	/* configure desired image size */
	struct v4l2_format fmt;
	memset(&fmt, 0, sizeof fmt);
	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
	fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGB565;
	int rotation = 0;
	if (argc >= 4) {
		ret = sscanf(argv[3], "%u,%u,%d",
			&fmt.fmt.pix_mp.width,
			&fmt.fmt.pix_mp.height,
			&rotation);
		BYE_ON(ret < 2, "incorrect sensor size and rotation\n");
	}

	if (rotation) {
		struct v4l2_control ctrl = {
			.id = V4L2_CID_ROTATE,
			.value = rotation,
		};
		ret = ioctl(f_in, VIDIOC_S_CTRL, &ctrl);
		BYE_ON(ret < 0, "VIDIOC_S_CTRL failed: %s\n", ERRSTR);
	}

	/* set format struct */
	ret = ioctl(f_in, VIDIOC_S_FMT, &fmt);
	BYE_ON(ret < 0, "VIDIOC_S_FMT failed: %s\n", ERRSTR);

	/* get format struct */
	ret = ioctl(f_in, VIDIOC_G_FMT, &fmt);
	BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR);
	printf("G_FMT(f_in): width = %u, height = %u, 4cc = %.4s\n",
		fmt.fmt.pix.width, fmt.fmt.pix.height,
		(char*)&fmt.fmt.pix.pixelformat);

	if (argc >= 5) {
		struct v4l2_crop crop;
		crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
		ret = sscanf(argv[4], "%d,%d,%d,%d",
			&crop.c.left, &crop.c.top,
			&crop.c.width, &crop.c.height);
		BYE_ON(ret != 4, "incorrect cropping format\n");
		ret = ioctl(f_out, VIDIOC_S_CROP, &crop);
		BYE_ON(ret < 0, "VIDIOC_S_CROP failed: %s\n", ERRSTR);
	}

	/* pass input format to output */
	fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
	ret = ioctl(f_out, VIDIOC_S_FMT, &fmt);
	BYE_ON(ret < 0, "VIDIOC_S_FMT failed: %s\n", ERRSTR);

	/* get format struct */
	ret = ioctl(f_out, VIDIOC_G_FMT, &fmt);
	BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR);
	printf("G_FMT(f_out): width = %u, height = %u, 4cc = %.4s\n",
		fmt.fmt.pix.width, fmt.fmt.pix.height,
		(char*)&fmt.fmt.pix.pixelformat);

	/* allocate buffers */
	struct v4l2_requestbuffers rqbufs;
	rqbufs.count = BUFFER_CNT;
	rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
	rqbufs.memory = V4L2_MEMORY_MMAP;

	ret = ioctl(f_in, VIDIOC_REQBUFS, &rqbufs);
	BYE_ON(ret < 0, "VIDIOC_REQBUFS failed: %s\n", ERRSTR);
	BYE_ON(rqbufs.count < BUFFER_CNT, "failed to get %d buffers\n", 
BUFFER_CNT);

	rqbufs.count = BUFFER_CNT;
	rqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
	rqbufs.memory = V4L2_MEMORY_DMABUF;

	ret = ioctl(f_out, VIDIOC_REQBUFS, &rqbufs);
	BYE_ON(ret < 0, "VIDIOC_REQBUFS failed: %s\n", ERRSTR);
	BYE_ON(rqbufs.count < BUFFER_CNT, "failed to get %d buffers\n", 
BUFFER_CNT);

	int fd[BUFFER_CNT];
	/* buffers initalization */
	for (int i = 0; i < BUFFER_CNT; ++i) {
		struct v4l2_plane plane;
		struct v4l2_buffer buf;

		memset(&buf, 0, sizeof buf);
		memset(&plane, 0, sizeof plane);
		buf.index = i;
		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
		buf.memory = V4L2_MEMORY_MMAP;
		buf.m.planes = &plane;
		buf.length = 1;

		/* get buffer properties from a driver */
		ret = ioctl(f_in, VIDIOC_QUERYBUF, &buf);
		BYE_ON(ret < 0, "VIDIOC_QUERYBUF for buffer %d failed: %s\n",
			buf.index, ERRSTR);
		BYE_ON(buf.memory != V4L2_MEMORY_MMAP, "bad memory type\n");
		BYE_ON(buf.length != 1, "non singular plane format\n");

		fd[i] = ioctl(f_in, VIDIOC_EXPBUF, &plane.m.mem_offset);
		BYE_ON(fd[i] < 0, "VIDIOC_EXPBUF failed; %s\n", ERRSTR);

		if (i < BUFFER_CNT / 2) {
			/* enqueue low-index buffers to input */
			ret = ioctl(f_in, VIDIOC_QBUF, &buf);
		} else {
			/* enqueue high-index buffers to output */
			buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
			buf.memory = V4L2_MEMORY_DMABUF;
			plane.m.fd = fd[i];
			ret = ioctl(f_out, VIDIOC_QBUF, &buf);
		}
		BYE_ON(ret < 0, "VIDIOC_QBUF for buffer %d failed: %s\n",
			buf.index, ERRSTR);
	}

	/* start streaming */
	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
	ret = ioctl(f_in, VIDIOC_STREAMON, &type);
	BYE_ON(ret < 0, "STREAMON failed: %s\n", ERRSTR);

	type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
	ret = ioctl(f_out, VIDIOC_STREAMON, &type);
	BYE_ON(ret < 0, "STREAMON failed: %s\n", ERRSTR);

	/* setup polling */
	struct pollfd fds[2] = {
		{ .fd = f_in, .events = POLLIN },
		{ .fd = f_out, .events = POLLOUT },
	};

	while ((ret = poll(fds, 2, 5000)) > 0) {
		struct v4l2_buffer buf;
		struct v4l2_plane plane;

		memset(&buf, 0, sizeof buf);
		memset(&plane, 0, sizeof plane);
		buf.m.planes = &plane;
		buf.length = 1;

		if (fds[0].revents & POLLIN) {
			/* dequeue buffer */
			buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
			buf.memory = V4L2_MEMORY_MMAP;
			ret = ioctl(f_in, VIDIOC_DQBUF, &buf);
			BYE_ON(ret, "VIDIOC_DQBUF failed: %s\n", ERRSTR);

			/* enqueue buffer */
			buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
			buf.memory = V4L2_MEMORY_DMABUF;
			plane.m.fd = fd[buf.index];
			ret = ioctl(f_out, VIDIOC_QBUF, &buf);
			BYE_ON(ret, "VIDIOC_QBUF failed: %s\n", ERRSTR);
		}
		if (fds[1].revents & POLLOUT) {
			/* dequeue buffer */
			buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
			buf.memory = V4L2_MEMORY_DMABUF;
			ret = ioctl(f_out, VIDIOC_DQBUF, &buf);
			BYE_ON(ret, "VIDIOC_DQBUF failed: %s\n", ERRSTR);

			/* enqueue buffer */
			buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
			buf.memory = V4L2_MEMORY_MMAP;
			ret = ioctl(f_in, VIDIOC_QBUF, &buf);
			BYE_ON(ret, "VIDIOC_QBUF failed: %s\n", ERRSTR);
		}
	}

	BYE_ON(ret == 0, "polling timeout\n");
	BYE_ON(1, "polling stopped: %s\n", ERRSTR);

	return 0;
}

  parent reply	other threads:[~2012-01-26  9:48 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-23 13:51 [PATCH 00/10] Integration of videobuf2 with dmabuf Tomasz Stanislawski
2012-01-23 13:51 ` [PATCH 01/10] arm: dma: support for dma_get_pages Tomasz Stanislawski
2012-01-23 13:51 ` [PATCH 02/10] [media] media: vb2: remove plane argument from call_memop and cleanup mempriv usage Tomasz Stanislawski
2012-01-23 13:51 ` [PATCH 03/10] media: vb2: add prepare/finish callbacks to allocators Tomasz Stanislawski
2012-02-03 15:42   ` Pawel Osciak
2012-01-23 13:51 ` [PATCH 04/10] v4l: vb2: fixes for DMABUF support Tomasz Stanislawski
2012-01-23 14:22   ` Mauro Carvalho Chehab
2012-01-23 14:32     ` Tomasz Stanislawski
2012-01-23 14:52       ` Mauro Carvalho Chehab
2012-01-23 15:25         ` Tomasz Stanislawski
2012-01-23 16:06           ` Mauro Carvalho Chehab
2012-01-23 16:37             ` Tomasz Stanislawski
2012-01-23 16:51               ` Mauro Carvalho Chehab
2012-01-25  5:35           ` Semwal, Sumit
2012-01-25 10:34             ` Tomasz Stanislawski
2012-01-25 14:09               ` Semwal, Sumit
2012-01-23 13:51 ` [PATCH 05/10] v4l: add buffer exporting via dmabuf Tomasz Stanislawski
2012-01-23 14:32   ` Mauro Carvalho Chehab
2012-01-23 14:37     ` Laurent Pinchart
2012-01-23 14:42     ` Tomasz Stanislawski
2012-01-23 15:04       ` Mauro Carvalho Chehab
2012-01-23 15:56         ` Tomasz Stanislawski
2012-01-23 16:42           ` Mauro Carvalho Chehab
2012-01-23 16:57             ` V4L2 Overlay mode replacement by dma-buf - was: " Mauro Carvalho Chehab
2012-01-24  0:11               ` Clark, Rob
2012-01-24  9:44             ` Laurent Pinchart
2012-01-24 11:07   ` [Linaro-mm-sig] " Subash Patel
2012-01-24 12:06     ` Tomasz Stanislawski
2012-01-27 13:40       ` Subash Patel
2012-01-30 14:16         ` Laurent Pinchart
2012-01-26  9:48   ` Tomasz Stanislawski [this message]
2012-02-03 15:47     ` Pawel Osciak
2012-02-03 15:50   ` Pawel Osciak
2012-01-23 13:51 ` [PATCH 06/10] v4l: vb2: " Tomasz Stanislawski
2012-01-23 13:51 ` [PATCH 07/10] v4l: vb2: remove dma-contig allocator Tomasz Stanislawski
2012-01-23 14:24   ` Mauro Carvalho Chehab
2012-01-23 13:51 ` [PATCH 08/10] v4l: vb2-dma-contig: code refactoring, support for DMABUF exporting Tomasz Stanislawski
2012-01-23 14:26   ` Mauro Carvalho Chehab
2012-01-23 14:35     ` Tomasz Stanislawski
2012-01-23 14:43       ` Mauro Carvalho Chehab
2012-01-23 14:35   ` [PATCH] media: vb2-memops: Export vb2_get_vma symbol Laurent Pinchart
2012-01-23 14:44     ` Tomasz Stanislawski
2012-03-21 11:12       ` Laurent Pinchart
2012-01-23 13:51 ` [PATCH 09/10] v4l: fimc: integrate capture i-face with dmabuf Tomasz Stanislawski
2012-01-23 13:51 ` [PATCH 10/10] v4l: s5p-tv: mixer: integrate " Tomasz Stanislawski
2012-01-23 14:37 ` [PATCH 00/10] Integration of videobuf2 " Mauro Carvalho Chehab

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F212167.9090607@samsung.com \
    --to=t.stanislaws@samsung.com \
    --cc=daniel@ffwll.ch \
    --cc=hverkuil@xs4all.nl \
    --cc=jesse.barker@linaro.org \
    --cc=kyungmin.park@samsung.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-media@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=pawel@osciak.com \
    --cc=rob@ti.com \
    --cc=sumit.semwal@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).