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.

How to display captured video using DVO2 with the demo saLoopBack

Other Parts Discussed in Thread: TVP7002

With the example saLoopBack ,I got the video captured(720p) and displayed correctly.
And I want to change it to display captured video with DVO2.

Here is what I have made some changes with the saLoopBack example.

The changed parts are marked red below.

/*
* saLoopBack.c

*/

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/display1/enabled");


/* 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_720P60:
printf("%s:\n Mode set is 720P60\n", APP_NAME);
system ("echo 720p-60 > /sys/devices/platform/vpss/display1/mode");
break;
case V4L2_DV_1080I60:
printf("%s:\n Mode set is 1080I60\n", APP_NAME);
system ("echo 1080i-60 > /sys/devices/platform/vpss/display1/mode");
break;
case V4L2_DV_1080P60:
printf("%s:\n Mode set is 1080P60\n", APP_NAME);
system ("echo 1080p-60 > /sys/devices/platform/vpss/display1/mode");
break;
case V4L2_DV_1080P30:
printf("%s:\n Mode set is 1080P30\n", APP_NAME);
system ("echo 1080p-30 > /sys/devices/platform/vpss/display1/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/display1/enabled");

return 0;
}

/* 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");
system("echo vcompmux:dvo2 > /sys/devices/platform/vpss/video0/nodes");
/* Open the capture driver. Query the resolution from the capture driver
*/
ret = initCapture();
if (ret < 0) {
printf("Error in opening capture device for channel 0\n");
return ret;
}
/* Open the Display driver. */
ret = initDisplay();
if (ret < 0) {
printf("Error in opening display device for channel 0\n");
return ret;
}
restart:
/* Setup the capture driver Step includes
* Set the format according to the resolution queried.
* request for buffer descriptors for userpointer buffers
*/
ret = setupCapture();
if (ret < 0) {
printf("Error in setting up of capture\n");
return ret;
}
/* 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;
}
/* 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
*/
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.
*/
ret = queueCaptureBuffers();
if (ret < 0) {
printf("Error in queuing capture buffers\n");
return ret;
}
/* 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;
}
/* Start capture driver after display driver */
ret = startCapture();
if (ret < 0) {
printf("Error starring capture \n");
return ret;
}
/* 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;
}
// printf("%d\n",i);
/* 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/display1/enabled");
system ("echo 1080p-60 > /sys/devices/platform/vpss/display1/mode");
// system("echo 0 > /sys/devices/platform/vpss/display0/enabled");
system("echo vcompmux:hdmi > /sys/devices/platform/vpss/video0/nodes");
// system("echo 0 > /sys/devices/platform/vpss/graphics0/enabled");
// system("echo 1 > /sys/devices/platform/vpss/display0/enabled");
system("echo 1 > /sys/devices/platform/vpss/display1/enabled");
// system("echo 1:hdmi > /sys/devices/platform/vpss/graphics0/nodes");
return 0;
}


When run on the dm8168evm, nothing displayed through the on-chip-hdmi or sonboard hdmi output.

Here is what I got on the terminal.

root@dm816x-evm:~# ./saLoopBack
Driver Name: ti81xxvin
Driver bus info: TI81xx Platform
Driver is capable of doing capture
saLoopBack:
Mode set is 720P60
Driver Name:
Driver bus info: �Ѓ@@`
=============================================================
Capture Format:
=============================================================
fmt.type = 1
fmt.width = 1280
fmt.height = 720
fmt.pixelformat = 1448695129
fmt.bytesperline = 2560
fmt.sizeimage = 1843200
=============================================================
=============================================================
Display Format:
=============================================================
fmt.type = 2
fmt.width = 1280
fmt.height = 720
fmt.pixelformat = 1448695129
fmt.bytesperline = 2560
fmt.sizeimage = 1843200
=============================================================
Count=0
Frame rate = 62

I don't know where problems lay.

Hope for your help.

  • Hello Yang,

     

    Does you DVO2 display work fine when you just enable it? Do you see black back ground color on the DVO2? Does your TV detects the mode that you have selected? I would suggest first making sure that the DVO2 output is correct? We could then try to make this app work for DVO2?

     

    Regards,

    Brijesh

  • Hello Brijesh Jadav:

               I use the ADV7611(or TVP7002 ) which support HMDI receive to capture the 1280*720 video,and show on the  LCD screens  which only supports the resolution of 1024*600 and must be RGB ,not YUV .So based on the example of  saLoopbackFbedev, I have to get the 1280*720 capture data to another 
    user buffer(not FBDEV buffer as the example) first and then extract 1024*600 by some algorithm ,But when I use my new user defined buffer to replace the fbdev buffer,I found there are many *** question,eg:the programe will be crashed undefined or the picture is overlapping 。。。。although I use the methord to show the video on the TV Screeen which support 1280*720(so I not need extract anything),still exist the above question.
    My steps are: 
          (1)Add the new variable which will be used  to as the buffer  of caputre.
            unsigned char *captBufferArray[MAX_BUFFER];
         (2In function "setupFbdevAndBuffers"  add:
           captBufferArray[0]=(unsigned char *)malloc(1280*720*3*MAX_BUFFER);
    for (i = 1; i < MAX_BUFFER; i++)
    captBufferArray[i] = captBufferArray[i-1] + 1280*720*3;
    memset(captBufferArray[0], 0x00,1280*720*3*MAX_BUFFER);
         (3)In function "queueCaptureBuffers" ,Replace fbdev.buffer_addr  with the capBufferArray.
     static int queueCaptureBuffers(void)
    {
    int ret, i;
    for (i = 0; i < MAX_BUFFER; 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)fbdev.buffer_addr[0];*/
            capt.buf.m.userptr = (unsigned long)captBufferArray[capt.buf.index];
    capt.buf.length =1280*720*3;
    ret = ioctl(capt.fd, VIDIOC_QBUF, &capt.buf);
    if (ret < 0) {
    perror("VIDIOC_QBUF\n");
    /*return -1;*/
    }
    }
    return ret;
    }
    (4)
    static int app_main(int argc , char *argv[])
    {
    -----------
    for (i = 0; i < MAXLOOPCOUNT; i++)
    {
        /*
      Get capture buffer using DQBUF ioctl
    */
    /*printf("Get capture buffer 1\n");*/
    ret = ioctl(capt.fd, VIDIOC_DQBUF, &capt.buf);
    if (ret < 0) {
    printf("VIDIOC_DQBUF\n");
    /*return -1;*/
    }
             memcpy(fbdev.buffer_addr[0],(unsigned char *)(capt.buf.m.userptr),1280*3*720);
    -------------
    capt.buf.m.userptr = (unsigned long)captBufferArray[capt.buf.index];
    capt.buf.length = 1280*3*720;
    ret = ioctl(capt.fd, VIDIOC_QBUF, &capt.buf);
    if (ret < 0) {
    perror("VIDIOC_QBUF\n");
    /*return -1;*/
    }
    }
    Am I right?Is there something wrong? Why my user defined buffer captBuffer can not get the correct caputre data?But if use the buffer which was mmaped by fb0(Fbdev) was ok.So wheather there are some others steps need to do when pass a user defined buffer to capture capt.buf.m.userptr ?
    Thanks very much.
                                           zhichao.
  • Hi,

    Even I am also facing the same issue as my LCD resolution is 800x480. When I try to display the captured data in LCD, its showing some patches in front of captured image and the same I am getting proper data in HDMI.


    Please give any solution to solve this issue.


    Thanks in advance.

    Regards,
    Salih