This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Re:Capturing video at 576i@50 in DM8148 EVM

Other Parts Discussed in Thread: TVP7002

Hello,


I am having a DVD player which gives a component output of 576i@50. I want to capture the DVD output using DM8148 evm. I have modified the saLoopBack application  which came with PSP04.04.00.02 for capturing 576i video resolution. I have attached the file.

I have modified TVP7002 driver and the kept some prints in it to give the value of lines per frame and clock per line which are coming perfect. While I am executing the application it is getting failed in startCapture() with the following logs:

VPSS_CAPTURE: create capture0
VPSS_SHRBUF: FOUND 0xbfb14000, end 0xbfd00000, map vir 0xe9c14000 size 4096
VPSS_FVID2: create timeout
VPSS_SHRBUF: free mem paddr 0xbfb14000 vaddr 0xe9c14000 size 4096
ti81xxvin ti81xxvin: ti81xxvin_vps_create failed
ti81xxvin ti81xxvin: Vps create failed

tvp7002_s_stream

Inside tvp7002_write

 inside the video_ioctl2 and cmd=-1069263343

 copied from user SUCCESS

 INSIDE vidioc_dqbuf
ti81xxvin ti81xxvin: vidioc_dqbuf

 inside the ti81xxvin_release
ti81xxvin ti81xxvin: ti81xxvin_release

I have the following questions:

1) what are the changes I need to do in ti81xxvin driver for capturing a video at 576i ?

2) Does any change need to be done in the HDVPSS driver code for adding support for capturing at 576i?

Regards,

Debasish

/*
 * saLoopBack.c
 *
 * Copyright (C) 2011 TI
 * Author: Hardik Shah <hardik.shah@ti.com>
 *
 * This is a sample for loopback application. This application captures through
 * V4L2 capture driver on TVP7002 input and displays the captured content
 * on the V4L2 display driver. Application uses userpointer mechanism for
 * both capture and display drivers. Buffers for the userpointer are taken from
 * framebuffer driver (fbdev).
 *
 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
 *
 *
 *  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.
 *
*/

/*
 * Header File Inclusion
 */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <linux/videodev2.h>
#include <linux/fb.h>
#include <linux/ti81xxfb.h>
#include <linux/ti81xxhdmi.h>
#include <linux/ti81xxvin.h>

/* Number of buffers required for application. Less that this may cause
 * considerable frame drops
 */
#define MAX_BUFFER			8


/* device node to be used for capture */
#define CAPTURE_DEVICE		"/dev/video0"
#define CAPTURE_NAME		"Capture"
/* device node to be used for display */
#define DISPLAY_DEVICE		"/dev/video1"
#define DISPLAY_NAME		"Display"
/* number of frames to be captured and displayed
 * Increase this for long runs
 */
#define MAXLOOPCOUNT		500

/* Pixel format for capture and display. Capture supports
 * V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_NV16, V4L2_PIX_FMT_RGB24 but display
 * supports only V4L2_PIX_FMT_YUYV. So this has to be V4L2_PIX_FMT_YUYV
 */
#define DEF_PIX_FMT		V4L2_PIX_FMT_YUYV

/* Application name */
#define APP_NAME		"saLoopBack"

/* Define below #def for debug information enable */
#undef SALOOPBACK_DEBUG


/* Structure for storing buffer information */
struct buf_info {
	int index;
	unsigned int length;
	char *start;
};

/* Structure for storing application data like file pointers, format etc. */
#if 1  //commented by debasish
struct app_obj {
	int fd;
	struct v4l2_capability cap;
	struct v4l2_format fmt;
	struct v4l2_dv_preset dv_preset;
	struct v4l2_requestbuffers reqbuf;
	int numbuffers;
	struct v4l2_buffer buf;
	struct ti81xxvin_overflow_status over_flow;
};
#endif

#if 0
struct app_obj {
        int fd;
        struct v4l2_capability cap;
        struct v4l2_format fmt;
        struct v4l2_dv_preset dv_preset;
        struct v4l2_requestbuffers reqbuf;
        unsigned int numbuffers;
        unsigned int buffersize;
        unsigned char *buffer_addr[MAX_BUFFER];
        struct v4l2_buffer buf;
        struct ti81xxvin_overflow_status over_flow;
        struct v4l2_crop crop;
        struct v4l2_format fmt_win;
        void *myCaptureBuffer;
        //CMEM_AllocParams cmemParams;
};
#endif


/* Globals for capture and display application objects */
struct app_obj disp, capt;

/* File pointer for fbdev. fbdev is only used to get buffers
 */
static int fbdev_fd;

/* Pointers for storing buffer addresses */
unsigned char *buffer_addr[MAX_BUFFER];

/* Utility function for printing format */
static void printFormat(char *string, struct v4l2_format *fmt)
{
	printf("=============================================================\n");
	printf("%s Format:\n", string);
	printf("=============================================================\n");
	printf("fmt.type\t\t = %d\n", fmt->type);
	printf("fmt.width\t\t = %d\n", fmt->fmt.pix.width);
	printf("fmt.height\t\t = %d\n", fmt->fmt.pix.height);
	printf("fmt.pixelformat\t = %d\n", fmt->fmt.pix.pixelformat);
	printf("fmt.bytesperline\t = %d\n", fmt->fmt.pix.bytesperline);
	printf("fmt.sizeimage\t = %d\n", fmt->fmt.pix.sizeimage);
	printf("=============================================================\n");
}
/* Open and query dv preset for capture driver*/
static int initCapture(void)
{
	int mode = O_RDWR;

	/* Open capture driver */
	capt.fd = open((const char *)CAPTURE_DEVICE, mode);
	if (capt.fd == -1) {
		printf("failed to open capture device\n");
		return -1;
	}
	/* Query for capabilities */
	if (ioctl(capt.fd, VIDIOC_QUERYCAP, &capt.cap)) {
		printf("Query capability failed\n");
		exit(2);
	} else 	{
		printf("Driver Name: %s\n", capt.cap.driver);
		printf("Driver bus info: %s\n", capt.cap.bus_info);
		if (capt.cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
			printf("Driver is capable of doing capture\n");
		if (capt.cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
			printf("Driver is capabled of scaling and cropping\n");

	}
//	system("echo 0 > /sys/devices/platform/vpss/display0/enabled"); debasish
	/* Query the preset. Set it to invalid and query for it */
	capt.dv_preset.preset = 0x0;
	if (ioctl(capt.fd, VIDIOC_QUERY_DV_PRESET, &capt.dv_preset)) {
		printf("Querying DV Preset failed\n");
		exit(2);
	}
	switch (capt.dv_preset.preset) {
              
        case V4L2_DV_576P50:
                printf("%s:\n Mode set is 576p@50\n", APP_NAME);  //added by debasish
                break;
	case V4L2_DV_720P60:
		printf("%s:\n Mode set is 720P60\n", APP_NAME);
		system ("echo 720p-60 > /sys/devices/platform/vpss/display0/mode");
		break;
	case V4L2_DV_1080I60:
		printf("%s:\n Mode set is 1080I60\n", APP_NAME);
		system ("echo 1080i-60 > /sys/devices/platform/vpss/display0/mode");
		break;
	case V4L2_DV_1080P60:
		printf("%s:\n Mode set is 1080P60\n", APP_NAME);
		system ("echo 1080p-60 > /sys/devices/platform/vpss/display0/mode");
		break;
	case V4L2_DV_1080P30:
		printf("%s:\n Mode set is 1080P30\n", APP_NAME);
		system ("echo 1080p-30 > /sys/devices/platform/vpss/display0/mode");
		break;
	default:
		printf("%s:\n Mode set is %d\n", APP_NAME, capt.dv_preset.preset);
	}
	if (ioctl(capt.fd, VIDIOC_S_DV_PRESET, &capt.dv_preset)) {
		printf("Setting DV Preset failed\n");
		exit(2);
	}
	//system("echo 1 > /sys/devices/platform/vpss/display0/enabled");
	return 0;
}
/* Open display driver and set format according to resolution on capture */
static int initDisplay(void)
{
	int mode = O_RDWR;
	struct v4l2_capability cap;

	/* Open display driver */
	disp.fd = open((const char *)DISPLAY_DEVICE, mode);
	if (disp.fd == -1) {
		printf("failed to open display device\n");
		return -1;
	}
	/* Query driver capability */
	if (ioctl(disp.fd, VIDIOC_QUERYCAP, &disp.cap)) {
		printf("Query capability failed for display\n");
		exit(2);
	}  else {
		printf("Driver Name: %s\n", cap.driver);
		printf("Driver bus info: %s\n", cap.bus_info);
		if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)
			printf("Driver is capable of doing capture\n");
		if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
			printf("Driver is capabled of scaling and cropping\n");

	}
	return 0;
}
/* Setup capture driver */
int setupCapture(void)
{
	int ret, i;

	/* Get current format */
	capt.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	ret = ioctl(capt.fd, VIDIOC_G_FMT, &capt.fmt);
	if (ret < 0) {
		printf("Set Format failed\n");
		return -1;
	}
        //--------Added by debasish --------------------//

        printf("%s: width = %d\n", APP_NAME, capt.fmt.fmt.pix.width);
        printf("%s: height = %d\n", APP_NAME, capt.fmt.fmt.pix.height);
        printf("%s: bytesperline = %d\n", APP_NAME, capt.fmt.fmt.pix.bytesperline);
        printf("%s: sizeimage = %d\n", APP_NAME, capt.fmt.fmt.pix.sizeimage);

        if(capt.fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
                printf("%s: pixelformat = V4L2_PIX_FMT_RGB24\n", APP_NAME);
        else if(capt.fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
                printf("%s: pixelformat = V4L2_PIX_FMT_YUYV\n", APP_NAME);
        else if(capt.fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
                printf("%s: pixelformat = Others\n", APP_NAME);
#if 1

        if(capt.dv_preset.preset == V4L2_DV_576P50) {
                capt.fmt.fmt.pix.width = 720;
                capt.fmt.fmt.pix.height = 576;
        }  else {
                printf("%s: Wrong preset value\n", APP_NAME);
                capt.fmt.fmt.pix.width = 720;
                capt.fmt.fmt.pix.height = 576 ;
        }

#endif

        //---------------------------------------------//
#if 0          //commented by debasish
	/* Set format according to mode detected */
	if (capt.dv_preset.preset == V4L2_DV_720P60) {
		capt.fmt.fmt.pix.width = 1280;
		capt.fmt.fmt.pix.height = 720;
	} else if (capt.dv_preset.preset == V4L2_DV_1080P60) {
		capt.fmt.fmt.pix.width = 1920;
		capt.fmt.fmt.pix.height = 1080;
	}  else {
		capt.fmt.fmt.pix.width = 1920;
		capt.fmt.fmt.pix.height = 1080;
	}
#endif
        
       printf("\nThe value of capt.fmt.fmt.pix.bytesperline:%d\n",capt.fmt.fmt.pix.bytesperline);
       printf("\nThe value of capt.fmt.fmt.pix.sizeimage:%d\n",capt.fmt.fmt.pix.sizeimage);

	capt.fmt.fmt.pix.bytesperline = capt.fmt.fmt.pix.width * 2;
	capt.fmt.fmt.pix.sizeimage = capt.fmt.fmt.pix.bytesperline *
		capt.fmt.fmt.pix.height;
	ret = ioctl(capt.fd, VIDIOC_S_FMT, &capt.fmt);
	if (ret < 0) {
		printf("Set Format failed\n");
		return -1;
	}
	/* Get format again and print it on console */
	capt.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	ret = ioctl(capt.fd, VIDIOC_G_FMT, &capt.fmt);
	if (ret < 0) {
		printf("Set Format failed\n");
		return -1;
	}
	printFormat("Capture", &capt.fmt);

	/* Request buffers. We are operating in userPtr mode */
	capt.reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	capt.reqbuf.count = MAX_BUFFER;
	capt.reqbuf.memory = V4L2_MEMORY_USERPTR;
	ret = ioctl(capt.fd, VIDIOC_REQBUFS, &capt.reqbuf);
	if (ret < 0) {
		printf("Could not allocate the buffers\n");
		return -1;
	}
	//return 0;
#if 0
        //----------Added by debasish ----------------//
              /* Mmap the driver buffers in application space so that application
         * can write on to them. Driver allocates contiguous memory for
         * three buffers. These buffers can be displayed one by one. */
        capt.buffersize = capt.fmt.fmt.pix.sizeimage;
        capt.buffer_addr[0] = (unsigned char*)capt.myCaptureBuffer;

        if (capt.buffer_addr[0] == NULL) {
                printf("MMap capt Failed.\n");
                return -1;
        }
        /* Store each buffer addresses in the local variable. These buffer
         * addresses can be used to fill the image. */
        for (i = 1; i < MAX_BUFFER; i++)
                capt.buffer_addr[i] = capt.buffer_addr[i-1] + capt.buffersize;

        memset(capt.buffer_addr[0], 0x00, capt.buffersize * MAX_BUFFER);

        printf("%s: Out %s\n", APP_NAME, __FUNCTION__);
 
        //-------------------------------------------//
#endif
	return 0;
}

/* Setup display driver */
int setupDisplay(void)
{
	int ret;

	/* Get format */
	disp.fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	ret = ioctl(disp.fd, VIDIOC_G_FMT, &disp.fmt);
	if (ret < 0) {
		printf("Get Format failed\n");
		return -1;
	}
	/* Set format according to display mode */
	if (capt.dv_preset.preset == V4L2_DV_720P60) {
		disp.fmt.fmt.pix.width = 1280;
		disp.fmt.fmt.pix.height = 720;
	} else if (capt.dv_preset.preset == V4L2_DV_1080P60) {
		disp.fmt.fmt.pix.width = 1920;
		disp.fmt.fmt.pix.height = 1080;
	}  else {
		disp.fmt.fmt.pix.width = 1920;
		disp.fmt.fmt.pix.height = 1080;
	}
	disp.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
	disp.fmt.fmt.pix.bytesperline = disp.fmt.fmt.pix.width * 2;
	disp.fmt.fmt.pix.sizeimage = disp.fmt.fmt.pix.bytesperline *
		disp.fmt.fmt.pix.height;
	ret = ioctl(disp.fd, VIDIOC_S_FMT, &disp.fmt);
	if (ret < 0) {
		printf("Set Format failed\n");
		return -1;
	}
	/* Get format again and display it on console */
	disp.fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	ret = ioctl(disp.fd, VIDIOC_G_FMT, &disp.fmt);
	if (ret < 0) {
		printf("Get Format failed for display\n");
		return -1;
	}
	printFormat("Display", &disp.fmt);
	/* Requests buffers, we are operating in userPtr mode */
	disp.reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	disp.reqbuf.count = MAX_BUFFER;
	disp.reqbuf.memory = V4L2_MEMORY_USERPTR;
	ret = ioctl(disp.fd, VIDIOC_REQBUFS, &disp.reqbuf);
	if (ret < 0) {
		perror("Could not allocate the buffers\n");
		return -1;
	}
	return 0;
}
/* Stop capture */
static int stopCapture(void)
{

	/* Stop capture */
	int a = V4L2_BUF_TYPE_VIDEO_CAPTURE, ret;
	ret = ioctl(capt.fd, VIDIOC_STREAMOFF, &a);
	if (ret < 0) {
		perror("VIDIOC_STREAMOFF\n");
		return -1;
	}
	return 0;
}
/* Stop display */
static int stopDisplay(void)
{
	int a = V4L2_BUF_TYPE_VIDEO_OUTPUT, ret;
	ret = ioctl(disp.fd, VIDIOC_STREAMOFF, &a);
	if (ret < 0) {
		perror("VIDIOC_STREAMOFF\n");
		return -1;
	}
	return 0;
}
/* Start display */
static int startDisplay(void)
{
	int a = V4L2_BUF_TYPE_VIDEO_OUTPUT, ret;
	ret = ioctl(disp.fd, VIDIOC_STREAMON, &a);
	if (ret < 0) {
		perror("VIDIOC_STREAMON\n");
		return -1;
	}
	return 0;
}
/* Start capture */
static int startCapture(void)
{
	int a = V4L2_BUF_TYPE_VIDEO_CAPTURE, ret;
	ret = ioctl(capt.fd, VIDIOC_STREAMON, &a);
	if (ret < 0) {
		perror("VIDIOC_STREAMON\n");
		return -1;
	}
	return 0;
}
/* Start display */
static int deInitCapture(void)
{
	if (close(capt.fd))
		return -1;
	return 0;
}

/* Close display */
static int deInitDisplay(void)
{
	if (close(disp.fd))
		return -1;
	return 0;
}

/* Get fix screeninfo on fbdev */
static int get_fixinfo(struct fb_fix_screeninfo *fixinfo)
{
	int ret;
	ret = ioctl(fbdev_fd, FBIOGET_FSCREENINFO, fixinfo);
	if (ret < 0) {
		perror("Error reading fixed information.\n");
		return ret;
	}
#ifdef SALOOPBACK_DEBUG
	printf("\nFix Screen Info:\n");
	printf("----------------\n");
	printf("Line Length - %d\n", fixinfo->line_length);
	printf("Physical Address = %lx\n", fixinfo->smem_start);
	printf("Buffer Length = %d\n", fixinfo->smem_len);
#endif
	return 0;
}
/* Get variable screeninfo on FBDEV */
static int get_varinfo(struct fb_var_screeninfo *varinfo)
{
	int ret;

	ret = ioctl(fbdev_fd, FBIOGET_VSCREENINFO, varinfo);
	if (ret < 0) {
		perror("Error reading variable information.\n");
		return ret;
	}
#ifdef SALOOPBACK_DEBUG
	printf("\nVar Screen Info:\n");
	printf("----------------\n");
	printf("Xres - %d\n", varinfo->xres);
	printf("Yres - %d\n", varinfo->yres);
	printf("Xres Virtual - %d\n", varinfo->xres_virtual);
	printf("Yres Virtual - %d\n", varinfo->yres_virtual);
	printf("nonstd       - %d\n", varinfo->nonstd);
	printf("Bits Per Pixel - %d\n", varinfo->bits_per_pixel);
	printf("blue lenth %d msb %d offset %d\n",
			varinfo->blue.length,
			varinfo->blue.msb_right,
			varinfo->blue.offset);
	printf("red lenth %d msb %d offset %d\n",
			varinfo->red.length,
			varinfo->red.msb_right,
			varinfo->red.offset);
	printf("green lenth %d msb %d offset %d\n",
			varinfo->green.length,
			varinfo->green.msb_right,
			varinfo->green.offset);
	printf("trans lenth %d msb %d offset %d\n",
			varinfo->transp.length,
			varinfo->transp.msb_right,
			varinfo->transp.offset);
#endif
	return 0;

}
/* We derive buffers from fbdev for userpointer operation.
 * We have to setupBuffers
 * fbdev to get enough number of buffers and with enough size
 *
 */
static int setupBuffers(void)
{
	struct fb_fix_screeninfo fixinfo;
	struct fb_var_screeninfo varinfo, org_varinfo;
	int ret;
	int buffersize;
	int i;
#if 1 
	/*Open FB device*/
	fbdev_fd = open("/dev/fb0", O_RDWR);
	if (fbdev_fd <= 0) {
		perror("Could not open fb device\n");
		return -1;
	}
	/* Get fix screen information. Fix screen information gives
	 * fix information like panning step for horizontal and vertical
	 * direction, line length, memory mapped start address and length etc.
	 */
	if (get_fixinfo(&fixinfo)) {
		perror("Could not get fixed screen info\n");
		return -1;
	}
	/* Get variable screen information. Variable screen information
	 * gives informtion like size of the image, bites per pixel,
	 * virtual size of the image etc. */
	if (get_varinfo(&varinfo)) {
		perror("getting variable screen info failed\n");
		return -1;
	}
	/*store the original information*/
	memcpy(&org_varinfo, &varinfo, sizeof(varinfo));

	/*
	 * Set the resolution which read before again to prove the
	 * FBIOPUT_VSCREENINFO ioctl, except virtual part which is required for
	 * panning.
	 */
	varinfo.xres = disp.fmt.fmt.pix.width;
	varinfo.yres = disp.fmt.fmt.pix.height;
	varinfo.xres_virtual = varinfo.xres;
	varinfo.yres_virtual = varinfo.yres * MAX_BUFFER;
	varinfo.bits_per_pixel = 16;
	varinfo.transp.offset = 0;
	varinfo.transp.length = 0;
	varinfo.transp.msb_right = 0;
	varinfo.red.offset = 16;
	varinfo.red.length = 5;
	varinfo.blue.offset = 0;
	varinfo.blue.length = 5;
	varinfo.green.offset = 8;
	varinfo.green.length = 6;

#if 0
	ret = ioctl(fbdev_fd, FBIOPUT_VSCREENINFO, &varinfo);
	if (ret < 0) {
		perror("Error writing variable information.\n");
		return -1;
	}
#endif
	if (get_varinfo(&varinfo)) {
		perror("Error getting variable screen information\n");
		return -1;
	}
	/* It is better to get fix screen information again. its because
	 * changing variable screen info may also change fix screen info. */
	ret = ioctl(fbdev_fd, FBIOGET_FSCREENINFO, &fixinfo);
	if (ret < 0) {
		perror("Error reading fixed information.\n");
		return -1;
	}

	/* Get fix screen information. Fix screen information gives
	 * fix information like panning step for horizontal and vertical
	 * direction, line length, memory mapped start address and length etc.
	 */
	if (get_fixinfo(&fixinfo)) {
		perror("Getting fixed screen info failed\n");
		return -1;
	}
	/* Mmap the driver buffers in application space so that application
	 * can write on to them. Driver allocates contiguous memory for
	 * three buffers. These buffers can be displayed one by one. */
#endif
	buffersize = fixinfo.line_length * varinfo.yres;
	buffer_addr[0] = (unsigned char *)mmap(0,
			buffersize *  MAX_BUFFER,
			(PROT_READ | PROT_WRITE),
			MAP_SHARED, fbdev_fd, 0);
	for (i = 1; i < MAX_BUFFER; i++)
		buffer_addr[i] = buffer_addr[i-1] + buffersize;

	memset(buffer_addr[0], 0xFF, buffersize * MAX_BUFFER);
	return 0;
}
/* Prime capture buffers */
static int queueCaptureBuffers(void)
{
	int ret, i;
	for (i = 0; i < (MAX_BUFFER / 2); i++) {
		capt.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		capt.buf.memory = V4L2_MEMORY_USERPTR;
		capt.buf.index = i;
		capt.buf.m.userptr = (unsigned long)buffer_addr[capt.buf.index];
		capt.buf.length = capt.fmt.fmt.pix.sizeimage;
		ret = ioctl(capt.fd, VIDIOC_QBUF, &capt.buf);
		if (ret < 0) {
			perror("VIDIOC_QBUF\n");
			return -1;
		}
	}
	return ret;
}
/* Prime display buffers */
static int queueDisplayBuffers(void)
{
	int ret, i;
	for (i = (MAX_BUFFER / 2); i < MAX_BUFFER; i++) {
		disp.buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
		disp.buf.memory = V4L2_MEMORY_USERPTR;
		disp.buf.index = i - (MAX_BUFFER / 2);
		disp.buf.m.userptr = (unsigned long)buffer_addr[i];
		disp.buf.length = capt.fmt.fmt.pix.sizeimage;
		ret = ioctl(disp.fd, VIDIOC_QBUF, &disp.buf);
		if (ret < 0) {
			perror("VIDIOC_QBUF\n");
			return -1;
		}
	}
	return 0;
}
/* This is a utility function to calculate time  between start and stop. This
 * is used to calculate FPS
 */
static int calc_result_time(struct timeval *result, struct timeval *after,
		struct timeval *before)
{
	/* Perform the carry for the later subtraction by updating "before" */
	if (after->tv_usec < before->tv_usec) {
		int nsec = (before->tv_usec - after->tv_usec) / 1000000 + 1;
		before->tv_usec -= 1000000 * nsec;
		before->tv_sec += nsec;
	}
	if (after->tv_usec - before->tv_usec > 1000000) {
		int nsec = (after->tv_usec - before->tv_usec) / 1000000;

		before->tv_usec += 1000000 * nsec;
		before->tv_sec -= nsec;
	}
	/* Compute the time remaining to wait, tv_usec is certainly positive.
	 * */
	result->tv_sec = after->tv_sec - before->tv_sec;
	result->tv_usec = after->tv_usec - before->tv_usec;
	/* Return 1 if result is negative. */
	return after->tv_sec < before->tv_sec;
}
/* Main function */
int main(int argc, char *argv[])
{
	int i = 0, ret = 0;
	struct v4l2_buffer temp_buf;
	struct timeval before, after, result;

	/* Divert fbdev to dvo2 so that it does  not do blending with display*/
	system ("echo 1:dvo2 > /sys/devices/platform/vpss/graphics0/nodes");
	/* Open the capture driver. Query the resolution from the capture driver
	 */
        printf("%s: Call initCapture\n", APP_NAME);
	ret = initCapture();
	if (ret < 0) {
		printf("Error in opening capture device for channel 0\n");
		return ret;
	}
	/* Open the Display driver. */
#if 0    //commented by debasish
	ret = initDisplay();
	if (ret < 0) {
		printf("Error in opening display device for channel 0\n");
		return ret;
	}
#endif 
restart:
	/* Setup the capture driver Step includes
	 * Set the format according to the resolution queried.
	 * request for buffer descriptors for userpointer buffers
	 */
        printf("%s: Call setupCapture\n", APP_NAME);
	ret = setupCapture();
	if (ret < 0) {
		printf("Error in setting up of capture\n");
		return ret;
	}

#if 0   //commented by debasish
	/* Setup the display driver Step includes
	 * Set the format according to the resolution queried by capture.
	 * request for buffer descriptors for userpointer buffers
	 */
	ret = setupDisplay();
	if (ret < 0) {
		printf("Error in setting up of Display\n");
		return ret;
	}
#endif
	/* As application works on userPointer, Buffers for both capture and
	 * display driver are allocated using the fbdev, buffers. Below functionality
	 * setups the fbdev to mmap the buffers and later capture and display
	 * will use those buffers
	 */
        printf("%s: Call setupBuffers\n", APP_NAME);
	ret = setupBuffers();
	if (ret < 0) {
		printf("Error in setting up of Buffers\n");
		return ret;
	}
	/* Total 8 buffers are allocated using fbdev, 4 buffers are primed to
	 * capture driver.
	 */
        printf("%s: Call queueCaptureBuffers\n", APP_NAME);
	ret = queueCaptureBuffers();
	if (ret < 0) {
		printf("Error in queuing capture buffers\n");
		return ret;
	}
#if 0  //commented by debasish
	/* Total 8 buffers are allocated using fbdev, 4 buffers are primed to
	 * display driver.
	 */
	ret = queueDisplayBuffers();
	if (ret < 0) {
		printf("Error in queuing display buffers\n");
		return ret;
	}
	/* Start display driver always first. This is because display driver
	 * takes 2 frames to come out of start. If capture is started first
	 * frame drops will be seen, since capture will already complete two
	 * frame by time display starts
	 */
	ret = startDisplay();
	if (ret < 0) {
		printf("Error starring capture \n");
		return ret;
	}
#endif
	/* Start capture driver after display driver */
        printf("%s: Call startCapture\n", APP_NAME);
	ret = startCapture();
	if (ret < 0) {
		printf("Error starring capture \n");
		return ret;
	}
        printf("\nSuccessful upto startCapture\n");
	/* Get time of day to calculate FPS */
	gettimeofday(&before, NULL);
	/* Start the steady state loop. Following steps are followed
	 * 1 dequeue buffer from capture
	 * 2 dequeue buffer from display
	 * 3 exchange capture and display buffer pointers
	 * 4 queue dislay buffer pointer to capture
	 * 5 queue capture buffer pointer to display
	 */
	for (i = 0; i < MAXLOOPCOUNT; i++) {
		/* Dq capture buffer */
		ret = ioctl(capt.fd, VIDIOC_DQBUF, &capt.buf);
		if (ret < 0) {
			perror("VIDIOC_DQBUF\n");
			return -1;
		}
		/* Because of IP bugs, capture hardware gets locked up once in
		 * a while. In that case DQbuf will return  V4L2_BUF_FLAG_ERROR
		 * in flags.
		 */
		if (capt.buf.flags & V4L2_BUF_FLAG_ERROR) {
			/* If DQbuf returned error check for the hardware lockup
			 */
			ret = ioctl(capt.fd, TICAPT_CHECK_OVERFLOW, &capt.over_flow);
			if (ret < 0) {
				perror("TICAPT_CHECK_OVERFLOW\n");
				return -1;
			} else {
				/* If hardware locked up, restart display and
				 * capture driver
				 */
				if (capt.over_flow.porta_overflow) {
					printf("Port a overflowed\n\n\n\n\n\n\n");
					stopCapture();
					stopDisplay();
					goto restart;

				}
				if (capt.over_flow.portb_overflow) {
					printf("Port b overflowed\n\n\n\n\n\n\n");
					stopCapture();
					stopDisplay();
					goto restart;
				}
			}
		}
		/* DQ display buffer */
		ret = ioctl(disp.fd, VIDIOC_DQBUF, &disp.buf);
		if (ret < 0) {
			perror("VIDIOC_DQBUF Display\n");
			return -1;
		}
		/* Exchange display and capture buffer pointers */
		temp_buf.m.userptr = capt.buf.m.userptr;
		capt.buf.m.userptr = disp.buf.m.userptr;
		disp.buf.m.userptr = temp_buf.m.userptr;
		/* Queue the capture buffer with updated address */
		ret = ioctl(capt.fd, VIDIOC_QBUF, &capt.buf);
		if (ret < 0) {
			perror("VIDIOC_QBUF\n");
			return -1;
		}
		disp.buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
		disp.buf.memory = V4L2_MEMORY_USERPTR;
		disp.buf.length = capt.fmt.fmt.pix.sizeimage;
		/* Queue the display buffer back with updated address */
		ret = ioctl(disp.fd, VIDIOC_QBUF, &disp.buf);
		if (ret < 0) {
			perror("VIDIOC_QBUF Display\n");
			return -1;
		}
		if ((i % 1000) == 0)
			printf("Count=%d\n", i);
	}
	/* Get end time to calculate FPS */
	gettimeofday(&after, NULL);
	/* Calculate FPS */
	calc_result_time(&result, &after, &before);
	printf("Frame rate = %lu\n", MAXLOOPCOUNT/result.tv_sec);
	/* Stop capture driver */
	ret = stopCapture();
	if (ret < 0) {
		printf("Error in stopping capture\n");
		return ret;
	}
	/* Stop display driver */
	ret = stopDisplay();
	if (ret < 0) {
		printf("Error in stopping display\n");
		return ret;
	}
	/* Deinit capture driver */
	ret = deInitCapture();
	if (ret < 0) {
		printf("Error in capture deInit\n");
		return ret;
	}
	/* Deinit display driver */
	ret = deInitDisplay();
	if (ret < 0) {
		printf("Error in display deInit\n");
		return ret;
	}
	close(fbdev_fd);
	system("echo 0 > /sys/devices/platform/vpss/display0/enabled");
	system ("echo 1080p-60 > /sys/devices/platform/vpss/display0/mode");
	system("echo 0 > /sys/devices/platform/vpss/graphics0/enabled");
	system("echo 1 > /sys/devices/platform/vpss/display0/enabled");
	system("echo 1:hdmi > /sys/devices/platform/vpss/graphics0/nodes");
	return 0;
}