summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRakesh Movva <r-movva@ti.com>2015-06-11 20:59:03 -0500
committerVishal Mahaveer <vishalm@ti.com>2015-08-11 17:00:24 -0500
commit3bb831ef3d07447bc987658878cf0afb61e3f760 (patch)
tree2eb377bf7b93a74e9788f817bcbf682b84ee78a4
parent66f01db31b2403e6ee4d4b3cffa8a05e0762f596 (diff)
downloaddra7xx-3bb831ef3d07447bc987658878cf0afb61e3f760.tar.gz
vpetest: Add test case for testing VPE V4L2 API
This is a commandline test used for validating VPE functionality. It can be used for testing color conversion, cropping, scaling and de-interlacing feature of VPE. Change-Id: I1a75a3efbfe8bffe775d5957a4f60d7bdf95878a Signed-off-by: Rakesh Movva <r-movva@ti.com>
-rw-r--r--test/Android.mk3
-rw-r--r--test/vpe/Android.mk37
-rw-r--r--test/vpe/Makefile.am6
-rw-r--r--test/vpe/README16
-rw-r--r--test/vpe/vpetest.c622
5 files changed, 684 insertions, 0 deletions
diff --git a/test/Android.mk b/test/Android.mk
new file mode 100644
index 0000000..5b2943c
--- /dev/null
+++ b/test/Android.mk
@@ -0,0 +1,3 @@
+ifeq ($(TARGET_BOARD_PLATFORM), $(filter $(TARGET_BOARD_PLATFORM), jacinto6))
+ include $(all-subdir-makefiles)
+endif
diff --git a/test/vpe/Android.mk b/test/vpe/Android.mk
new file mode 100644
index 0000000..a0c3f67
--- /dev/null
+++ b/test/vpe/Android.mk
@@ -0,0 +1,37 @@
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(TARGET_BOARD_PLATFORM), $(filter $(TARGET_BOARD_PLATFORM), jacinto6))
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ vpetest.c
+
+LOCAL_SHARED_LIBRARIES:= \
+ libdl \
+ libui \
+ libutils \
+ libcutils \
+ liblog \
+ libbinder \
+ libmedia \
+ libui \
+ libgui \
+ libcamera_client
+
+LOCAL_C_INCLUDES += \
+ frameworks/base/include/ui \
+ frameworks/base/include/surfaceflinger \
+ frameworks/base/include/camera \
+ frameworks/base/include/media \
+ $(PV_INCLUDES)
+
+LOCAL_MODULE:= vpetest
+LOCAL_MODULE_TAGS:= tests
+
+LOCAL_CFLAGS += -Wall -fno-short-enums -O0 -g -D___ANDROID___
+
+
+include $(BUILD_EXECUTABLE)
+
+endif #ifeq ($(TARGET_BOARD_PLATFORM), $(filter $(TARGET_BOARD_PLATFORM), ))
diff --git a/test/vpe/Makefile.am b/test/vpe/Makefile.am
new file mode 100644
index 0000000..629d0be
--- /dev/null
+++ b/test/vpe/Makefile.am
@@ -0,0 +1,6 @@
+bin_PROGRAMS = testvpe
+
+testvpe_CFLAGS = \
+ -O0 -g
+
+testvpe_SOURCES = testvpe.c
diff --git a/test/vpe/README b/test/vpe/README
new file mode 100644
index 0000000..90ba578
--- /dev/null
+++ b/test/vpe/README
@@ -0,0 +1,16 @@
+This program is used to test vpe (Video Processing Engine)
+It is applicable for only dra7xx devices
+================
+Make sure you have loaded the vpe kernel module before this test is run
+It would register a video device as /dev/videoX
+Also, the vpdma firmware has to be loaded from userspace
+===============
+This test uses vpe through v4l2 apis for m2m framework
+
+Example usage:
+
+ vpetest frame-176-144-nv12-inp.yuv 176 144 nv12 di-ip-176-144-nv12-op-176-144-nv12-1-0-0-8-3-14.yuyv 176 288 nv12 0 0 176 144 1 1
+
+This is an example to demonstrate how to use vpe through v4l2 m2m framework
+
+For now, only deinterlacing is supported by vpe
diff --git a/test/vpe/vpetest.c b/test/vpe/vpetest.c
new file mode 100644
index 0000000..f6b0720
--- /dev/null
+++ b/test/vpe/vpetest.c
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2010-2011, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include <linux/videodev2.h>
+#include <linux/v4l2-controls.h>
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+#define pexit(str) { \
+ perror(str); \
+ exit(1); \
+}
+
+#define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_USER_TI_VPE_BASE + 0)
+
+/**< Input file descriptor */
+int fin = -1;
+
+/**< Output file descriptor */
+int fout = -1;
+
+/**< File descriptor for device */
+int fd = -1;
+
+int describeFormat (
+ char *format,
+ int width,
+ int height,
+ int *size,
+ int *fourcc,
+ int *coplanar,
+ enum v4l2_colorspace *clrspc)
+{
+ *size = -1;
+ *fourcc = -1;
+ if (strcmp (format, "rgb24") == 0) {
+ *fourcc = V4L2_PIX_FMT_RGB24;
+ *size = height * width * 3;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SRGB;
+
+ } else if (strcmp (format, "bgr24") == 0) {
+ *fourcc = V4L2_PIX_FMT_BGR24;
+ *size = height * width * 3;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SRGB;
+
+ } else if (strcmp (format, "argb32") == 0) {
+ *fourcc = V4L2_PIX_FMT_RGB32;
+ *size = height * width * 4;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SRGB;
+
+ } else if (strcmp (format, "abgr32") == 0) {
+ *fourcc = V4L2_PIX_FMT_BGR32;
+ *size = height * width * 4;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SRGB;
+
+ } else if (strcmp (format, "yuv444") == 0) {
+ *fourcc = V4L2_PIX_FMT_YUV444;
+ *size = height * width * 3;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "yvyu") == 0) {
+ *fourcc = V4L2_PIX_FMT_YVYU;
+ *size = height * width * 2;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "yuyv") == 0) {
+ *fourcc = V4L2_PIX_FMT_YUYV;
+ *size = height * width * 2;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "uyvy") == 0) {
+ *fourcc = V4L2_PIX_FMT_UYVY;
+ *size = height * width * 2;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "vyuy") == 0) {
+ *fourcc = V4L2_PIX_FMT_VYUY;
+ *size = height * width * 2;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "nv16") == 0) {
+ *fourcc = V4L2_PIX_FMT_NV16;
+ *size = height * width * 2;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "nv61") == 0) {
+ *fourcc = V4L2_PIX_FMT_NV61;
+ *size = height * width * 2;
+ *coplanar = 0;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "nv12") == 0) {
+ *fourcc = V4L2_PIX_FMT_NV12;
+ *size = height * width * 1.5;
+ *coplanar = 1;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else if (strcmp (format, "nv21") == 0) {
+ *fourcc = V4L2_PIX_FMT_NV21;
+ *size = height * width * 1.5;
+ *coplanar = 1;
+ *clrspc = V4L2_COLORSPACE_SMPTE170M;
+
+ } else {
+ return 0;
+
+ }
+
+ return 1;
+}
+
+int allocBuffers(
+ int type,
+ int width,
+ int height,
+ int coplanar,
+ enum v4l2_colorspace clrspc,
+ int *sizeimage_y,
+ int *sizeimage_uv,
+ int fourcc,
+ void *base[],
+ void *base_uv[],
+ int *numbuf,
+ int interlace,
+ struct v4l2_crop crop,
+ bool crop_enabled)
+{
+ struct v4l2_format fmt;
+ struct v4l2_requestbuffers reqbuf;
+ struct v4l2_buffer buffer;
+ struct v4l2_plane buf_planes[2];
+ int i = 0;
+ int ret = -1;
+
+ bzero(&fmt,sizeof(fmt));
+ fmt.type = type;
+ fmt.fmt.pix_mp.width = width;
+ fmt.fmt.pix_mp.height = height;
+ fmt.fmt.pix_mp.pixelformat = fourcc;
+ fmt.fmt.pix_mp.colorspace = clrspc;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && interlace)
+ fmt.fmt.pix_mp.field = V4L2_FIELD_ALTERNATE;
+ else
+ fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
+
+ ret = ioctl(fd,VIDIOC_S_FMT,&fmt);
+ if(ret < 0) {
+ pexit("Cant set color format\n");
+ } else {
+ *sizeimage_y = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+ *sizeimage_uv = fmt.fmt.pix_mp.plane_fmt[1].sizeimage;
+ }
+
+ if (crop_enabled && type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ ret = ioctl(fd, VIDIOC_S_CROP, &crop);
+ if (ret < 0)
+ pexit("error setting crop\n");
+ }
+
+ bzero(&reqbuf,sizeof(reqbuf));
+ reqbuf.count = *numbuf;
+ reqbuf.type = type;
+ reqbuf.memory = V4L2_MEMORY_MMAP;
+
+ ret = ioctl (fd, VIDIOC_REQBUFS, &reqbuf);
+ if(ret < 0) {
+ pexit("Cant request buffers\n");
+ } else {
+ *numbuf = reqbuf.count;
+ }
+
+ for(i = 0; i < *numbuf; i++) {
+
+ memset(&buffer, 0, sizeof(buffer));
+ buffer.type = type;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ buffer.index = i;
+ buffer.m.planes = buf_planes;
+ buffer.length = coplanar ? 2 : 1;
+
+ ret = ioctl (fd, VIDIOC_QUERYBUF, &buffer);
+ if (ret < 0)
+ pexit("Cant query buffers\n");
+
+ printf("query buf, plane 0 = %d, plane 1 = %d\n", buffer.m.planes[0].length,
+ buffer.m.planes[1].length);
+
+ base[i] = mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, buffer.m.planes[0].m.mem_offset);
+
+ if (MAP_FAILED == base[i]) {
+ while(i>=0){
+ /** Unmap all previous buffers */
+ i--;
+ munmap(base[i], *sizeimage_y);
+ base[i] = NULL;
+ }
+ pexit("Cant mmap buffers Y");
+ return 0;
+ }
+
+ if (!coplanar)
+ continue;
+
+ base_uv[i] = mmap(NULL, buffer.m.planes[1].length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, buffer.m.planes[1].m.mem_offset);
+
+ if (MAP_FAILED == base_uv[i]) {
+ while(i >= 0){
+ /** Unmap all previous buffers */
+ i--;
+ munmap(base_uv[i], *sizeimage_uv);
+ base[i] = NULL;
+ }
+ pexit("Cant mmap buffers UV");
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+void releaseBuffers(
+ void *base[],
+ int numbuf,
+ int bufsize)
+{
+ while (numbuf >= 0){
+ numbuf--;
+ munmap(base[numbuf],bufsize);
+ }
+}
+
+int queueAllBuffers(
+ int type,
+ int numbuf
+ )
+{
+ struct v4l2_buffer buffer;
+ struct v4l2_plane buf_planes[2];
+ int i = 0;
+ int ret = -1;
+ int lastqueued = -1;
+
+ for (i=0; i<numbuf; i++) {
+ memset(&buffer,0,sizeof(buffer));
+ buffer.type = type;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ buffer.index = i;
+ buffer.m.planes = buf_planes;
+ buffer.length = 2;
+
+ ret = ioctl (fd, VIDIOC_QBUF, &buffer);
+ if (-1 == ret) {
+ break;
+ } else {
+ lastqueued=i;
+ }
+ }
+ return lastqueued;
+}
+
+int queue(
+ int type,
+ int index,
+ int field,
+ int size_y,
+ int size_uv)
+{
+ struct v4l2_buffer buffer;
+ struct v4l2_plane buf_planes[2];
+ int ret = -1;
+
+ buf_planes[0].length = buf_planes[0].bytesused = size_y;
+ buf_planes[1].length = buf_planes[1].bytesused = size_uv;
+ buf_planes[0].data_offset = buf_planes[1].data_offset = 0;
+
+ memset(&buffer,0,sizeof(buffer));
+ buffer.type = type;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ buffer.index = index;
+ buffer.m.planes = buf_planes;
+ buffer.field = field;
+ buffer.length = 2;
+
+ ret = ioctl (fd, VIDIOC_QBUF, &buffer);
+ if(-1 == ret) {
+ pexit("Failed to queue\n");
+ }
+ return ret;
+}
+
+int dequeue(int type, struct v4l2_buffer *buf, struct v4l2_plane *buf_planes)
+{
+ int ret = -1;
+
+ memset(buf, 0, sizeof(*buf));
+ buf->type = type;
+ buf->memory = V4L2_MEMORY_MMAP;
+ buf->m.planes = buf_planes;
+ buf->length = 2;
+ ret = ioctl (fd, VIDIOC_DQBUF, buf);
+ return ret;
+}
+
+void streamON (
+ int type)
+{
+ int ret = -1;
+ ret = ioctl (fd, VIDIOC_STREAMON, &type);
+ if(-1 == ret) {
+ pexit("Cant Stream on\n");
+ }
+}
+
+void streamOFF (
+ int type)
+{
+ int ret = -1;
+ ret = ioctl (fd, VIDIOC_STREAMOFF, &type);
+ if(-1 == ret) {
+ pexit("Cant Stream on\n");
+ }
+}
+
+void do_read (char *str, int fd, void *addr, int size) {
+ int nbytes = size, ret = 0, val;
+ do {
+ nbytes = size - ret;
+ addr = addr + ret;
+ if (nbytes == 0) {
+ break;
+ }
+ ret = read(fd, addr, nbytes);
+ } while(ret > 0);
+
+ if (ret < 0) {
+ val = errno;
+ printf ("Reading failed %s: %d %s\n", str, ret, strerror(val));
+ exit (1);
+ } else {
+ printf ("Total bytes read %s = %d\n", str, size);
+ }
+}
+
+void do_write (char *str, int fd, void *addr, int size) {
+ int nbytes = size, ret = 0, val;
+ do {
+ nbytes = size - ret;
+ addr = addr + ret;
+ if(nbytes == 0) {
+ break;
+ }
+ ret = write(fd, addr, nbytes);
+ } while(ret > 0);
+ if (ret < 0) {
+ val = errno;
+ printf ("Writing failed %s: %d %s\n", str, ret, strerror(val));
+ exit (1);
+ } else {
+ printf ("Total bytes written %s = %d\n", str, size);
+ }
+}
+
+int main (
+ int argc,
+ char *argv[])
+{
+ int i, ret = 0;
+
+ int srcHeight = 0, dstHeight = 0;
+ int srcWidth = 0, dstWidth = 0;
+ int srcSize = 0, dstSize = 0, srcSize_uv = 0, dstSize_uv = 0;
+ int srcFourcc = 0, dstFourcc = 0;
+ int src_coplanar = 0, dst_coplanar = 0;
+ enum v4l2_colorspace src_colorspace, dst_colorspace;
+
+ void *srcBuffers[6];
+ void *dstBuffers[6];
+ void *srcBuffers_uv[6];
+ void *dstBuffers_uv[6];
+ int src_numbuf = 6;
+ int dst_numbuf = 6;
+ int num_frames = 20;
+ int dequeued_frames = 0;
+ int interlace = 0;
+ int translen = 3;
+ struct v4l2_control ctrl;
+ struct v4l2_crop crop;
+ bool crop_enabled;
+ int field;
+ off_t file_size;
+
+ if (argc != 15) {
+ printf (
+ "USAGE : <SRCfilename> <SRCWidth> <SRCHeight> <SRCFormat> "
+ "<DSTfilename> <DSTWidth> <DSTHeight> <DSTformat> "
+ "<crop top> <crop left> <crop width> <crop height> "
+ "<interlace> <translen>\n");
+
+ return 1;
+ }
+
+ /** Open input file in read only mode */
+ fin = open (argv[1], O_RDONLY);
+ srcWidth = atoi (argv[2]);
+ srcHeight = atoi (argv[3]);
+ describeFormat (argv[4], srcWidth, srcHeight, &srcSize, &srcFourcc, &src_coplanar, &src_colorspace);
+
+ /** Open output file in write mode Create the file if not present */
+ fout = open (argv[5], O_WRONLY | O_CREAT | O_TRUNC, 777);
+ dstWidth = atoi (argv[6]);
+ dstHeight = atoi (argv[7]);
+ describeFormat (argv[8], dstWidth, dstHeight, &dstSize, &dstFourcc, &dst_coplanar, &dst_colorspace);
+
+ if((atoi (argv[9]) == 0) && (atoi (argv[10]) == 0) && (atoi (argv[11]) == 0) && (atoi (argv[12]) == 0)){
+ crop_enabled = 0;
+ }
+ else{
+ crop.c.top = atoi (argv[9]);
+ crop.c.left = atoi (argv[10]);
+ crop.c.width = atoi (argv[11]);
+ crop.c.height = atoi (argv[12]);
+ crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ crop_enabled = 1;
+ }
+
+
+ interlace = atoi (argv[13]);
+ translen = atoi (argv[14]);
+
+ printf ("Input @ %d = %d x %d , %d\nOutput @ %d = %d x %d , %d\n",
+ fin, srcWidth, srcHeight, srcFourcc,
+ fout, dstWidth, dstHeight, dstFourcc);
+
+ if ( fin < 0 || srcHeight < 0 || srcWidth < 0 || srcFourcc < 0 || \
+ fout < 0 || dstHeight < 0 || dstWidth < 0 || dstFourcc < 0) {
+ /** TODO:Handle errors precisely */
+ exit (1);
+ }
+ /*************************************
+ Files are ready Now
+ *************************************/
+
+ fd = open("/dev/video0",O_RDWR);
+ if(fd < 0) {
+ pexit("Cant open /device\n");
+ }
+
+#if 0
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = V4L2_CID_TRANS_NUM_BUFS;
+ ctrl.value = translen;
+ ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
+ if (ret < 0)
+ pexit("ioctl");
+#endif
+ ret = allocBuffers (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, srcWidth,
+ srcHeight, src_coplanar, src_colorspace, &srcSize, &srcSize_uv,
+ srcFourcc, srcBuffers, srcBuffers_uv, &src_numbuf, interlace,
+ crop, crop_enabled);
+ if(ret < 0) {
+ pexit("Cant Allocate buffurs for OUTPUT device\n");
+ }
+
+ ret = allocBuffers (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, dstWidth,
+ dstHeight, dst_coplanar, dst_colorspace, &dstSize, &dstSize_uv,
+ dstFourcc, dstBuffers, dstBuffers_uv, &dst_numbuf, interlace,
+ crop, crop_enabled);
+ if(ret < 0) {
+ pexit("Cant Allocate buffurs for CAPTURE device\n");
+ }
+
+ /** Queue All empty buffers (Available to capture in) */
+ ret = queueAllBuffers (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, dst_numbuf);
+ if(ret < 0) {
+ pexit("Error queueing buffers for CAPTURE device\n");
+ }
+
+ printf ("Input Buffers = %d each of size %d\nOutput Buffers = %d each of size %d\n",
+ src_numbuf, srcSize, dst_numbuf, dstSize);
+
+ /*************************************
+ Driver is ready Now
+ *************************************/
+
+ /** Read into the OUTPUT buffers from fin file */
+
+ field = V4L2_FIELD_TOP;
+ for (i = 0; i < src_numbuf; i++) {
+ do_read("Y plane", fin, srcBuffers[i], srcSize);
+ if (src_coplanar)
+ do_read("UV plane", fin, srcBuffers_uv[i], srcSize_uv);
+
+ queue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, i, field, srcSize, srcSize_uv);
+ if (field == V4L2_FIELD_TOP)
+ field = V4L2_FIELD_BOTTOM;
+ else
+ field = V4L2_FIELD_TOP;
+ }
+
+ /*************************************
+ Data is ready Now
+ *************************************/
+
+ streamON (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ streamON (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+ while (num_frames) {
+ struct v4l2_buffer buf;
+ struct v4l2_plane buf_planes[2];
+ int last = num_frames == 1 ? 1 : 0;
+
+ dequeue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, &buf, buf_planes);
+ printf("dequeued source buffer with index %d\n", buf.index);
+
+ if (!last) {
+ do_read ("Y plane", fin, srcBuffers[buf.index], srcSize);
+ if (src_coplanar)
+ do_read ("UV plane", fin, srcBuffers_uv[buf.index], srcSize_uv);
+
+ queue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, buf.index, field, srcSize, srcSize_uv);
+ if (field == V4L2_FIELD_TOP)
+ field = V4L2_FIELD_BOTTOM;
+ else
+ field = V4L2_FIELD_TOP;
+ }
+
+ dequeue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &buf, buf_planes);
+ printf("dequeued dest buffer with index %d\n", buf.index);
+ //printf("dequed_frames %d\n", ++dequeued_frames);
+
+ do_write("Y plane", fout, dstBuffers[buf.index], dstSize);
+ if (dst_coplanar)
+ do_write("UV plane", fout, dstBuffers_uv[buf.index], dstSize_uv);
+
+ if (!last)
+ queue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, buf.index, V4L2_FIELD_NONE, dstSize, dstSize_uv);
+
+ num_frames--;
+
+ printf("frames left %d\n", num_frames);
+ }
+
+ /** Driver cleanup */
+ streamOFF (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ streamOFF (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+ releaseBuffers (srcBuffers, src_numbuf, srcSize);
+ releaseBuffers (dstBuffers, dst_numbuf, dstSize);
+
+ if (src_coplanar)
+ releaseBuffers (srcBuffers_uv, src_numbuf, srcSize_uv);
+ if (dst_coplanar)
+ releaseBuffers (dstBuffers_uv, dst_numbuf, dstSize_uv);
+
+ close(fin);
+ close(fout);
+ close(fd);
+
+ return 0;
+}
+