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.

Problems with cropping, scaling and positioning using V4L



1) The overlay size does not change with VIDIOC_S_FMT.  The command reports success and the window width and height look like there were changed with a subsequent VIDIOC_G_FMT but the video overlay does not scale.

2) Cropping with VIDIOC_S_CROP and positioning with VIDIOC_S_FMT work but not reliably.  Again, the command reports success and the values look like there were changed with a subsequent query, but the video overlay does not update.  It can sometimes take 5-6 retries of the command for the overlay changes to actually take effect.

Anyone else see similar problems?  I am trying the latest EZSDK.

  • Hi,

    Could you please give us more details of your test setup and the application that you are using.

  • A short program (test-v4l) is at the bottom of the post which you can use to see the issue.  I use a simple gstreamer line to start playing video while testing the following commands.

      # gst-launch playbin2 uri="file:///test.h264"

    1)  The following tries to scale the video overlay using VIDIOC_S_FMT.  When run the size of the video does not change.

      # test-v4l setpos 0 0 320 240

    2) The following command lines try to change the overlay (x,y) with VIDIOC_S_FMT.  If you toggle between the lines you will see sometimes the video does not change.  You sometimes need to repeat a command several times before the video will change position.

       # dv4l setpos 0 0 320 240
       # dv4l setpos 200 200 320 240

    The VIDIOC_S_FMT ioctl does not fail.  If you read back the overlay window it looks like the (x,y) was successfully changed.

    3) The following command lines try to crop with VIDIOC_S_CROP.  If you toggle between the lines you will see sometimes the cropping does not change.  You sometimes need to repeat a command several times before the video will change postion.

       # dv4l crop 0 0 720 480
       # dv4l crop 100 100 200 200

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <linux/videodev.h>
    #include <linux/videodev2.h>
    #include <string.h>
    #define exit_if(expr, s) do{ if (expr) { perror(s); exit(-1); } } while(0)
    int crop(int fd, int x, int y, int w, int h)
    {
        struct v4l2_crop crop; 
        crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 
        crop.c.left   = x; 
        crop.c.top    = y;
        crop.c.width  = w; 
        crop.c.height = h; 
        int rc = ioctl(fd, VIDIOC_S_CROP, &crop); 
        exit_if(rc < 0, "VIDIOC_S_CROP:");
        return rc;
    }
    int getpos(int fd)
    {
        struct v4l2_format fmt; 
        fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
        int rc = ioctl(fd, VIDIOC_G_FMT, &fmt); 
        exit_if(rc < 0, "VIDIOC_G_FMT:");
        printf( "%d %d %d %d\n", fmt.fmt.win.w.left, fmt.fmt.win.w.top, fmt.fmt.win.w.width, fmt.fmt.win.w.height);
        return rc;
    }
    int setpos(int fd, int x, int y, int w, int h)
    {
        struct v4l2_format fmt; 
        fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
        int rc = ioctl(fd, VIDIOC_G_FMT, &fmt); 
        exit_if(rc < 0, "VIDIOC_G_FMT:");
        fmt.fmt.win.w.left   = x;
        fmt.fmt.win.w.top    = y;
        fmt.fmt.win.w.width  = w;
        fmt.fmt.win.w.height = h;
        rc = ioctl(fd, VIDIOC_S_FMT, &fmt); 
        exit_if(rc < 0, "VIDIOC_S_FMT:");
        return rc;
    }
    int main(int argc, char *argv[])
    {
        const char *dev = "/dev/video1";
        int fd = open(dev, O_RDWR);
        exit_if(fd < 0, "Failed to open display device:");
        if (strcmp("crop", argv[1]) == 0)
            crop(fd, atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
        else if (strcmp("setpos", argv[1]) == 0)
            setpos(fd, atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
        else if (strcmp("getpos", argv[1]) == 0)
            getpos(fd);
        close(fd); 
        return 0;
    }