RE: [PATCH-V2 7/7] TVP514x: Add Powerup sequence during s_input to lock the signal properly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Vaibhav,

See my response with [MK] prefix.
>>
>[Hiremath, Vaibhav] Murali,
>
>I think I had already explained it to you, let me explain it again for
>broader audience.
>
>We are talking about two different issues here -
>
>- The default state of TVP514x after reset is active state, but when you
>execute streamoff then driver will put TVP514x into powered down state,
>which will cause locking issues when you try to S_INPUT next time. Since
>power on sequence will only be get executed during streamon.
>
>This is valid bug in the driver, which this patch addresses.

[MK]  Agree and I am okay with this patch and will sign-off
>
>- The second issue is related to auto switch feature and detected/set
>standard. The fix which you are talking about is putting TVP514x in auto
>switch mode in QUERYSTD. This is only required when application sets the
>standard explicitly and the spec says that the standard should not change
>unless set explicitly by the user. And since user is very well aware of
>what he is doing.
>

[MK] Ok. I looked back at your old email. Again the issue that I was referring to is failure to switch to a new standard in the following scenario:-


Input signal - NTSC
-------------------
Following sequence of call made to tvp driver:-

s_input()
query_std()
s_std() -> set the detected standard
stream on
stream off

Input signal changed to PAL

s_input() -> fails here

Here is what you had explained earlier (reproduced for discussion)

>2) Now we have 2 inputs, one with NTSC and other with PAL, the first >detected input will work without any issues, wince the signal has locked. >Say for example,

>First time you started streaming with CVBS-NTSC, with following sequence,

>S_INPUT (CVBS)
>QUERYSTD
>S_STD (NTSC)

>Now here you are explicitly setting the standard,

[MK] For S_STD ioctl, the vpfe_capture calls s_std() of tvp5146 to set the standard and if successful set the standard in the capture. So in this case
do you mean, the s_std call is causing the problem at tvp? Do you expect the vpfe_capture not calling s_std() of tvp514x at all? Or should it call
query_std() instead when it is supported and s_std() when sub device doesn't 
have the query capability. In that case, why do we need s_std() at all. We
will be better of by removing that call.

>so when you again come back to s_input with S-Video (PAL), the TVP is not >going to lock the standard because, you did S_STD with NTSC in last attempt.

[MK] So when you say tvp is not going to lock the standard, is it a hardware behavior? Here the s_input() is called and it fails because no signal locked at the input. IMO, since tvp has auto detect feature, it should enable auto detect every time there is a call to s_input and attempt to do auto detection and shouldn't fail because last time user has set standard NTSC.  

>The V4L2 spec says when user explicitly sets the standard then he is aware >of what exactly he is doing and he has to take care of it. 

[MK] Not sure what you mean by "he has to take care of it". Reboot the box to recover? If I understand you correctly, what you are saying is when the  input signal is NTSC and user sets standard to PAL what is the expected behavior. I think driver should do auto detect and gracefully returns -EINVAL if the detected standard is different from user requested standard and shouldn't result in a state where the board has to be rebooted.

>I had a good discussion with Hans on this; please refer to the link below
>
>http://www.mail-archive.com/linux-media@xxxxxxxxxxxxxxx/msg11518.html
>
>I was about to re-initiate this thread, since we did not have any
>conclusion last time.

[MK] If required, you can re-initiate a separate thread to discuss this.

>
>I hope this clears all your doubts.
>
>Thanks,
>Vaibhav
>
>> Murali Karicheri
>> Software Design Engineer
>> Texas Instruments Inc.
>> Germantown, MD 20874
>> phone: 301-407-9583
>> email: m-karicheri2@xxxxxx
>>
>> >-----Original Message-----
>> >From: Hiremath, Vaibhav
>> >Sent: Friday, March 19, 2010 2:04 AM
>> >To: linux-media@xxxxxxxxxxxxxxx
>> >Cc: Karicheri, Muralidharan; Hiremath, Vaibhav; Rajashekhara, Sudhakar
>> >Subject: [PATCH-V2 7/7] TVP514x: Add Powerup sequence during s_input to
>> >lock the signal properly
>> >
>> >From: Vaibhav Hiremath <hvaibhav@xxxxxx>
>> >
>> >For the sequence streamon -> streamoff and again s_input, it fails
>> >to lock the signal, since streamoff puts TVP514x into power off state
>> >which leads to failure in sub-sequent s_input.
>> >
>> >So add powerup sequence in s_routing (if disabled), since it is
>> >important to lock the signal at this stage.
>> >
>> >Signed-off-by: Vaibhav Hiremath <hvaibhav@xxxxxx>
>> >Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@xxxxxx>
>> >---
>> > drivers/media/video/tvp514x.c |   13 +++++++++++++
>> > 1 files changed, 13 insertions(+), 0 deletions(-)
>> >
>> >diff --git a/drivers/media/video/tvp514x.c
>b/drivers/media/video/tvp514x.c
>> >index 26b4e71..97b7db5 100644
>> >--- a/drivers/media/video/tvp514x.c
>> >+++ b/drivers/media/video/tvp514x.c
>> >@@ -78,6 +78,8 @@ struct tvp514x_std_info {
>> > };
>> >
>> > static struct tvp514x_reg tvp514x_reg_list_default[0x40];
>> >+
>> >+static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
>> > /**
>> >  * struct tvp514x_decoder - TVP5146/47 decoder object
>> >  * @sd: Subdevice Slave handle
>> >@@ -643,6 +645,17 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
>> > 		/* Index out of bound */
>> > 		return -EINVAL;
>> >
>> >+	/*
>> >+	 * For the sequence streamon -> streamoff and again s_input
>> >+	 * it fails to lock the signal, since streamoff puts TVP514x
>> >+	 * into power off state which leads to failure in sub-sequent s_input.
>> >+	 *
>> >+	 * So power up the TVP514x device here, since it is important to lock
>> >+	 * the signal at this stage.
>> >+	 */
>> >+	if (!decoder->streaming)
>> >+		tvp514x_s_stream(sd, 1);
>> >+
>> > 	input_sel = input;
>> > 	output_sel = output;
>> >
>> >--
>> >1.6.2.4

--- Begin Message ---
Vaibhav,

I have tested this one more time...

I see the same issue. I am also attaching the application that I used....
Check the function set_data_format(). This used the same sequence as
suggested by you...

S_INPUT
QUERYSTD
S_STD.

Send me your version of tvp514x, and I will try it tomorrow. It will be
great if we can discuss this tomorrow morning over phone so that we can have a quick resolution. I will be at my work around 9:30AM EST. If available, What number can I reach you tomorrow morning?

regards,

Murali Karicheri
Software Design Engineer
Texas Instruments Inc.
Germantown, MD 20874
phone: 301-407-9583
email: m-karicheri2@xxxxxx

>-----Original Message-----
>From: Karicheri, Muralidharan
>Sent: Thursday, February 25, 2010 3:33 PM
>To: Hiremath, Vaibhav; Jadav, Brijesh R
>Cc: Narnakaje, Snehaprabha
>Subject: RE: NTSC-PAL switching...
>
>Vaibhav,
>
>
>>> Vaibhav & Brijesh,
>>>
>>> I think we still need Brijesh's patch to get this working.
>>[Hiremath, Vaibhav] Logically it is not required; the change I sent you
>>should work.
>
>The code that I sent to you is from Arago tree. As far I Know, Brijesh
>has changed it recently to resolve the NTSC->PAL switching issue. I am
>attaching the version from Arago to this attachment..
>
>
>>I need to understand in details here. If you could send me exact steps you
>>are following then I could try it here at my end.
>
>I had mentioned the steps in my original email....
>
>1) Power On the evm (DM365)
>2) Play DVD NTSC video
>3) run the looback application for NTSC capture and display. The
>loopback runs fine for NTSC. stop the application (either cntrl-C or wait
>for application to exit)
>4) stop video and change the mode in DVD player to play PAL video. Wait
>for few minutes to have the DVD player play the video.
>5) re-run the application for PAL capture and display.
>
>In step 5) the query_std fails (no locking).
>
>>
>>> I am attaching
>>> the tvp514x.c that I use to this email. I am using the kernel from Arago
>>> tree below. With this file, I am able to switch from NTSC -> PAL -> NTSC.
>>> So Could you send me a patch for this based on the tree below?
>>>
>>[Hiremath, Vaibhav] I do not have this tree cloned at my end, is tvp514x.c
>>driver under this tree different than available in main-line (which I
>>believe should not be)?
>>
>I have attached the version in Arago to this email. I will checkout one
>more
>time and let you know if I made any mistake....
>
>>
>>Thanks,
>>Vaibhav Hiremath
>>
>>> http://arago-project.org/git/people/sneha/linux-davinci-staging.git
>>>
>>>
>>> Murali Karicheri
>>> Software Design Engineer
>>> Texas Instruments Inc.
>>> Germantown, MD 20874
>>> phone: 301-407-9583
>>> email: m-karicheri2@xxxxxx
>>>
>>> >-----Original Message-----
>>> >From: Karicheri, Muralidharan
>>> >Sent: Thursday, February 25, 2010 11:46 AM
>>> >To: Hiremath, Vaibhav; Jadav, Brijesh R
>>> >Cc: Narnakaje, Snehaprabha
>>> >Subject: RE: NTSC-PAL switching...
>>> >
>>> >Vaibhav,
>>> >
>>> >Is this patch against the tvp514x.c in Arago tree? What happened to the
>>fix
>>> >that Brijesh has put in tvp514x_s_routing()? Since I don't see the code
>>in
>>> >your diff below, I have removed that code from tvp514x_s_routing() and
>>> >replaced it with the one below. Also I have changed the application to
>>do
>>> >QUERYSTD followed by S_STD. I still get problem in switching from NTSC
>>to
>>> >PAL...
>>> >
>>> >Could you send me the tvp514x.c file that you are using along with the
>>> >application ?
>>> >
>>> >Murali Karicheri
>>> >Software Design Engineer
>>> >Texas Instruments Inc.
>>> >Germantown, MD 20874
>>> >phone: 301-407-9583
>>> >email: m-karicheri2@xxxxxx
>>> >
>>> >>-----Original Message-----
>>> >>From: Hiremath, Vaibhav
>>> >>Sent: Thursday, February 25, 2010 10:16 AM
>>> >>To: Karicheri, Muralidharan; Jadav, Brijesh R
>>> >>Cc: Narnakaje, Snehaprabha
>>> >>Subject: RE: NTSC-PAL switching...
>>> >>
>>> >>But as mentioned by Brijesh, the steps you are following is not
>correct.
>>> >>You may run into issues.
>>> >>
>>> >>Thanks,
>>> >>Vaibhav Hiremath
>>> >>
>>> >>> -----Original Message-----
>>> >>> From: Karicheri, Muralidharan
>>> >>> Sent: Thursday, February 25, 2010 8:29 PM
>>> >>> To: Jadav, Brijesh R; Hiremath, Vaibhav
>>> >>> Cc: Narnakaje, Snehaprabha
>>> >>> Subject: RE: NTSC-PAL switching...
>>> >>>
>>> >>> Brijesh & Vaibhav,
>>> >>>
>>> >>> Thanks for your patch.
>>> >>>
>>> >>> But the vpif application on Arago tree doesn't show this. I guess it
>>> >>should
>>> >>> work both cases.
>>> >>>
>>> >>> Murali Karicheri
>>> >>> Software Design Engineer
>>> >>> Texas Instruments Inc.
>>> >>> Germantown, MD 20874
>>> >>> phone: 301-407-9583
>>> >>> email: m-karicheri2@xxxxxx
>>> >>>
>>> >>> >-----Original Message-----
>>> >>> >From: Jadav, Brijesh R
>>> >>> >Sent: Thursday, February 25, 2010 1:41 AM
>>> >>> >To: Hiremath, Vaibhav; Karicheri, Muralidharan
>>> >>> >Cc: Narnakaje, Snehaprabha
>>> >>> >Subject: RE: NTSC-PAL switching...
>>> >>> >
>>> >>> >Murali,
>>> >>> >
>>> >>> >I think the correct sequence to be followed in the application is
>>> >>S_INPUT,
>>> >>> >QUERYSTD and S_STD.
>>> >>> >
>>> >>> >Thanks,
>>> >>> >Brijesh Jadav
>>> >>> >
>>> >>> >-----Original Message-----
>>> >>> >From: Hiremath, Vaibhav
>>> >>> >Sent: Thursday, February 25, 2010 10:44 AM
>>> >>> >To: Karicheri, Muralidharan; Jadav, Brijesh R
>>> >>> >Cc: Narnakaje, Snehaprabha
>>> >>> >Subject: RE: NTSC-PAL switching...
>>> >>> >
>>> >>> >Murali,
>>> >>> >This issue has already been fixed and I (or Sudhakar) will send a
>>patch
>>> >>to
>>> >>> >list.
>>> >>> >
>>> >>> >The fix is something -
>>> >>> >
>>> >>> >diff --git a/drivers/media/video/tvp514x.c
>>> >>b/drivers/media/video/tvp514x.c
>>> >>> >index b344b58..0253d87 100644
>>> >>> >--- a/drivers/media/video/tvp514x.c
>>> >>> >+++ b/drivers/media/video/tvp514x.c
>>> >>> >@@ -78,6 +78,8 @@ struct tvp514x_std_info {
>>> >>> > };
>>> >>> >
>>> >>> > static struct tvp514x_reg tvp514x_reg_list_default[0x40];
>>> >>> >+
>>> >>> >+static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
>>> >>> > /**
>>> >>> >  * struct tvp514x_decoder - TVP5146/47 decoder object
>>> >>> >  * @sd: Subdevice Slave handle
>>> >>> >@@ -658,6 +660,13 @@ static int tvp514x_s_routing(struct
>v4l2_subdev
>>> >*sd,
>>> >>> >                /* Index out of bound */
>>> >>> >                return -EINVAL;
>>> >>> >
>>> >>> >+       /*
>>> >>> >+        * For the sequence streamon -> streamoff and again s_input,
>>> >>most
>>> >>> >of
>>> >>> >+        * the time it fails to lock the signal, since streamoff
>>puts
>>> >>> >TVP514x
>>> >>> >+        * into power off state which leads to failure in sub-
>>sequent
>>> >>> >s_input.
>>> >>> >+        */
>>> >>> >+       tvp514x_s_stream(sd, 1);
>>> >>> >+
>>> >>> >        input_sel = input;
>>> >>> >        output_sel = output;
>>> >>> >
>>> >>> >
>>> >>> >
>>> >>> >Hope this will help you.
>>> >>> >
>>> >>> >
>>> >>> >Thanks,
>>> >>> >Vaibhav Hiremath
>>> >>> >> -----Original Message-----
>>> >>> >> From: Karicheri, Muralidharan
>>> >>> >> Sent: Thursday, February 25, 2010 4:55 AM
>>> >>> >> To: Karicheri, Muralidharan; Hiremath, Vaibhav; Jadav, Brijesh R
>>> >>> >> Cc: Narnakaje, Snehaprabha
>>> >>> >> Subject: RE: NTSC-PAL switching...
>>> >>> >>
>>> >>> >> A quick update...
>>> >>> >>
>>> >>> >> I moved the while loop in tvp514x_s_routing() to querystd() and
>it
>>> >>seems
>>> >>> >to
>>> >>> >> work fine. I have tried switching from PAL->NTSC->PAL a couple of
>>> >>times
>>> >>> >and
>>> >>> >> it worked fine.
>>> >>> >>
>>> >>> >> I know this is not the right fix. The root cause to fix is why
>the
>>> >>> >> tvp514x_s_routing() not able to detect the correct standard first
>>> >time.
>>> >>> >The
>>> >>> >> STD bits in the status registers seems to remember the last
>>standard
>>> >>> >> detected. Any comments ??
>>> >>> >>
>>> >>> >> Murali Karicheri
>>> >>> >> Software Design Engineer
>>> >>> >> Texas Instruments Inc.
>>> >>> >> Germantown, MD 20874
>>> >>> >> phone: 301-407-9583
>>> >>> >> email: m-karicheri2@xxxxxx
>>> >>> >>
>>> >>> >> >-----Original Message-----
>>> >>> >> >From: Karicheri, Muralidharan
>>> >>> >> >Sent: Wednesday, February 24, 2010 6:12 PM
>>> >>> >> >To: Hiremath, Vaibhav; Jadav, Brijesh R
>>> >>> >> >Cc: Narnakaje, Snehaprabha
>>> >>> >> >Subject: NTSC-PAL switching...
>>> >>> >> >
>>> >>> >> >Hi,
>>> >>> >> >
>>> >>> >> >There was an IR against this issue and it was fixed by Brijesh
>>> >though
>>> >>> >> >changes to tvp514x.c. I am running the latest release from Arago
>>and
>>> >>> >> >I am running into the same issue.
>>> >>> >> >
>>> >>> >> >Here are the steps I am invoking...
>>> >>> >> >
>>> >>> >> >The evm input is composite and is connected to output of DVD
>>player.
>>> >>> >> >
>>> >>> >> >1) Power On the evm (DM365)
>>> >>> >> >2) Play DVD NTSC video
>>> >>> >> >3) run the looback application for NTSC capture and display. The
>>> >>> >loopback
>>> >>> >> >runs fine for NTSC. stop the application (either cntrl-C or wait
>>for
>>> >>> >> >application to exit)
>>> >>> >> >4) stop video and change the mode in DVD player to play PAL
>video.
>>> >>Wait
>>> >>> >for
>>> >>> >> >few minutes to have the DVD player play the video.
>>> >>> >> >5) re-run the application for PAL capture and display.
>>> >>> >> >
>>> >>> >> >In step 5) the query_std fails (no locking). This was the
>>original
>>> >>issue
>>> >>> >> >and it continues to exist now even after the fix. I have
>verified
>>> >the
>>> >>> >patch
>>> >>> >> >that
>>> >>> >> >Brijesh has for this issue is in the build.
>>> >>> >> >
>>> >>> >> >After putting some debug prints, what I see is in
>>> >tvp514x_s_routing(),
>>> >>> >the
>>> >>> >> >video detected is whatever video played in the previous session
>>> >>though
>>> >>> >> >input has changed since then. Once driver reaches this state,
>>> >>query_std
>>> >>> >> >fails since it can't lock the carrier. During querystd, the
>video
>>> >>> >detected
>>> >>> >> >is correct, but the locking doesn't happen. Any idea why this
>>could
>>> >>be
>>> >>> >> >happening ?
>>> >>> >> >
>>> >>> >> >The application first call S_INPUT and set input to composite.
>It
>>> >>then
>>> >>> >> >calls S_STD and set standard. This is followed by QUERYSTD. I
>>have
>>> >>> >checked
>>> >>> >> >the vpif_userptr_loopback.c which does the same thing. Any help
>>to
>>> >>> >resolve
>>> >>> >> >this issue will be appreciated...
>>> >>> >> >
>>> >>> >> >Regards,
>>> >>> >> >
>>> >>> >> >Murali Karicheri
>>> >>> >> >Software Design Engineer
>>> >>> >> >Texas Instruments Inc.
>>> >>> >> >Germantown, MD 20874
>>> >>> >> >phone: 301-407-9583
>>> >>> >> >email: m-karicheri2@xxxxxx

/*
 * v4l2_userptr_loopback
 *
 * Copyright (C) 2009 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.
 *
*/
/*******************************************************************************
**+--------------------------------------------------------------------------+**
**|                            ****                                          |**
**|                            ****                                          |**
**|                            ******o***                                    |**
**|                      ********_///_****                                   |**
**|                      ***** /_//_/ ****                                   |**
**|                       ** ** (__/ ****                                    |**
**|                           *********                                      |**
**|                            ****                                          |**
**|                            ***                                           |**
**|                                                                          |**
**|         Copyright (c) 1998-2008 Texas Instruments Incorporated           |**
**|                        ALL RIGHTS RESERVED                               |**
**|                                                                          |**
**| Permission is hereby granted to licensees of Texas Instruments           |**
**| Incorporated (TI) products to use this computer program for the sole     |**
**| purpose of implementing a licensee product based on TI products.         |**
**| No other rights to reproduce, use, or disseminate this computer          |**
**| program, whether in part or in whole, are granted.                       |**
**|                                                                          |**
**| TI makes no representation or warranties with respect to the             |**
**| performance of this computer program, and specifically disclaims         |**
**| any responsibility for any damages, special or consequential,            |**
**| connected with the use of this program.                                  |**
**|																			 |**
**|	File: v4l2_userptr_loopback.c											 	 |**
**|																			 |**
**| Description: 															 |**
**|																			 |**
**|   This is a sample loopback application that sense the input video       |**
**| standard at the composite input and play the same for NTSC/PAL display   |**
**|	at the composite output. This uses MMAP IO for capture and display		 |** 
**|	driver. 				                                                 |**
**|                                                                          |**
**+--------------------------------------------------------------------------+**
*******************************************************************************/
/*******************************************************************************
 *	HEADER FILES
 */
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <time.h>

/* Kernel header file, prefix path comes from makefile */
#include <video/davincifb_ioctl.h>
#include <video/davinci_osd.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <media/davinci/davinci_display.h>
#include <media/davinci/videohd.h>

/*******************************************************************************
 *	LOCAL DEFINES
 */
#define CAPTURE_DEVICE	"/dev/video0"

#define WIDTH_NTSC		720
#define HEIGHT_NTSC		480
#define WIDTH_PAL		720
#define HEIGHT_PAL		576
#define WIDTH_720P		1280
#define HEIGHT_720P		720	
#define WIDTH_1080I		1920
#define HEIGHT_1080I		1080

#define MIN_BUFFERS	6

#define UYVY_BLACK	0x10801080

/* Device parameters */
#define VID0_DEVICE	"/dev/video2"
#define VID1_DEVICE	"/dev/video3"
#define OSD0_DEVICE	"/dev/fb0"
#define OSD1_DEVICE	"/dev/fb2"

/* Function error codes */
#define SUCCESS		0
#define FAILURE		-1

/* Bits per pixel for video window */
#define YUV_422_BPP	16
#define BITMAP_BPP_8	8

#define DISPLAY_INTERFACE_COMPOSITE	"COMPOSITE"
#define DISPLAY_INTERFACE_COMPONENT	"COMPONENT"
#define DISPLAY_MODE_PAL	"PAL"
#define DISPLAY_MODE_NTSC	"NTSC"
#define DISPLAY_MODE_720P	"720P-60"		
#define DISPLAY_MODE_1080I	"1080I-30"		

#define round_32(width)	((((width) + 31) / 32) * 32 )

#define VIDEO_NUM_BUFS	6

/* Standards and output information */
#define ATTRIB_MODE		"mode"
#define ATTRIB_OUTPUT		"output"

#define LOOP_COUNT		500

#define DEBUG
#ifdef DEBUG
#define DBGENTER  	printf("%s : Enter\n", __FUNCTION__);
#define DBGEXIT		printf("%s : Leave\n", __FUNCTION__);
#define PREV_DEBUG(x)	printf("DEBUG:%s:%s:%s\n",__FUNCTION__,__LINE__,x);
#else
#define DBGENTER
#define DBGEXIT
#define PREV_DEBUG(x)
#endif

#define CLEAR(x)	memset (&(x), 0, sizeof (x))
static int en_capture_to_file;
int num_frame_to_capture = 100;
#define FILE_CAPTURE "./output.yuv"
FILE *fp_capture;
int file_size;


/*******************************************************************************
 *	STRUCTURE DEFINITIONS
 */
struct buffer {
	void *start;
	size_t length;
};

/*******************************************************************************
 *	FILE GLOBALS
 */
static int fdCapture = -1;
static struct buffer *buffers, vid1Buf[VIDEO_NUM_BUFS];
static int nBuffers;
static int nWidthFinal;
static int nHeightFinal;
static int quit;
static int fd_vid1, fd_osd0, fd_osd1;
static int cr_width = 0, cr_height = 0, cr_top = 0, cr_left = 0, crop_en = 0, src_line_len = 0;
static int stress_test = 1;
static int start_loopCnt = LOOP_COUNT;
static struct v4l2_requestbuffers reqbuf;
static int disppitch, dispheight, dispwidth;
static int numbuffers = VIDEO_NUM_BUFS;
static struct v4l2_cropcap cropcap;
static int printfn = 0;
/* 0 - composite
 * 1 - S-video
 * 2 - Camera
 */
int vpfe_input = 0;
static int input_std;
static int field;
char *inputs[] = { "COMPOSITE", "SVIDEO", "COMPONENT" };
int display_image_size = 0;

/*******************************************************************************
 *	EXTERN VARIABLES
 */
extern int errno;

/*******************************************************************************
 *	LOCAL FUNCTION PROTOTYPES
 */
static int initialize_capture(v4l2_std_id * cur_std);
static int put_display_buffer(int, int);
static int get_display_buffer(int);
static int stop_display(int);
static int release_display(int *);
static int release_capture(int *);
static int stop_capture(int);
static int start_loop(void);
static int init_capture_device(void);
static int set_data_format(v4l2_std_id * cur_std);
static int init_capture_buffers(void);
static int start_streaming(void);
static int start_display(int, int, int);
static int init_vid1_device(v4l2_std_id cur_std);
static int vpbe_UE_1();
static int change_sysfs_attrib(char *attribute, char *value);

/*******************************************************************************
 *	FUNCTION DEFINITIONS
 */
static int initialize_capture(v4l2_std_id * cur_std)
{
	int ret;
	printf("initializing capture device\n");
	init_capture_device();
	printf("setting data format\n");
	ret = set_data_format(cur_std);
	if (ret) {
		printf("Error in setting capture format\n");
		return ret;
	}
	printf("initializing capture buffers\n");
	ret = init_capture_buffers();
	if (ret) {
		printf("Failed to initialize capture buffers\n");
		return ret;
	}
	printf("initializing display device\n");
	ret = start_streaming();
	if (ret) {
		printf("Failed to start capture streaming\n");
		return ret;
	}
	return 0;
}

/*******************************************************************************
 *	Takes the address, finds the appropriate index
 *	of the buffer, and QUEUEs the buffer to display
 *	If this part is done in the main loop,
 *	there is no need of this conversionof address
 *	to index as both are available.
 */
static int put_display_buffer(int vid_win, int index)
{
	struct v4l2_buffer buf;
	int i = 0;
	int ret;

	memset(&buf, 0, sizeof(buf));

	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	buf.memory = V4L2_MEMORY_USERPTR;
	buf.index = index;
	buf.length = display_image_size;
	buf.m.userptr = (unsigned long)buffers[index].start;

	ret = ioctl(vid_win, VIDIOC_QBUF, &buf);
	return ret;
}

/*******************************************************************************
 *	Does a DEQUEUE and gets/returns the address of the
 *	dequeued buffer
 */
static int get_display_buffer(int vid_win)
{
	int ret;
	struct v4l2_buffer buf;
	memset(&buf, 0, sizeof(buf));
	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	ret = ioctl(vid_win, VIDIOC_DQBUF, &buf);
	if (ret < 0) {
		perror("VIDIOC_DQBUF\n");
		return -1;
	}
	return buf.index;
}

/*******************************************************************************
 *	Stops Streaming
 */
static int stop_display(int vid_win)
{
	int ret;
	enum v4l2_buf_type type;
	type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	ret = ioctl(vid_win, VIDIOC_STREAMOFF, &type);
	return ret;
}

/*******************************************************************************
 *	This routine unmaps all the buffers
 *	This is the final step.
 */
static int release_display(int *vid_win)
{
	close(*vid_win);
	*vid_win = 0;
	return 0;
}

/*******************************************************************************
 *      This routine unmaps all the buffers
 *      This is the final step.
 */
static int release_capture(int *vid_win)
{
	int i;
	for (i = 0; i < MIN_BUFFERS; i++) {
		munmap(buffers[i].start, buffers[i].length);
		buffers[i].start = NULL;
	}
	close(*vid_win);
	*vid_win = 0;
	return 0;
}

/*******************************************************************************
 *      Stops Streaming
 */
static int stop_capture(int vid_win)
{
	int ret;
	enum v4l2_buf_type type;
	type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	ret = ioctl(vid_win, VIDIOC_STREAMOFF, &type);
	return ret;
}

/******************************************************************************/
static int start_loop(void)
{
	int ret, display_index;
	struct v4l2_buffer buf;
	static int captFrmCnt = 0;
	unsigned char *displaybuffer = NULL;
	int i;
	char *ptrPlanar = NULL;
	void *src, *dest;

	ptrPlanar = (char *)calloc(1, nWidthFinal * nHeightFinal * 2);

	while (!quit) {
		fd_set fds;
		struct timeval tv;
		int r;


		FD_ZERO(&fds);
		FD_SET(fdCapture, &fds);

		/* Timeout */
		tv.tv_sec = 2;
		tv.tv_usec = 0;
		r = select(fdCapture + 1, &fds, NULL, NULL, &tv);
		if (-1 == r) {
			if (EINTR == errno)
				continue;
			printf("StartCameraCapture:select\n");
			return -1;
		}
		if (0 == r)
			continue;

		CLEAR(buf);
		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_MMAP;

		/* determine ready buffer */
		if (-1 == ioctl(fdCapture, VIDIOC_DQBUF, &buf)) {
			if (EAGAIN == errno)
				continue;
			printf("StartCameraCaputre:ioctl:VIDIOC_DQBUF\n");
			return -1;
		}

		if (en_capture_to_file) {
			if (captFrmCnt == num_frame_to_capture) {
				printf("Writing frame %d to file %s, size = %d\n",num_frame_to_capture,
					 FILE_CAPTURE, file_size);
				fwrite(buffers[buf.index].start, 1, file_size, fp_capture);
				printf("Writing file %s complete\n", FILE_CAPTURE);
				fclose(fp_capture);
			}
		}
		if (captFrmCnt <= 1) {
			
			if (!captFrmCnt) {
				printf("5. Test enque first buffer\n");
				ret = start_display(fd_vid1, buf.index, 0);
			}
			else {
				printf("5. Test enque second buffer\n");
				ret = start_display(fd_vid1, buf.index, 1);
			}
			if (ret < 0) {
				printf("\tError: Starting display failed:VID1\n");
				return ret;
			}
			captFrmCnt++;
			continue;
		}
		
		ret = put_display_buffer(fd_vid1, buf.index);
		if (ret < 0) {
			printf("Error in putting the display buffer\n");
			return ret;
		}

		/******************* V4L2 display ********************/
		display_index = get_display_buffer(fd_vid1);
		if (display_index < 0) {
			printf("Error in getting the  display buffer:VID1\n");
			return ret;
		}
		/***************** END V4L2 display ******************/

		
		if (printfn)
			printf("time:%lu    frame:%u\n", (unsigned long)time(NULL),
		       		captFrmCnt++);

		buf.index = display_index;
		/* requeue the buffer */
		if (-1 == ioctl(fdCapture, VIDIOC_QBUF, &buf))
			printf("StartCameraCaputre:ioctl:VIDIOC_QBUF\n");
		if (stress_test) {
			start_loopCnt--;
			if (start_loopCnt == 0) {
				start_loopCnt = 50;
				break;
			}
		}
	}

	return ret;
}

/******************************************************************************/
static int init_capture_device(void)
{
	struct v4l2_capability cap;

	/* input-0 is selected by default, so no need to set it */
	if ((fdCapture = open(CAPTURE_DEVICE, O_RDWR, 0)) <= -1) {
		printf("InitDevice:open::\n");
		return -1;
	}

	/* is capture supported? */
	if (-1 == ioctl(fdCapture, VIDIOC_QUERYCAP, &cap)) {
		printf("InitDevice:ioctl:VIDIOC_QUERYCAP:\n");
		return -1;
	}

	if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
		printf("InitDevice:capture is not supported on:%s\n",
		       CAPTURE_DEVICE);
		return -1;
	}

	/* is MMAP-IO supported? */
	if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
		printf("InitDevice:IO method MMAP is not supported on:%s\n",
		       CAPTURE_DEVICE);
		return -1;
	}

	return 0;
}

/******************************************************************************/
static int set_data_format(v4l2_std_id * cur_std)
{
	v4l2_std_id prev_std;
	struct v4l2_format fmt;
	unsigned int min;
	struct v4l2_input input;
	int temp_input;
	struct v4l2_cropcap cropcap;
	struct v4l2_crop crop;
	struct v4l2_fmtdesc fmt_desc;
	struct v4l2_standard standard;
	int ret;

	// first set the input
	input.type = V4L2_INPUT_TYPE_CAMERA;
	input.index = 0;
  	while ((ret = ioctl(fdCapture,VIDIOC_ENUMINPUT, &input) == 0)) { 
		printf("input.name = %s\n", input.name);
		if ((vpfe_input == 0) && !strcmp(input.name, "Composite"))
			break;
		if ((vpfe_input == 1) && !strcmp(input.name, "S-Video"))
			break;
		if ((vpfe_input == 2) && !strcmp(input.name, "Camera"))
			break;
		if ((vpfe_input == 3) && !strcmp(input.name, "Component"))
			break;
		input.index++;
  	}

	if (ret < 0) {
		printf("Couldn't find the input\n");
		return -1;
	}

	printf("Calling S_INPUT with index = %d\n", input.index);
  	if (-1 == ioctl (fdCapture, VIDIOC_S_INPUT, &input.index))
  	{
		perror("Error:InitDevice:ioctl:VIDIOC_S_INPUT\n");
      		return -1;
  	}
  	printf ("InitDevice:ioctl:VIDIOC_S_INPUT, selected input index = %d\n",
		input.index);

	if (-1 == ioctl (fdCapture, VIDIOC_G_INPUT, &temp_input))
	{
		perror("Error:InitDevice:ioctl:VIDIOC_G_INPUT\n");
		return -1;
	}
	
	if (temp_input == input.index)
		printf ("InitDevice:ioctl:VIDIOC_G_INPUT, selected input, %s\n", input.name);
	else {
		printf ("Error: InitDevice:ioctl:VIDIOC_G_INPUT,");
		printf("Couldn't select %s input\n", input.name);
		return -1;
  	}

	printf("Following standards available at the input\n");
	standard.index = 0;
	if (vpfe_input != 3) {
		while (0 == ioctl (fdCapture, VIDIOC_ENUMSTD, &standard)) {
			printf("standard.index = %d\n", standard.index);
			printf("standard.id = %llx\n", standard.id);
			printf("standard.frameperiod.numerator = %d\n",
				standard.frameperiod.numerator);
			printf("standard.frameperiod.denominator = %d\n",
				standard.frameperiod.denominator);
			printf("standard.framelines = %d\n",
				standard.framelines);
			standard.index++;
		}
	}

#if 0
	*cur_std = V4L2_STD_PAL;

	if (-1 == ioctl(fdCapture, VIDIOC_S_STD, cur_std)) {
		perror("set_data_format:ioctl:VIDIOC_S_STD\n");
		return -1;
	}

#endif
	if (vpfe_input < 2) {

		if (-1 == ioctl(fdCapture, VIDIOC_QUERYSTD, cur_std)) {
			perror("set_data_format:ioctl:VIDIOC_QUERYSTD:\n");
			return -1;
		}

		if (*cur_std & V4L2_STD_NTSC)
			printf("Input video standard is NTSC.\n");
		else if (*cur_std & V4L2_STD_PAL)
			printf("Input video standard is PAL.\n");
		else if (*cur_std & V4L2_STD_PAL_M)
			printf("Input video standard is PAL-M.\n");
		else if (*cur_std & V4L2_STD_PAL_N)
			printf("Input video standard is PAL-N.\n");
		else if (*cur_std & V4L2_STD_SECAM)
			printf("Input video standard is SECAM.\n");
		else if (*cur_std & V4L2_STD_PAL_60)
			printf("Input video standard to PAL60.\n");
		else 
			return -1;

		/* Set the standard to detected one */
		if ((*cur_std & V4L2_STD_NTSC) && (input_std == 0))
			printf("Setting standard to NTSC\n"); 
		else if ((*cur_std & V4L2_STD_PAL) && (input_std == 1)) 
			printf("Setting standard to PAL\n"); 
		else {
			if (!input_std)
				printf("Fail to detect the NTSC standard at the input\n");
			else 
				printf("Fail to detect the PAL standard at the input\n");
			return -1;
		}

		if (-1 == ioctl(fdCapture, VIDIOC_S_STD, cur_std)) {
			perror("set_data_format:ioctl:VIDIOC_S_STD:\n");
			return -1;
		}

	} else if (vpfe_input == 3) {
		if (input_std == 0)
			*cur_std = V4L2_STD_720P_60;
		else
			*cur_std = V4L2_STD_1080I_60;
		printf("Setting standard, std_id - %llx\n",*cur_std); 

		if (-1 == ioctl(fdCapture, VIDIOC_S_STD, cur_std)) {
			perror("set_data_format:ioctl:VIDIOC_S_STD:\n");
			return -1;
		}

		if (-1 == ioctl(fdCapture, VIDIOC_QUERYSTD, cur_std)) {
			perror("set_data_format:ioctl:VIDIOC_QUERYSTD:\n");
			return -1;
		}

		if (*cur_std & V4L2_STD_720P_60)
			printf("Input video standard is 720P-60.\n");
		else if (*cur_std & V4L2_STD_1080I_60)
			printf("Input video standard is 1080I-60.\n");
		else 
			return -1;
	}

	/* select cropping as deault rectangle */
	cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	if (-1 == ioctl(fdCapture, VIDIOC_CROPCAP, &cropcap)) {
		printf("InitDevice:ioctl:VIDIOC_CROPCAP\n");
		/* ignore error */
	}

	printf("Default crop capbility bounds - %d %d %d %d"
	       " ; default - %d %d %d %d \n",
	       cropcap.bounds.left, cropcap.bounds.top,
	       cropcap.bounds.width, cropcap.bounds.height,
	       cropcap.defrect.left, cropcap.defrect.top,
	       cropcap.defrect.width, cropcap.defrect.height);
	printf("set_data_format:setting data format\n");

	CLEAR(fmt_desc);
	fmt_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	printf("Available image formats at the capture driver :-\n");
	while (0 == ioctl(fdCapture, VIDIOC_ENUM_FMT, &fmt_desc)) {
		printf("fmt_desc.index = %d\n", fmt_desc.index);
		printf("fmt_desc.type = %d\n", fmt_desc.type);
		printf("fmt_desc.description = %s\n", fmt_desc.description);
		printf("fmt_desc.pixelformat = %x\n", fmt_desc.pixelformat);
		fmt_desc.index++;
	}
	
	/* Try format with minimum and maximum values */
	CLEAR(fmt);
	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	fmt.fmt.pix.width = 1;
	fmt.fmt.pix.height = 1;
	if (vpfe_input == 2) {
		fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
		fmt.fmt.pix.field = V4L2_FIELD_ANY;
	} else {
		fmt.fmt.pix.field = V4L2_FIELD_ANY;
		fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
	}
	printf("*******TRY_FMT (Min resolution) values before calling ioctl*************\n");
	printf("fmt.fmt.pix.width = %d\n", fmt.fmt.pix.width);
	printf("fmt.fmt.pix.height = %d\n", fmt.fmt.pix.height);
	printf("fmt.fmt.pix.field= %d\n", fmt.fmt.pix.field);
	printf("fmt.fmt.pix.bytesperline = %d\n", fmt.fmt.pix.bytesperline);
	printf("fmt.fmt.pix.sizeimage = %d\n", fmt.fmt.pix.sizeimage);
	if (-1 == ioctl(fdCapture, VIDIOC_TRY_FMT, &fmt))
		printf("Error:set_data_format:ioctl:VIDIOC_TRY_FMT\n");

	printf("*******TRY_FMT values after calling ioctl*************\n");
	printf("fmt.fmt.pix.width = %d\n", fmt.fmt.pix.width);
	printf("fmt.fmt.pix.height = %d\n", fmt.fmt.pix.height);
	printf("fmt.fmt.pix.field= %d\n", fmt.fmt.pix.field);
	printf("fmt.fmt.pix.bytesperline = %d\n", fmt.fmt.pix.bytesperline);
	printf("fmt.fmt.pix.sizeimage = %d\n", fmt.fmt.pix.sizeimage);
	
	CLEAR(fmt);
	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	fmt.fmt.pix.width = (1 << 15);
	fmt.fmt.pix.height = (1 << 15);
	if (vpfe_input == 2) {
		fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
		fmt.fmt.pix.field = V4L2_FIELD_ANY;
	} else {
		fmt.fmt.pix.field = V4L2_FIELD_ANY;
		fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
	}
	printf("*******TRY_FMT (Max resolution) values before calling ioctl*************\n");
	printf("fmt.fmt.pix.width = %d\n", fmt.fmt.pix.width);
	printf("fmt.fmt.pix.height = %d\n", fmt.fmt.pix.height);
	printf("fmt.fmt.pix.field= %d\n", fmt.fmt.pix.field);
	printf("fmt.fmt.pix.bytesperline = %d\n", fmt.fmt.pix.bytesperline);
	printf("fmt.fmt.pix.sizeimage = %d\n", fmt.fmt.pix.sizeimage);
	if (-1 == ioctl(fdCapture, VIDIOC_TRY_FMT, &fmt))
		printf("Error:set_data_format:ioctl:VIDIOC_TRY_FMT\n");

	printf("*******TRY_FMT values after calling ioctl*************\n");
	printf("fmt.fmt.pix.width = %d\n", fmt.fmt.pix.width);
	printf("fmt.fmt.pix.height = %d\n", fmt.fmt.pix.height);
	printf("fmt.fmt.pix.field= %d\n", fmt.fmt.pix.field);
	printf("fmt.fmt.pix.bytesperline = %d\n", fmt.fmt.pix.bytesperline);
	printf("fmt.fmt.pix.sizeimage = %d\n", fmt.fmt.pix.sizeimage);

	if (vpfe_input == 2) {
		if(input_std == 0)
		{
			fmt.fmt.pix.width = 640;
			fmt.fmt.pix.height = 480;
		}
		else if(input_std == 1)
		{
			fmt.fmt.pix.width = 736;
			fmt.fmt.pix.height = 480;
		}
		else if(input_std == 2)
		{
			fmt.fmt.pix.width = 736;
			fmt.fmt.pix.height = 576;
		}
		else if(input_std == 3)
		{
			fmt.fmt.pix.width = 1280;
			fmt.fmt.pix.height = 720;
		}
		else if(input_std == 4)
		{
			fmt.fmt.pix.width = 1920;
			fmt.fmt.pix.height = 1080;
		}
		fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
		fmt.fmt.pix.field = V4L2_FIELD_NONE;
	} else if (vpfe_input == 3) {
		fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
		if(input_std == 0)
		{
			fmt.fmt.pix.width = 1280;
			fmt.fmt.pix.height = 720;
			fmt.fmt.pix.field = V4L2_FIELD_NONE;
		}
		else if(input_std == 1)
		{
			fmt.fmt.pix.width = 1920;
			fmt.fmt.pix.height = 1080;
			fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
		}
	} else {
		if (crop_en == 1)
		{
			fmt.fmt.pix.width = cr_width;
			fmt.fmt.pix.height = cr_height;
		}	
		else if (*cur_std & V4L2_STD_NTSC) {
			fmt.fmt.pix.width = WIDTH_NTSC;
			fmt.fmt.pix.height = HEIGHT_NTSC;
			cr_width = WIDTH_NTSC;
			cr_height = HEIGHT_NTSC;
		} else {
			fmt.fmt.pix.width = WIDTH_PAL;
			fmt.fmt.pix.height = HEIGHT_PAL;
			cr_width = WIDTH_PAL;
			cr_height = HEIGHT_PAL;
		}
		
		fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
		if (field)
			fmt.fmt.pix.field = V4L2_FIELD_SEQ_TB;
		else
			fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
	}

	printf("the filed = %d \n", fmt.fmt.pix.field);
	
	#if 0
	fmt.fmt.pix.field = 0;
	fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
	#endif

	if (-1 == ioctl(fdCapture, VIDIOC_S_FMT, &fmt))
		printf("set_data_format:ioctl:VIDIOC_S_FMT\n");

	if (-1 == ioctl(fdCapture, VIDIOC_G_FMT, &fmt))
		printf("set_data_format:ioctl:VIDIOC_QUERYSTD:\n");

	if(crop_en == 1)
	{
		crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		crop.c.width= cr_width;
		crop.c.height= cr_height;
		crop.c.top  = cr_top;
		crop.c.left = cr_left;
		if(-1 == ioctl(fdCapture, VIDIOC_S_CROP, &crop))
		{
			perror("Error in setting crop \n");
			return -1;
		}
	}
		
	

	nWidthFinal = fmt.fmt.pix.width;
	nHeightFinal = fmt.fmt.pix.height;

	printf("set_data_format:finally negotiated width:%d height:%d\n",
	       nWidthFinal, nHeightFinal);

	/* checking what is finally negotiated */
	min = fmt.fmt.pix.width * 2;
	if (fmt.fmt.pix.bytesperline < min) {
		printf
		    ("set_data_format:driver reports bytes_per_line:%d(bug)\n",
		     fmt.fmt.pix.bytesperline);
		/*correct it */
		fmt.fmt.pix.bytesperline = min;
	} else {
		printf
		    ("set_data_format:driver reports bytes_per_line:%d\n",
		     fmt.fmt.pix.bytesperline);
	}
	src_line_len = fmt.fmt.pix.bytesperline;
	min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
	if (fmt.fmt.pix.sizeimage < min) {
		printf("set_data_format:driver reports size:%d(bug)\n",
		       fmt.fmt.pix.sizeimage);

		/*correct it */
		fmt.fmt.pix.sizeimage = min;
	} else {
		printf("set_data_format:driver reports size:%d\n",
		       fmt.fmt.pix.sizeimage);
	}

	printf("set_data_format:Finally negotiated width:%d height:%d\n",
	       nWidthFinal, nHeightFinal);

	return 0;
}

/******************************************************************************/
static int init_capture_buffers(void)
{
	struct v4l2_requestbuffers req;
	int nIndex = 0;

	CLEAR(req);
	req.count = MIN_BUFFERS;
	req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	req.memory = V4L2_MEMORY_MMAP;

	if (-1 == ioctl(fdCapture, VIDIOC_REQBUFS, &req)) {
		printf("init_capture_buffers:ioctl:VIDIOC_REQBUFS\n");
		return -1;
	}

	if (req.count < MIN_BUFFERS) {
		printf("init_capture_buffers only:"
		       "%d buffers avilable, can't proceed\n", req.count);
		return -1;
	}

	nBuffers = req.count;
	printf("device buffers:%d\n", req.count);
	buffers = (struct buffer *)calloc(req.count, sizeof(struct buffer));
	if (!buffers) {
		printf("init_capture_buffers:calloc:\n");
		return -1;
	}

	for (nIndex = 0; nIndex < req.count; ++nIndex) {
		struct v4l2_buffer buf;
		CLEAR(buf);
		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_MMAP;
		buf.index = nIndex;

		if (-1 == ioctl(fdCapture, VIDIOC_QUERYBUF, &buf)) {
			printf("init_capture_buffers:VIDIOC_QUERYBUF:\n\n");
			return -1;
		}

		buffers[nIndex].length = buf.length;
		buffers[nIndex].start =
		    mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
			 MAP_SHARED, fdCapture, buf.m.offset);

		printf("buffer:%d phy:%x mmap:%p length:%d\n", buf.index,
		       buf.m.offset, buffers[nIndex].start, buf.length);

		if (MAP_FAILED == buffers[nIndex].start) {
			printf("init_capture_buffers:mmap:\n");
			return -1;
		}
	}
	return 0;
}

/******************************************************************************/
static int start_streaming(void)
{
	int i = 0;
	enum v4l2_buf_type type;

	for (i = 0; i < nBuffers; i++) {
		struct v4l2_buffer buf;
		CLEAR(buf);
		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_MMAP;
		buf.index = i;
		printf("Queing buffer:%d\n", i);

		if (-1 == ioctl(fdCapture, VIDIOC_QBUF, &buf))
			printf("start_streaming:ioctl:VIDIOC_QBUF:\n");
	}
	/* all done , get set go */
	type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	if (-1 == ioctl(fdCapture, VIDIOC_STREAMON, &type))
		printf("start_streaming:ioctl:VIDIOC_STREAMON:\n");

	return 0;
}

/******************************************************************************/
static int start_display(int fd, int index, int flag)
{
	int ret;
	struct v4l2_buffer buf;
	enum v4l2_buf_type type;

	bzero(&buf, sizeof(buf));
	/*
	 *      Queue all the buffers for the initial running
	 */
	printf("6. Test enqueuing of buffers - ");
	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	buf.memory = V4L2_MEMORY_USERPTR;
	buf.index = index;
	buf.length = display_image_size;
	buf.m.userptr = (unsigned long)buffers[index].start;
	ret = ioctl(fd, VIDIOC_QBUF, &buf);
	if (ret < 0) {
		printf("fd = %d\n", fd);
		printf("\n\tError: Enqueuing buffer[%d] failed: VID1",
		       index);
		return -1;
	}

	printf("done\n");

	if (flag) {
		printf("7. Test STREAM_ON\n");
		type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
		ret = ioctl(fd, VIDIOC_STREAMON, &type);
		if (ret < 0) {
			perror("VIDIOC_STREAMON\n");
			return -1;
		}
	}

	return 0;
}

/******************************************************************************/
static int init_vid1_device(v4l2_std_id cur_std)
{
	int mode = O_RDWR;
	int i = 0, ret = 0;

	struct v4l2_format fmt, setfmt;
	struct v4l2_fmtdesc format;
	struct v4l2_capability capability;

	/* open osd0, osd1 devices and disable */
	fd_osd0 = open(OSD0_DEVICE, mode);
	ioctl(fd_osd0, FBIOBLANK, 1);

	fd_osd1 = open(OSD1_DEVICE, mode);
	ioctl(fd_osd1, FBIOBLANK, 1);

	/*
	 * 1. Open display channel
	 */
	printf("1. Opening VID1 device\n");
	fd_vid1 = open(VID1_DEVICE, mode);
	if (-1 == fd_vid1) {
		printf("failed to open VID1 display device\n");
		return -1;
	}
	printf("done\n");

	/* Testing IOCTLs */
	ret = ioctl(fd_vid1, VIDIOC_QUERYCAP, &capability);
	if (ret < 0) {
		printf("FAILED: QUERYCAP\n");
		return -1;
	}
	printf("fd = %d\n", fd_vid1);
	if (capability.capabilities & V4L2_CAP_VIDEO_OUTPUT)
		printf("Display capability is supported\n");
	if (capability.capabilities & V4L2_CAP_STREAMING)
		printf("Streaming is supported\n");

	while (1) {
		format.index = i;
		format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
		ret = ioctl(fd_vid1, VIDIOC_ENUM_FMT, &format);
		if (ret < 0)
			break;
		printf("description = %s\n", format.description);
		if (format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
			printf("Video Display type\n");
		if (format.pixelformat == V4L2_PIX_FMT_UYVY)
			printf("V4L2_PIX_FMT_UYVY\n");
		i++;
	}

	/*
	 * Now for the buffers. Request the number of buffers needed
	 * and the kind of buffers (User buffers or kernel buffers
	 * for memory mapping).
	 * Please note that the return value in the reqbuf.count
	 * might be lesser than numbuffers under some low memory
	 * circumstances
	 */
	printf("2. Test request for buffers\n");
	reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	reqbuf.count = numbuffers;
	reqbuf.memory = V4L2_MEMORY_USERPTR;
	ret = ioctl(fd_vid1, VIDIOC_REQBUFS, &reqbuf);
	if (ret < 0) {
		printf("\n\tError: Could not allocate the buffers: VID1\n");
		return -1;
	}
	printf("\tNumbers of buffers returned - %d\n", reqbuf.count);
	CLEAR(setfmt);
	setfmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	setfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
	if (cur_std & V4L2_STD_NTSC) {
		printf("init_vid1_device:requesting width:%d height:%d\n",
		       WIDTH_NTSC, HEIGHT_NTSC);
		setfmt.fmt.pix.bytesperline = WIDTH_NTSC * 2;
		setfmt.fmt.pix.sizeimage =
		    setfmt.fmt.pix.bytesperline * HEIGHT_NTSC;
		setfmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
	} else if ((cur_std & V4L2_STD_PAL) ||
		(cur_std & V4L2_STD_PAL_M) ||
		(cur_std & V4L2_STD_PAL_N)) {
		printf("init_vid1_device:requesting width:%d height:%d\n",
		       WIDTH_PAL, HEIGHT_PAL);
		setfmt.fmt.pix.bytesperline = WIDTH_PAL * 2;
		setfmt.fmt.pix.sizeimage =
		    setfmt.fmt.pix.bytesperline * HEIGHT_PAL;
		setfmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
	} else if ((cur_std & V4L2_STD_720P_60) ||
		   (cur_std & V4L2_STD_720P_50)) {
		printf("init_vid1_device:requesting width:%d height:%d\n",
		       WIDTH_720P, HEIGHT_720P);
		setfmt.fmt.pix.bytesperline = WIDTH_720P * 2;
		setfmt.fmt.pix.sizeimage =
		    setfmt.fmt.pix.bytesperline * HEIGHT_720P;
		setfmt.fmt.pix.field = V4L2_FIELD_NONE;
	} else if ((cur_std & V4L2_STD_1080I_60) ||
		   (cur_std & V4L2_STD_1080I_50)) {
		printf("init_vid1_device:requesting width:%d height:%d\n",
		       WIDTH_1080I, HEIGHT_1080I);
		setfmt.fmt.pix.bytesperline = WIDTH_1080I * 2;
		setfmt.fmt.pix.sizeimage =
		    setfmt.fmt.pix.bytesperline * HEIGHT_1080I;
		setfmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
	} else {
		printf("This video cannot be displayed\n");
		close(fd_vid1);
		return -1;
	}

	display_image_size = setfmt.fmt.pix.sizeimage;
	
	ret = ioctl(fd_vid1, VIDIOC_S_FMT, &setfmt);
	if (ret < 0) {
		perror("VIDIOC_S_FMT\n");
		close(fd_vid1);
		return -1;
	} else
		printf(" VIDIOC_S_FMT: PASS\n");

	/*
	 * It is necessary for applications to know about the
	 * buffer chacteristics that are set by the driver for
	 * proper handling of buffers
	 * These are : width,height,pitch and image size
	 */
	printf("3. Test GetFormat\n");
	fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	ret = ioctl(fd_vid1, VIDIOC_G_FMT, &fmt);
	if (ret < 0) {
		printf("\tError: Get Format failed: VID1\n");
		return -1;
	}
	dispheight = fmt.fmt.pix.height;
	disppitch = fmt.fmt.pix.bytesperline;
	dispwidth = fmt.fmt.pix.width;

	printf("\tdispheight = %d\n\tdisppitch = %d\n\tdispwidth = %d\n",
	       dispheight, disppitch, dispwidth);
	printf("\timagesize = %d\n", fmt.fmt.pix.sizeimage);
	
	return SUCCESS;
}

/******************************************************************************
 * Example to show vid1 in YUV format,OSD0 in RGB565 format
 *  and OSD1 is attribute format.
 ******************************************************************************/
static int vpbe_UE_1(void)
{
	int ret = 0;
	v4l2_std_id cur_std;

	DBGENTER;

	/* Setup Capture */
	if (initialize_capture(&cur_std) < 0) {
		printf("Failed to intialize capture\n");
		return ret;
	}

	/* Setup Display */
	if (cur_std & V4L2_STD_NTSC) {
		if (change_sysfs_attrib(ATTRIB_OUTPUT, DISPLAY_INTERFACE_COMPOSITE))
			return FAILURE;
		if (change_sysfs_attrib(ATTRIB_MODE, DISPLAY_MODE_NTSC))
			return FAILURE;
		file_size = WIDTH_NTSC * HEIGHT_NTSC * 2;
	}
	else if (cur_std & V4L2_STD_PAL) {
		if (change_sysfs_attrib(ATTRIB_OUTPUT, DISPLAY_INTERFACE_COMPOSITE))
			return FAILURE;
		if (change_sysfs_attrib(ATTRIB_MODE, DISPLAY_MODE_PAL))
			return FAILURE;
		file_size = WIDTH_PAL * HEIGHT_PAL * 2;
	}
	else if (cur_std & V4L2_STD_720P_60) {
		if (change_sysfs_attrib(ATTRIB_OUTPUT, DISPLAY_INTERFACE_COMPONENT))
			return FAILURE;
		if (change_sysfs_attrib(ATTRIB_MODE, DISPLAY_MODE_720P))
			return FAILURE;
		file_size = WIDTH_720P * HEIGHT_720P * 2;
	}
	else if (cur_std & V4L2_STD_1080I_60) {
		if (change_sysfs_attrib(ATTRIB_OUTPUT, DISPLAY_INTERFACE_COMPONENT))
			return FAILURE;
		if (change_sysfs_attrib(ATTRIB_MODE, DISPLAY_MODE_1080I))
			return FAILURE;
		file_size = WIDTH_1080I * HEIGHT_1080I * 2;
	} else {
		printf("Cannot display this standard\n");
		return FAILURE;
	}

	/* Setup VID1 output */
	if ((init_vid1_device(cur_std)) < 0) {
		printf("\nFailed to init vid1 window ");
		return FAILURE;
	}
	
	ret = start_loop();
	if (ret)
		printf("\tError: Video loopback had some errors\n");
	printf("Video loopback completed successfully\n");

	/*
	 * Once the streaming is done  stop the display
	 * hardware
	 */
	printf("8. Test STREAM_OFF - \n");
	ret = stop_display(fd_vid1);
	if (ret < 0) {
		printf("\tError: Could not stop display\n");
		return ret;
	}

	/* Release display channel */
	printf("9. Test buffer unmapping & closing of device - \n");
	release_display(&fd_vid1);

	ret = stop_capture(fdCapture);
	if (ret < 0)
		printf("Error in VIDIOC_STREAMOFF:capture\n");

	release_capture(&fdCapture);
	close(fd_osd0);
	printf("DONE ALL\n\n\n");

	DBGEXIT;
	return ret;
}

/*******************************************************************************
 *	Function will use the SysFS interface to change the output and mode
 */
static int change_sysfs_attrib(char *attribute, char *value)
{
	int sysfd = -1;
	char init_val[32];
	char attrib_tag[128];

	bzero(init_val, sizeof(init_val));
	strcpy(attrib_tag, "/sys/class/davinci_display/ch0/");
	strcat(attrib_tag, attribute);

	sysfd = open(attrib_tag, O_RDWR);
	if (!sysfd) {
		printf("Error: cannot open %d\n", sysfd);
		return FAILURE;
	}
	printf("%s was opened successfully\n", attrib_tag);

	read(sysfd, init_val, 32);
	lseek(sysfd, 0, SEEK_SET);
	printf("Current %s value is %s\n", attribute, init_val);

	write(sysfd, value, 1 + strlen(value));
	lseek(sysfd, 0, SEEK_SET);

	memset(init_val, '\0', 32);
	read(sysfd, init_val, 32);
	lseek(sysfd, 0, SEEK_SET);
	printf("Changed %s to %s\n", attribute, init_val);

	close(sysfd);
	return SUCCESS;
}

/*******************************************************************************
* menu function
*******************************************************************************/
void menu(void)
{
	printf("Usage: v4l2_mmap_loopback -s <flag>\n");
	printf("flag = 0 for infinite loop, 1 - for 500 frames\n");
}


/******************************************************************************/
/* main function */
int main(int argc, char *argv[])
{
	int ret = 0, d, index;
	char shortoptions[] = "i:s:d:w:p:m:f:l:h:b:t:c:";

	DBGENTER;

	/* by default use composite */
	for (;;) {
		d = getopt_long(argc, argv, shortoptions, (void *)NULL, &index);
		if (-1 == d)
			break;
		switch (d) {
		case 'f':
			field = atoi(optarg);
			break;
		case 'i':
			vpfe_input = atoi(optarg);
			break;
		case 'm':
			input_std = atoi(optarg);
			break;
		case 'p':
			printfn = atoi(optarg);
		case 's':
		case 'S':
			stress_test = atoi(optarg);
			break;
		case 'l':
		case 'L':
			cr_width = atoi(optarg);
			break;
		case 'h':
		case 'H':
			cr_height = atoi(optarg);
			break;
		case 'b':
		case 'B':
			cr_left = atoi(optarg);
			break;
		case 't':
		case 'T':
			cr_top = atoi(optarg);
			break;
		case 'c':
		case 'C':
			crop_en = atoi(optarg);
			break;
		default:
			menu();
			exit(1);
		}
	}

	if (en_capture_to_file) {
		fp_capture = fopen(FILE_CAPTURE, "wb");
		if (fp_capture == NULL) {
			printf("Unable to open file %s for capture\n", FILE_CAPTURE);
			exit(1);
		}
	}

	ret = vpbe_UE_1();
	DBGEXIT;
	return ret;
}

--- End Message ---

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux