low resolution problems with a webcam.

onecue
Hi

I have a problem with capturing an image from webcam on the 2440.

I use the v4l2 source code.

The program works fine on the 144 X 176 resolution.

I want to change a higher resolution but program only has the 144 X 176
buffer size.



//    set width, height
        fmt2.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt2.fmt.pix.width       = 320; 
        fmt2.fmt.pix.height      = 240;
        fmt2.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        fmt2.fmt.pix.field       = V4L2_FIELD_NONE;


////////  init mmap

 struct v4l2_requestbuffers req;

        CLEAR (req);

        req.count               = 4;
        req.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req.memory              = V4L2_MEMORY_MMAP;

        if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
                if (EINVAL == errno) {
                        fprintf (stderr, "%s does not support "
                                 "memory mapping\n", dev_name);
                        exit (EXIT_FAILURE);
                } else {
                        errno_exit ("VIDIOC_REQBUFS");
                }
        }

        if (req.count < 2) {
                fprintf (stderr, "Insufficient buffer memory on %s\n",
                         dev_name);
                exit (EXIT_FAILURE);
        }

  char* buff;
        buff = (char*) calloc (req.count, sizeof (*buffers));
  buffers = (buffer*) buff;

        if (!buffers) {
                fprintf (stderr, "Out of memory\n");
                exit (EXIT_FAILURE);
        }

        for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
                struct v4l2_buffer buf;

                CLEAR (buf);

                buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buf.memory      = V4L2_MEMORY_MMAP;
                buf.index       = n_buffers;

                if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))
                        errno_exit ("VIDIOC_QUERYBUF");

                buffers[n_buffers].length = buf.length;
                buffers[n_buffers].start =
                        mmap (NULL /* start anywhere */,
                              buf.length,
                              PROT_READ | PROT_WRITE /* required */,
                              MAP_SHARED /* recommended */,
                              fd, buf.m.offset);

                if (MAP_FAILED == buffers[n_buffers].start)
                        errno_exit ("mmap");
        }

Tomasz Myrta
It's USB1.1 limitation. Camera calculates maximum resolution dividing USB
bandwidth by it's framerate (15 or 30fps) and colour format. If your camera
supports MJPEG compression, you can reach bigger resolutions like 640x480.
It doesn't matter that you need only still image at 1fps. Linux UVC doesn't
support still images and grabs frames directly from video stream.

onecue
Thanks for a comment.

I changed V4L2_PIX_FMT_YUYV to V4L2_PIX_FMT_MPEG.

but I don't know how can I convert the mpeg data to rgb.

Do I need other library? or Can I convert it to rgb using v4l2 function?

Tomasz Myrta
I was meaning MJPEG, not MPEG. MJPEG are JPEG frames after removing
headers. It's not so easy to get RGB data. You would need to add missing
header and decompress it using libjpeg.
I don't know what is your minimum resolution, but there are webcams working
at 320x240 or 352x288 on USB1.1 with YUYV or RGB pixelformat.

Pranav
Well, in my case with Logitech Quickcam Sphere AF i am getting resolution
1600X1200 with YUYV format but with MJPEG it is limited to 960X720. Why is
it so?

I am using V4L2 API video capture(similar to the code posted by OP).