Webcam and maximal resolution using v4l2

Neyna
Hi all,

I recently bought a webcam C200 (logitech) for use with the mini2440.
I modified the example from v4l2 website (capture.c) to save images.

My problem is that when the program is run on the mini2440, the maximal
resolution allowed by the driver is 176*144.
If the program is run on my PC it's 640*480.

I think the problem is from usb1.1 on 2440 and usb2 on my PC. Am i correct?

Has someone be able (with a UVC camera) to work with resolution higher than
176*144 ? If yes, which model?

Thanks,

Neyna
up :)

Neyna
up :)

has nobody be able to capture images greater than 176*144 with a usb webcam
on mini2440 ?

Thanks for help.

Neyna
up :)

Berello
Could you please send me the code?

I'm trying to understand how to work on those pictures, without results. I
tried to save the output directly on a file, but then the file was not
usable by other programs.

It would be very useful for me! Please!

Thank you,
        bye!

Neyna
yes i can but i need an email or something to send to.

Do you want the YUV or MJPEG code?
Because of the usb1.1 on the mini2440 i dropped my YUV capture project and
moved to MJPEG (which is more complicated).

Berello
You can send the code to this address: gorillarapito@yahoo.it
Thank you very much!

I'm not sure on which of the two I need... Could you send me both?
What I need is mainly: to understand how to use the output of capture.c;
after that I will try to process the images read from the webcam directly
(and eventually saving to file after processing).
The reason is that I'm studying a bit of computer vision and I want to try
some (very) simple things directly on my webcam.

Thank you again! :)

Berello
Hi!

I read some paragraphs of the V4L2 specification guide and I solved my
problem!
I could save one frame in a BMP file! I succeeded in my goal!

I don't need your code anymore... However I thank you for your
availability! And I hope you will succeed in your purpose, too!

Bye bye!

Irinel
Hi Berello,

I'm trying to get a capture in YUV format from web cam without success. I
need to show the frame on LCD 3.5" using framebuffer. In this case I need
the image to be in RGB565 format. Could you help me ?

Thanks

Berello
I'm sorry but I cannot help you.
I know almost nothing about codecs: I solved my problem because there were
instructions (and a description of the codecs I needed) in this PDF:
http://v4l2spec.bytesex.org/v4l2spec/v4l2.pdf

At first impact, that file doesn't seem very friendly; but reading it from
the first page, you understand the fundamentals of V4L2 and then you can
jump to the subject of your interest. It will be easier than you think.

Probably, there you can find a description of every codec supported by
V4L2, maybe your RGB565 too.

However I suppose that my code to save a "grey scale" bitmap could be
useful for you; with a few changes you can convert it to a colour bitmap
(which I suppose similar to the codec you're looking for).
I'll send you the code in a next message or eventually by e-mail.

Don't ask me anything about the code, except about the function
"process_image", which is the only part I wrote. The rest of the code has
been taken from: http://v4l2spec.bytesex.org/v4l2spec/capture.c
and I cannot tell you anything about it. However in the PDF I mentioned
before, you can find explanations for everything in that code.

About my code (process_image function):
I read in the PDF I mentioned before about the structure of YUYV (which is
very very similar to YUV) and I learned that it has one grey scale byte
(Y), followed by one blue channel byte (U), then one grey scale byte (Y
again) and finally one red channel byte (V).
The 2 grey scale bytes are 2 different pixels. The 2 colours (blue and red)
refer to both pixels and are the same for both pixels.
What I do in my code is: copying all the Y bytes (and ignoring all U and V
bytes).
It is done in lines 130-133 (it's a loop, just after the line "char
*bmp_data = ..."): as you can see, through "(2 * tmp)" I take only even
bytes (passing over odd bytes, which are U and V bytes), which is only the
grey scale part of my image.
If you are interested in colours, too, you can change my code, making it
consider U and V bytes too (and you can compute the green channel, knowing
that the grey channel contains R+G+B... Probably GREEN = (3*Y-(U+V)), but
I'm not sure about the "3", just read the PDF).
The rest of the code in "process_image" is just the creation of the header
of the bitmap (which, as I suppose, is not of your interest) and its
writing in a file.

Now I'll send you the code! I hope it will be helpful and useful!

Berello
/*
 *  V4L2 video capture example
 *
 *  This program can be used and distributed without restrictions.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <getopt.h>             /* getopt_long() */

#include <fcntl.h>              /* low-level i/o */
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include <asm/types.h>          /* for videodev2.h */

#include <linux/videodev2.h>

#define CLEAR(x) memset (&(x), 0, sizeof (x))
#define WIDTH  640
#define HEIGHT  480

typedef enum {
  IO_METHOD_READ,
  IO_METHOD_MMAP,
  IO_METHOD_USERPTR,
} io_method;

struct buffer {
        void *                  start;
        size_t                  length;
};

static char *           dev_name        = NULL;
static io_method  io    = IO_METHOD_MMAP;
static int              fd              = -1;
struct buffer *         buffers         = NULL;
static unsigned int     n_buffers       = 0;

static void
errno_exit                      (const char *           s)
{
        fprintf (stderr, "%s error %d, %s\n",
                 s, errno, strerror (errno));

        exit (EXIT_FAILURE);
}

static int
xioctl                          (int                    fd,
                                 int                    request,
                                 void *                 arg)
{
        int r;

        do r = ioctl (fd, request, arg);
        while (-1 == r && EINTR == errno);

        return r;
}

static void
process_image                   (const void *           p)
{
  int tmp;
  short int tmp_short;
  char *yuyv_img = (char *) p;
  
  char *bmp_fileheader = malloc(sizeof(char) * 14);
  /* "BM" */
  *(bmp_fileheader) = 'B';
  *(bmp_fileheader + 1) = 'M';
  /* Dimensione del file */
  tmp = 14 + 40 + 256 * 4 + WIDTH * HEIGHT;
  memcpy((bmp_fileheader+2), &tmp, 4);
  /* 0 */
  tmp = 0;
  memcpy((bmp_fileheader+6), &tmp, 4);
  /* Offset mappa */
  tmp = 14 + 40 + 256 * 4;
  memcpy((bmp_fileheader+10), &tmp, 4);
  
  char *bmp_infoheader = malloc(sizeof(char) * 40);
  /* 40 */
  tmp = 40;
  memcpy(bmp_infoheader, &tmp, 4);
  /* Larghezza */
  tmp = WIDTH;
  memcpy(bmp_infoheader + 4, &tmp, 4);
  /* Altezza */
  tmp = -HEIGHT;
  memcpy(bmp_infoheader + 8, &tmp, 4);
  /* 1 */
  tmp_short = 1;
  memcpy(bmp_infoheader + 12, &tmp_short, 2);
  /* bpp */
  tmp_short = 8;
  memcpy(bmp_infoheader + 14, &tmp_short, 2);
  /* 0 = nessuna compressione */
  tmp = 0;
  memcpy(bmp_infoheader + 16, &tmp, 4);
  /* 0 se non c'è compressione */
  memcpy(bmp_infoheader + 20, &tmp, 4);
  /* 0 = pixel/m orizzontali del dispositivo non specificati */
  memcpy(bmp_infoheader + 24, &tmp, 4);
  /* 0 = pixel/m verticali del dispositivo non specificati */
  memcpy(bmp_infoheader + 28, &tmp, 4);
  /* 0 = usa tutte le corrispondenze della tavolozza */
  memcpy(bmp_infoheader + 32, &tmp, 4);
  /* 0 = usa tutti i colori della tavolozza */
  memcpy(bmp_infoheader + 36, &tmp, 4);
  
  char *bmp_colortable = malloc(256 * 4 * sizeof(char));
  for (tmp = 0; tmp < 256; tmp++) {
    *(bmp_colortable + 4 * tmp) = tmp;
    *(bmp_colortable + 4 * tmp + 1) = tmp;
    *(bmp_colortable + 4 * tmp + 2) = tmp;
    *(bmp_colortable + 4 * tmp + 3) = 0;
  }
  
  char *bmp_data = malloc(WIDTH * HEIGHT * sizeof(char));
  for (tmp = 0; tmp < (WIDTH * HEIGHT * sizeof(char)); tmp++) {
    *(bmp_data + tmp) = *(yuyv_img + (2 * tmp));
  }
  printf("NO\n");
  FILE *filebmp = fopen("Webcam.bmp", "w");
  
  for (tmp = 0; tmp < 14; tmp++) {
    putc(*(bmp_fileheader + tmp), filebmp);
  }
  for (tmp = 0; tmp < 40; tmp++) {
    putc(*(bmp_infoheader + tmp), filebmp);
  }
  for (tmp = 0; tmp < (256 * 4 * sizeof(char)); tmp++) {
    putc(*(bmp_colortable + tmp), filebmp);
  }
  for (tmp = 0; tmp < (WIDTH * HEIGHT * sizeof(char)); tmp++) {
    putc(*(bmp_data + tmp), filebmp);
  }
  fflush(filebmp);
  fclose(filebmp);
  
  free(bmp_fileheader);
  free(bmp_infoheader);
  free(bmp_colortable);
  free(bmp_data);
        fputc ('.', stdout);
        fflush (stdout);
}

static int
read_frame      (void)
{
        struct v4l2_buffer buf;
  unsigned int i;

  switch (io) {
  case IO_METHOD_READ:
        if (-1 == read (fd, buffers[0].start, buffers[0].length)) {
                switch (errno) {
                case EAGAIN:
                        return 0;

      case EIO:
        /* Could ignore EIO, see spec. */

        /* fall through */

      default:
        errno_exit ("read");
      }
    }

        process_image (buffers[0].start);

    break;

  case IO_METHOD_MMAP:
    CLEAR (buf);

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

        if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {
                switch (errno) {
                case EAGAIN:
                        return 0;

      case EIO:
        /* Could ignore EIO, see spec. */

        /* fall through */

      default:
        errno_exit ("VIDIOC_DQBUF");
      }
    }

                assert (buf.index < n_buffers);

          process_image (buffers[buf.index].start);

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

    break;

  case IO_METHOD_USERPTR:
    CLEAR (buf);

        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_USERPTR;

    if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {
      switch (errno) {
      case EAGAIN:
        return 0;

      case EIO:
        /* Could ignore EIO, see spec. */

        /* fall through */

      default:
        errno_exit ("VIDIOC_DQBUF");
      }
    }

    for (i = 0; i < n_buffers; ++i)
      if (buf.m.userptr == (unsigned long) buffers[i].start
          && buf.length == buffers[i].length)
        break;

    assert (i < n_buffers);

        process_image ((void *) buf.m.userptr);

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

    break;
  }

  return 1;
}

static void
mainloop                        (void)
{
  unsigned int count;

        count = 1;

        while (count-- > 0) {
                for (;;) {
                        fd_set fds;
                        struct timeval tv;
                        int r;

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

                        /* Timeout. */
                        tv.tv_sec = 2;
                        tv.tv_usec = 0;

                        r = select (fd + 1, &fds, NULL, NULL, &tv);

                        if (-1 == r) {
                                if (EINTR == errno)
                                        continue;

                                errno_exit ("select");
                        }

                        if (0 == r) {
                                fprintf (stderr, "select timeout\n");
                                exit (EXIT_FAILURE);
                        }

      if (read_frame ())
                        break;
  
      /* EAGAIN - continue select loop. */
                }
        }
}

static void
stop_capturing                  (void)
{
        enum v4l2_buf_type type;

  switch (io) {
  case IO_METHOD_READ:
    /* Nothing to do. */
    break;

  case IO_METHOD_MMAP:
  case IO_METHOD_USERPTR:
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type))
      errno_exit ("VIDIOC_STREAMOFF");

    break;
  }
}

static void
start_capturing                 (void)
{
        unsigned int i;
        enum v4l2_buf_type type;

  switch (io) {
  case IO_METHOD_READ:
    /* Nothing to do. */
    break;

  case IO_METHOD_MMAP:
    for (i = 0; i < n_buffers; ++i) {
                struct v4l2_buffer buf;

            CLEAR (buf);

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

            if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
                        errno_exit ("VIDIOC_QBUF");
    }
    
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
      errno_exit ("VIDIOC_STREAMON");

    break;

  case IO_METHOD_USERPTR:
    for (i = 0; i < n_buffers; ++i) {
                struct v4l2_buffer buf;

            CLEAR (buf);

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

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

    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
      errno_exit ("VIDIOC_STREAMON");

    break;
  }
}

static void
uninit_device                   (void)
{
        unsigned int i;

  switch (io) {
  case IO_METHOD_READ:
    free (buffers[0].start);
    break;

  case IO_METHOD_MMAP:
    for (i = 0; i < n_buffers; ++i)
      if (-1 == munmap (buffers[i].start, buffers[i].length))
        errno_exit ("munmap");
    break;

  case IO_METHOD_USERPTR:
    for (i = 0; i < n_buffers;...stripped-down

Berello
static void
uninit_device                   (void)
{
        unsigned int i;

  switch (io) {
  case IO_METHOD_READ:
    free (buffers[0].start);
    break;

  case IO_METHOD_MMAP:
    for (i = 0; i < n_buffers; ++i)
      if (-1 == munmap (buffers[i].start, buffers[i].length))
        errno_exit ("munmap");
    break;

  case IO_METHOD_USERPTR:
    for (i = 0; i < n_buffers; ++i)
      free (buffers[i].start);
    break;
  }

  free (buffers);
}

static void
init_read      (unsigned int    buffer_size)
{
        buffers = calloc (1, sizeof (*buffers));

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

  buffers[0].length = buffer_size;
  buffers[0].start = malloc (buffer_size);

  if (!buffers[0].start) {
        fprintf (stderr, "Out of memory\n");
              exit (EXIT_FAILURE);
  }
}

static void
init_mmap      (void)
{
  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);
        }

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

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

static void
init_userp      (unsigned int    buffer_size)
{
  struct v4l2_requestbuffers req;
        unsigned int page_size;

        page_size = getpagesize ();
        buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);

        CLEAR (req);

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

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

        buffers = calloc (4, sizeof (*buffers));

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

        for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
                buffers[n_buffers].length = buffer_size;
                buffers[n_buffers].start = memalign (/* boundary */
page_size,
                                                     buffer_size);

                if (!buffers[n_buffers].start) {
          fprintf (stderr, "Out of memory\n");
                exit (EXIT_FAILURE);
    }
        }
}

static void
init_device                     (void)
{
        struct v4l2_capability cap;
        struct v4l2_cropcap cropcap;
        struct v4l2_crop crop;
        struct v4l2_format fmt;
  unsigned int min;

        if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {
                if (EINVAL == errno) {
                        fprintf (stderr, "%s is no V4L2 device\n",
                                 dev_name);
                        exit (EXIT_FAILURE);
                } else {
                        errno_exit ("VIDIOC_QUERYCAP");
                }
        }

        if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
                fprintf (stderr, "%s is no video capture device\n",
                         dev_name);
                exit (EXIT_FAILURE);
        }

  switch (io) {
  case IO_METHOD_READ:
    if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
      fprintf (stderr, "%s does not support read i/o\n",
         dev_name);
      exit (EXIT_FAILURE);
    }

    break;

  case IO_METHOD_MMAP:
  case IO_METHOD_USERPTR:
    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
      fprintf (stderr, "%s does not support streaming i/o\n",
         dev_name);
      exit (EXIT_FAILURE);
    }

    break;
  }


        /* Select video input, video standard and tune here. */


  CLEAR (cropcap);

        cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

        if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
                crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                crop.c = cropcap.defrect; /* reset to default */

                if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {
                        switch (errno) {
                        case EINVAL:
                                /* Cropping not supported. */
                                break;
                        default:
                                /* Errors ignored. */
                                break;
                        }
                }
        } else {  
                /* Errors ignored. */
        }


        CLEAR (fmt);

        fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.width       = WIDTH; 
        fmt.fmt.pix.height      = HEIGHT;
        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;

        if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))
                errno_exit ("VIDIOC_S_FMT");

        /* Note VIDIOC_S_FMT may change width and height. */

  /* Buggy driver paranoia. */
  min = fmt.fmt.pix.width * 2;
  if (fmt.fmt.pix.bytesperline < min)
    fmt.fmt.pix.bytesperline = min;
  min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
  if (fmt.fmt.pix.sizeimage < min)
    fmt.fmt.pix.sizeimage = min;

  switch (io) {
  case IO_METHOD_READ:
    init_read (fmt.fmt.pix.sizeimage);
    break;

  case IO_METHOD_MMAP:
    init_mmap ();
    break;

  case IO_METHOD_USERPTR:
    init_userp (fmt.fmt.pix.sizeimage);
    break;
  }
}

static void
close_device                    (void)
{
        if (-1 == close (fd))
          errno_exit ("close");

        fd = -1;
}

static void
open_device                     (void)
{
        struct stat st; 

        if (-1 == stat (dev_name, &st)) {
                fprintf (stderr, "Cannot identify '%s': %d, %s\n",
                         dev_name, errno, strerror (errno));
                exit (EXIT_FAILURE);
        }

        if (!S_ISCHR (st.st_mode)) {
                fprintf (stderr, "%s is no device\n", dev_name);
                exit (EXIT_FAILURE);
        }

        fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);

        if (-1 == fd) {
                fprintf (stderr, "Cannot open '%s': %d, %s\n",
                         dev_name, errno, strerror (errno));
                exit (EXIT_FAILURE);
        }
}

static void
usage                           (FILE *                 fp,
                                 int                    argc,
                                 char **                argv)
{
        fprintf (fp,
                 "Usage: %s [options]\n\n"
                 "Options:\n"
                 "-d | --device name   Video device name [/dev/video]\n"
                 "-h | --help          Print this message\n"
                 "-m | --mmap          Use memory mapped buffers\n"
                 "-r | --read          Use read() calls\n"
                 "-u | --userp         Use application allocated buffers\n"
                 "",
     argv[0]);
}

static const char short_options [] = "d:hmru";

static const struct option
long_options [] = {
        { "device",     required_argument,      NULL,           'd' },
        { "help",       no_argument,            NULL,           'h' },
        { "mmap",       no_argument,            NULL,           'm' },
        { "read",       no_argument,            NULL,           'r' },
        { "userp",      no_argument,            NULL,           'u' },
        { 0, 0, 0, 0 }
};

int
main                            (int                    argc,
                                 char **    ...stripped-down

Berello
Nothing, I cannot send you the code here.

If you send me your e-mail address, I'll send it to you.

Otherwise try to put together the code I sent here with this other:
http://v4l2spec.bytesex.org/v4l2spec/capture.c
...

If you don't want to send your e-mail address here, where everybody can
read it, you can send it to my e-mail address (which I posted previously).

Bye,
        Berello

Berello
Ok, I saw that the third and last part of the code is very short, for this
reason I'm sending it here (overall for who, in the future, will need the
whole code).
You can ask me the code by e-mail, this way it will be easier to save it on
your computer (no collages needed! :-P ).



int
main                            (int                    argc,
                                 char **                argv)
{
        dev_name = "/dev/video";

        for (;;) {
                int index;
                int c;
                
                c = getopt_long (argc, argv,
                                 short_options, long_options,
                                 &index);

                if (-1 == c)
                        break;

                switch (c) {
                case 0: /* getopt_long() flag */
                        break;

                case 'd':
                        dev_name = optarg;
                        break;

                case 'h':
                        usage (stdout, argc, argv);
                        exit (EXIT_SUCCESS);

                case 'm':
                        io = IO_METHOD_MMAP;
      break;

                case 'r':
                        io = IO_METHOD_READ;
      break;

                case 'u':
                        io = IO_METHOD_USERPTR;
      break;

                default:
                        usage (stderr, argc, argv);
                        exit (EXIT_FAILURE);
                }
        }

        open_device ();

        init_device ();

        start_capturing ();

        mainloop ();

        stop_capturing ();

        uninit_device ();

        close_device ();

        exit (EXIT_SUCCESS);

        return 0;
}

Irinel
Hi,

I run your code and I only get a bad frame. I opened the bmp image on PC
machine and it only shows a lot of black and white horizontal lines. I
changed your process_image function and I get 100 captures but all are the
same.

Did you open your bmp image on PC machine and look fine ?

P.S. I sent you a mail.

Thanks

Irinel
Hi Neyna,

I'm trying to get a capture with resolution 176x144 but it's automatically
reset to 320x240 and the image type is JPG. Do you know why it's dropped ?
The best type of capture what I want to get is RGB565 but I'm also glad
with YUV or BMP, just compressed no. The resolution is not significant for
me, 176x144 it's ok.



Could you send me your code ?

Thanks

azzido
Could anyone help me ?

Thanks

themadmax
I've got the same problem with my logitech webcam: Enable to set frame size
upper 176x144.
So when I'm doing lsusb command I've got :
Bus 001 Device 003: ID 046d:080f Logitech, Inc. 
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
In arm processor specification is written 1.1 too.
With another webcam, I can take mutch sizer image but in jpeg format:
ID 0ac8:307b Z-Star Microelectronics Corp. USB 1.1 WebCam

mykorritsa
I'm using Logitech C270 and I ran into the same problem. I'm using the
fswebcam program and with kernel 3.2.9 I was able to get YUYV with
resolution 1280x960 but with kernel 3.5.7 only that pity 176x144 and the
palette color channels are also wrong.

The fswebcam application was using old kernel headers with a static file
videodev2.h included in the sources. I fixed that to use the recent kernel
headers but it still does not work properly.