v4l2grab - Grabbing JPEGs from V4L2 devices

A friend of mine, wanted to use a standard USB WebCam as an IPCam. He used an old Media-Receiver Box (T-Online S100) and installed Gentoo Linux on an CF Card.

Since Kernel 2.6.27 most of the USB webcams are supported through the Linux UVC drivers, which provides an Video4Linux2 Interface to those cams. We found some programs who claimed being able to grab JPEG images from V4L2 Cams, but most of them either didn't compile, supported only V4L Version 1 or just brought up some other errors.

So I checked up the Video for Linux Two API Specification and found there in Appendix B a small sample of howto communicate with the Cam. I adapted it to our needs and included an converter from YUV colorspace to RGB. Finally I added some code to support the export of JPEG images.

You can download it here: v4l2grab Version 0.1

The whole program is written in C and only needs libjpeg to compile. There are different ways to communicate with the camera, if you want to support all, you should go best with:

gcc v4l2grab.c -o v4l2grab -Wall -ljpeg -DIO_READ -DIO_MMAP -DIO_USERPTR

If you compiled the program, you can get some images with:

./v4l2grab -o image.jpg

With -W width -H height its possible to adjust the size of the image. If the camera doesn't support the resolution the programs adjusts it automatically and prints an information on stderr.

The current version of V4L2grab can be found on github.

This entry was posted in Linux, Software and tagged , by twam. Bookmark the permalink.

About the author

My name is Tobias Müller. I'm interested in com­puters, physics, elec­tronics and photo­graphy. more …

85 thoughts on “v4l2grab - Grabbing JPEGs from V4L2 devices

  1. I'm trying to use a webcam in V4L2_PIX_FMT_MJPEG format (not V4L2_PIX_FMT_YUYV) and grab image into jpeg files, some ideas on how do it?

  2. Hoi,

    Great work! It would be a good idea to add the compile statement to the readme file on github.
    Works like a charm!

    Groeten,
    Frank.

  3. I just built this for the DM3730 Logic SOM running Linux built from the 2.6.32 OMAP PSP_03.00.01.06 kernel from TI. I used libjpeg62-dev. Worked right out of the box. Great work.

    Thanks,
    Jemiah
    .

  4. I was running v4l2grab on ARM with logitech C200.
    Even set the format by using VIDIOC_S_FMT, I still get 176x144 size of image.
    I saw the notes in source as follow:
    'Note VIDIOC_S_FMT may change width and height.'
    Could you please share the more detail about this?

  5. Hi,

    I'm trying to compile v4l2grab for an ARM processor and can see that some of you have already succeded in that. Could you please give me a step by step guide on how to accomplish this task? Thanks in advanced

    /Anders

  6. This is a very useful little utility, nice code, but has a stutter.

    I've added some debugging text

    static void imageProcess(const void* p)
    {
            unsigned char* src = (unsigned char*)p;
            unsigned char* dst = malloc(width*height*3*sizeof(char));
    
            // convert from YUV422 to RGB888
    printf("Munge\n"); fflush(stdout);
            YUV422toRGB888(width,height,src,dst);
    
            // write jpeg
    printf("Write\n"); fflush(stdout);
            jpegWrite(dst);
    
            // free temporary image
            free(dst);
    }
    # ./v4l2grab -m -o test.jpg
    1Open
    Init
    Start
    Frameread
    Frameread
    Munge
    Write
    Frameread
    Munge
    Write

    Should it not read a frame once, process it once, and write t once ? 🙂

    Thanks,
    Jon

  7. Hallo Tobias,

    super kleines Tool. Genau was ich gerade gesucht habe, um nicht mit Kanonen auf Spatzen zu schiessen.
    Runter laden, übersetzen und laufen lassen. Ohne Fehler; einfach so !!!

    Vielen Dank
    Franz

  8. Was ich vergessen habe:

    I use OpenSuse 12.1 (64 Bit ) on AMD Quadcore 2,9 Ghz with USB - Logitech, Inc. Webcam C270 .

    Thanks
    Franz

  9. /tmp/cc6gk2Pb.o: In function `imageProcess':
    v4l2grab.c:(.text+0x258): undefined reference to `YUV422toRGB888'
    collect2: ld returned 1 exit status

    i am getting this error when i compile the programme
    please help to fix this problem

  10. @vijay
    It look like you tried to compile it with the line given in the post above. The latest version supplies a makefile, so you just have to run 'make' to compile the program.

  11. Thanks for sharing this example, it was very helpful! Moreover, work out of the box 😉 Thanks again Tobias.

  12. This runs without error:
    # gcc v4l2grab.c -o v4l2grab -Wall -ljpeg -DIO_READ -DIO_MMAP -DIO_USERPTR

    But I am getting a "select timeout" error when I run the following (on a BeagleBone Armv7 processor)
    # ./v4l2grab -o image.jpg

  13. @twam The latest version from Github gives me the following error:

    # make
    gcc v4l2grab.c -c -Wall -march=native -Werror
    cc1: error: bad value (native) for -march switch
    make: *** [v4l2grab.o] Error 1
  14. @twam I was able to compile and run ./v4l2grab -o image.jpg without errors but I can't seem to locate any produced image files.

  15. hi again.
    I believe to compile libjped. the screen gave this message

    halil@toshiba:~/İndirilenler/jpeg-8d$ ./configure 
    checking build system type... i686-pc-linux-gnu
    [...]
    config.status: executing libtool commands

    But I tried to work gcc v4l2grab.c -o v4l2grab -Wall -ljpeg -DIO_READ -DIO_MMAP -DIO_USERPTR and I gave this error message

    v4l2grab.c:26:2: error: #error You have to include one of IO_READ, IO_MMAP oder IO_USERPTR!
    v4l2grab.c:45:21: error: jpeglib.h: Böyle bir dosya ya da dizin yok
    [...]

    Can you help me about this issue. what do I do? thanks you for your helps

  16. @halo
    After running configure, you usually need to run make; make install. Detailed information should be found in the README.

    But you should think of installing it through your distributions package manager. There should be something like a libjpeg-dev package.

  17. Hi @twan,
    I compiled this app successful, and when I ran it with
    # ./v4l2grab -d /dev/video0 -o out.jpg
    and the only thing I'v got is
    Using pixel format V4L2_PIX_FMT_YUYV.
    and no any output images. Can you please help me out here? Thx.

  18. One error is caught:
    Pixel format V4L2_PIX_FMT_JPEG not supported!

    How to grab a JPEG frame from a usb camera with V4L2_PIX_FMT_JPEG support only?

  19. HI,

    Thanks for sharing!
    I'm a beginner on Linux and we need our camera to take pictures for our project.
    I am using a beagleboard xM that runs Angstrom with kernel 2.6.32.
    I first installed libjpeg using tarbal from their website. And then i tired your v0.1 and latest version from github; both of them were built fine but when i run them they give:
    ./v4l2grab: error while loading shared libraries: libjpeg.so.9: cannot open shared object file: No such file or directory

    Any idea?

    Your help is very much appreciated!!

    • You can run

      ldd v4l2grab

      to see against with librarys your program is linked. You should something like

      	linux-vdso.so.1 =>  (0x00007fff70185000)
      	libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f0630710000)
      	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0630351000)
      	/lib64/ld-linux-x86-64.so.2 (0x00007f0630984000)
      

      If libjpeg.so.* is not found, check that the file is one of your lib directories or set LD_LIBRARY_PATH accordingly. Maybe you forgot an make install as root after compiling your libjpeg.

      • Hi,

        Thanks alot for your fast reply!
        I did check with "ldd" and yes it says " libjpeg.so.9 => not found"
        However, when I do "ls /usr/local/lib", the libjpeg.so* files are there...

        So i copied the lbjpeg.so.9 from /usr/local/lib to /lib and now v4l2Grab works.

        However, when I call imgcmp, which is a part of jasPer and that it seems to require libjpeg at runtime, it prompts" JPEG decoder not available"....and asks me to install libjpeg...
        I did "ldd imgcmp" and it says:
        libm.so.6 => /lib/libm.so.6 (0x40026000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40099000)
        libc.so.6 => /lib/libc.so.6 (0x400ab000)
        /lib/ld-linux.so.3 (0x40000000)
        Which seems to say that all needed .so files are in /lib...

        I don't know whats going on...

        Thanks,

  20. Hi Tobias,
    thanks for posting the code. I confirm that the code compiles flawlessly and works on my Debian Squeeze system. I was able to capture images at the highest possible resolution ( 2592 x 1944 pixes) from a Logitech C-910 webcam.
    Cheers, Rob

  21. Hi! I got some problem when I was cross-compiling the code in hope to port your program on ARM processor. The make error messages are something like that:

    /opt/embedded/collections/v4l2grab/v4l2grab.c:118: undefined reference to `v4l2_ioctl'

    I know it's linking errors. But I do have libv4l2.so and libv4lconvert.so as well as their header files in my arm-linux-gcc compiler directory. That's weird. Your code has been successfully compiled on my i686 platform PC. So I want to ask what's the problem there? Thank you!

  22. Did you tell your compile to actually link the libraries? May you have to add the path to search in for the cross-compiled libraries.

    • OK, I've solved the compiling problem. I'm not very familiar with gcc command so I just added into Makefile -I"compiler include directory" and -L"library directory" rather than -lv4l2 and -lv4lconvert.
      Also, for arm-linux-gcc, there was also a problem occurred: undefined reference to `rpl_malloc'. I solved this problem by deleting the line:
      #undef malloc
      in file config.h.in and then rerunning ./configure --host=arm-linux --target=arm-linux. After all those steps, I finally got an executable binary file. Hope this will help others who may have same problems. But I'm just curious about why this 'rpl_malloc' problem happens?

  23. Can you tell me if you can make to grab the RAW no compress .jpeg any way well done for the super software and work.

    If any information on how to make this change will be very help full.

    Regards
    Kenny

    • You can change the software to write the RAW data directly to disk, but most software won't open it.

      If you want to have best quality just select a JPEG quality of 100.

  24. I looking for Bayer RGB format, and save to .pnm is any way you can help me with this ?

    Regard,

    Kenny

  25. I don't think that the camera provide it in that format, so you would transform it anyhow. So just write out as in JPEG in 100 Quality and then read it on in your own tool to convert it to pnm.

  26. You could write a routine to store it directly into pnm yourself, but if the quality is bad with a high JPEG quality setting, then maybe your camera is providing low quality data.

  27. Is not the camera, is the jpeg compression from the program, any way I will still post any new if I have made any change to the progam.

    Regards
    Kenny

  28. Hi,

    I am using camera in my project.I'm trying to test it in linux 2.6.34.12 version.
    I'm running ./uvccapture -m from command line and getting the following error
    ioctl querycontrol error 22

    could you help me anyways..!!!

      • it is iball,Primax Elctronics manufacturer.
        Model No exactly i dn't know myself,but it is USB camera,working with cheese application fine.

          • Sir,
            I am very much sure that i am using linux.Actually uvccapture is an easy script that we are using.We want to use our camera in Raspberry Pi.But testing need to be done in Linux.

            cheese is working fine if used in GUI,but if used through command line it shows error.

          • If you're using Linux doesn't mean that you're using my program from this blog post. As you've written, you're using 'uvccapture' and I don't know this/program or script, so that I can't help. :/

  29. Hi,

    I am looking for example of how to use v4l2 mem2mem code driver on linux. Can anyone please point me to an example. Thanks.

  30. Hello there,
    I am using the camera specified in this tutorial:
    https://ipeerbhai.wordpress.com/2013/09/01/usb-camera-on-beaglebone-black/

    For now i am testing the code on a x64 Linux Mint 16 distro before i move it to arm enviroment. I have succesfully installed the libraries and compiled the code. I run the command using:

    ./v4l2grab -W 640 -H 480 -d /dev/video0 -q 100 -o img.jpeg

    And i do get an output but it is mostly green screen... Heres a link how it looks like.
    https://dl.dropboxusercontent.com/u/14154631/img.jpeg

    I would be really gratefull if you could drop some help here.

    • Hi!

      It's a little bit hard to remote debug without much information about the camera. Usually the cameras that won't work have an unsupported video format.
      Does the same thing happen if you try to capture smaller images? Are you using the latest version from GitHub?

      Tobias

      • I havent tried with smaller resolution. I am using the one that is posted on this site. I will try to use the one from Github if it differs.

      • Hello there again,
        Althrough i have succesfully used the software on my virtual machine it seems not to work on beaglebone black... When i take the picture the program just hangs in the middle of picture taking process and i have to kill it. I have checked it with 2 different cameras. Do you have any hits i could try to make it work?

        • Unfortunately I don't have any USB cameras lying around so I could test it on my BeagleBone Black. Maybe the power supply of the BBB is not enough, so you could try using a hub in between.

  31. it was just what I was looking for !!
    with the graber (0.3) I am able to capture jpg from my camera connected to tv capture (easyCap - empia chip) connected to my raspberry pi USB port.
    I changed the code so it will repeatedly send the new jpg's to /dev/shm/ so I can stream it as jpeg over the net.
    at the same time I am doing almost the same with my raspicam, so I have both camera online (it is great) I added my camera/tvcapture to github "compatible list".
    my raspbery pi cpu only goes up to 20%, it is great.

    couple of questions:
    1) played with everything and I still get jitters every now and then (it is not too bad), is there recommended setting or a way to improve performance.
    2) what does -r -u -m improve if any
    3) what does the FPS means, it will wait that amount of frames ? read in between ?
    I tried playing with that (-f) but it seems to do nothing ...

    I will apprciate an answer,
    but thanks eitherway (good job)

    • 1) I'm not aware of any
      2) That's just so select the method how the data is got from the v4l2 interface. It should not make any differences on the image output, but might affect speed. Also not all cameras might support all modes.
      3) It only affects the request to the hardware. You'll see now changes as only one image is saved.

  32. Hi twam,
    I successfully compiled and used your code in Android to capture Image from a USB Microscope. See the Image http://imgur.com/y8fjLMC . It has pink and green strips overlay. Can you help me to fix it . thanks for it

  33. This is working on my optiplex 760 running debian wheezy using a "Sabrent USB-AVCPT" connected to a ps2. The video mode for this adapter I believe it NTSC.
    At first it would capture green frames sometimes but I upp'd the count in mainLoop and now it gets a good frame everytime.

  34. Hi Tobias
    First of all thanks for this wonderful utility. I have a query as follows:
    I tried running v4l2grab -d /dev/video0 -o test.jpg and it worked well. I just wanted to know that instead of getting it as test.jpg can I store the image in some buffer and then I can access that buffer and do further operations on the buffer.

    Thanks
    Bhaarat

  35. Hi Tobias

    Also can you please explain or point me to understand how -mmap and read() works with this v4l2grab utility ? Is -mmap option the solution to my previous queries ?

    Thanks
    Bhaarat

    • mmap is just one option how the v4l2grab get's the data from your device. If you want to work with the data in a buffer instead of writing it to a jpeg file you should expand the v4l2grab source code to your needs or implement the needed changes into your software. For this you can use the v4l2grab source code as a template.

  36. Hi,

    Can you give an example with this to continuous streaming of images for each 1 second and overwrite in a same file in command line.

  37. Hi Tobias,

    May i know whether can we use the same v4l2grab for capturing image from a camera on MIPI CSI2 interface?

    If not what changes is required.

    Note: i am trying to interface AVM-737 camera.

    Thanks,
    Nits

  38. Dear Tobias, thanks for the source. I used it on the Raspberry Pi 3. The V4L2 interface was working fine, however due to the undersized ARM CPU of the Pi, rendering performance was not good. Only 9-10 fps. I decided to move YUYV to RGB conversion to GPU. Now I can get 26-27 fps. If anyone is interested, here's the link:
    https://github.com/ilkercakir/VideoCapture

    • Neat idea to put the conversion on the GPU! It's interesting to see how many people use this small tool for so many different occasions.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.