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.

Centering displayed video in saLoopBackScale (V4L2) demo

When running the saLoopBackScale demo (from examples included with http://software-dl.ti.com/dsps/dsps_public_sw/psp/LinuxPSP/DM814x_04_01/04_01_00_06/index_FDS.html), the scaled video is in the top left of the display, and the rest of the display is gray.  I am currently trying to determine how to center the scaled video.

In the capture initialization, I see the cropping region and scaled dimensions being configured:

    capt.crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    capt.crop.c.left = 0;
    capt.crop.c.top = 0;
    capt.crop.c.width = capt.fmt.fmt.pix.width;
    capt.crop.c.height = capt.fmt.fmt.pix.height;

    if (ioctl(capt.fd, VIDIOC_S_CROP, &capt.crop)) {
        printf("Setting format failed\n");
        exit(2);
    }

    capt.fmt_win.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    capt.fmt_win.fmt.win.w.left = 0;
    capt.fmt_win.fmt.win.w.top = 0;
    capt.fmt_win.fmt.win.w.width = SCALED_WIDTH;
    capt.fmt_win.fmt.win.w.height = SCALED_HEIGHT;

    if (ioctl(capt.fd, VIDIOC_S_FMT, &capt.fmt_win)) {
        printf("Setting window failed\n");
        exit(2);
    }

    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;
    }

However, in setupDisplay(), disp.fmt.fmt.pix.width/height are pulled from the display's native dimensions, rather than the scaled dimensions -- I found this a bit confusing.

When changing these to match the scaled dimensions, I end up with a corrupted image of the desired size, centered in the display. It looks like I've got a line size mismatch, which makes me think the scaled image is going into memory embedded in a 1280x720 region frame or something.  Do I need to change some buffer settings on the capture side of things in order for this to work correctly?

/* This is incorrect */

    disp.fmt.fmt.pix.width = SCALED_WIDTH;
    disp.fmt.fmt.pix.height = SCALED_HEIGHT;
    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;
    }

Anyone mind pointing out the correct way to do this, and perhaps the misconceptions I seem to have? I've been over the PSP user guide's sections on positioning the display image a few times without much luck.  (http://processors.wiki.ti.com/index.php/DM814X_AM387X_VPSS_Video_Driver_User_Guide#V4L2_IOCTL)

Thank you!

  • Jon,

    What is your HDMI display settings? Are they set to D1 resolution ? If you are using EZSDK by default they are set to 1080p-60 or 720p-60. This may be the reason why disp.fmt.fmt.pix.width/height are pulled from the display's native dimensions.

    Incase that doesnt resolve yur issue, also notice Display and Capture buffers are allocated in a single mmap call so all the buffers will be of the same size (buffersize = fixinfo.line_length * varinfo.yres;) which may be larger than your display resolution. This may also be cause of the issue that you are seeing. Since both the capture and the display use userptr buffers, you can try to allocate buffers of the size equal to the  display resolution (scaled) to ensure that the display image is not corrupted.

    Let me know if these suggestions helped

    Regards,

    Rahul

     

  • Hi,

    Following things needs to be taken care to display image in center.

    1. Buffer size in capture should be equal to scaled image and not the captured image.

    2. Same buffer size should go to display.

    If both above points are taken care off, display driver automatically positions image in center of display.

    Regards,

    Hardik Shah

  • Thank you both for the quick responses!  I should have noted that I am indeed running my monitor and DM8148EVM at 720p.

    HardikShah said:

    Following things needs to be taken care to display image in center.

    1. Buffer size in capture should be equal to scaled image and not the captured image.

    2. Same buffer size should go to display.

    If both above points are taken care off, display driver automatically positions image in center of display.

    Hardik, I seem to have forgotten item 1 -- I seem to have been writing my scaled data to "720p-sized" memory, which explains the image corruption that looked like my memory was off by lines. For reference, I've attached a patch of saLoopBackScale that made the small changes you mentioned -- this seems to work well so far!


    However, I'd like to place a GUI overlay (using FBDev's color keying transparencey) on top of the centered video feed, with the GUI filling the entire monitor. With that said, what do you recommend for centering the image, while keeping the display at the native resolution? I suspect I'll need to set up a VIDIOC_S_FMT ioctl() with a V4L2_BUF_TYPE_VIDEO_OVERLAY and the top/left parameters configured for the desired position, but I'm still a bit uncertain about capture/display bytesperline and sizeimage settings in this case.

    Note: I realize that this demo is reusing FBdev memory that I'd place my GUI in, but I've already got saLoopBack using memory allocated by CMEM, so doing the same here shouldn't be an issue.

    Thank you,

    Jon

    --- ./saLoopBackScale.c.orig	2011-11-15 07:14:56.000000000 -0500
    +++ ./saLoopBackScale.c	2012-02-28 09:46:14.026066049 -0500
    @@ -89,8 +89,8 @@
     /* Define below #def for debug information enable */
     #undef SALOOPBACKSCALE_DEBUG
     
    -#define SCALED_HEIGHT		480
    -#define SCALED_WIDTH		720
    +#define SCALED_HEIGHT		360
    +#define SCALED_WIDTH		640
     
     /* Structure for storing buffer information */
     struct buf_info {
    @@ -260,17 +260,18 @@
     	capt.fmt_win.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
     	capt.fmt_win.fmt.win.w.left = 0;
     	capt.fmt_win.fmt.win.w.top = 0;
    -	capt.fmt_win.fmt.win.w.width = 720;
    -	capt.fmt_win.fmt.win.w.height = 480;
    +	capt.fmt_win.fmt.win.w.width = SCALED_WIDTH;
    +	capt.fmt_win.fmt.win.w.height = SCALED_HEIGHT;
     
     	if (ioctl(capt.fd, VIDIOC_S_FMT, &capt.fmt_win)) {
     		printf("Setting window failed\n");
     		exit(2);
     	}
     
    -	capt.fmt.fmt.pix.bytesperline = capt.fmt.fmt.pix.width * 2;
    +    /* Set up our image format based upon the downscaled image size */
    +	capt.fmt.fmt.pix.bytesperline = capt.fmt_win.fmt.win.w.width * 2;
     	capt.fmt.fmt.pix.sizeimage = capt.fmt.fmt.pix.bytesperline *
    -		capt.fmt.fmt.pix.height;
    +		capt.fmt_win.fmt.win.w.height;
     	ret = ioctl(capt.fd, VIDIOC_S_FMT, &capt.fmt);
     	if (ret < 0) {
     		printf("Set Format failed\n");
    @@ -309,17 +310,9 @@
     		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.width = SCALED_WIDTH;
    +    disp.fmt.fmt.pix.height = SCALED_HEIGHT;
     	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 *