Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

video(4) v4l2 use



I am just trying out the video(4) interface, and managed to grab a video
frame from the uvideo webcam with the attached program. The thing is, after
a few goes, the program prints:

device index: 0
input name: "Camera" (0)
  0: YUYV
  1: MJPEG
height: 480
width: 640
pixel format: V4L2_PIX_FMT_YUYV (56595559)
field: V4L2_FIELD_NONE (0001)
bytes per line: 1280
image size: 614400
colour space: UNKNOWN V4L2_COLORSPACE (0)
video: read from camera: Input/output error


Input/output error doesn't give me much of a clue. Is some other call
needed beforehand, or is close() not sufficient after grabbing the
last frame?

Cheers,

Patrick

% videoctl -a
info.cap.card=XZB2Q05X 2SF001, rev 2.00/12.13
info.cap.driver=uvideo
info.cap.bus_info=usb:00000006
info.cap.version=6.99.7
info.cap.capabilities=0x5000001<VIDEO_CAPTURE,READWRITE,STREAMING>
info.format.0=YUYV
info.format.1=MJPEG
info.input.0=Camera
info.input.0.type=baseband
info.standard.0=webcam
ctrl.sharpness=12
#include <sys/ioctl.h>
#include <sys/videoio.h>

#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MZERO(x) memset(&x, 0, sizeof(x))

void
print_fmt(struct v4l2_format *f)
{
        printf("height: %d\n", f->fmt.pix.height);
        printf("width: %d\n", f->fmt.pix.width);
        printf("pixel format: ");
        switch (f->fmt.pix.pixelformat) {
        case V4L2_PIX_FMT_RGB332:       printf("V4L2_PIX_FMT_RGB332");  break;
        case V4L2_PIX_FMT_RGB555:       printf("V4L2_PIX_FMT_RGB555");  break;
        case V4L2_PIX_FMT_RGB565:       printf("V4L2_PIX_FMT_RGB565");  break;
        case V4L2_PIX_FMT_RGB555X:      printf("V4L2_PIX_FMT_RGB555X"); break;
        case V4L2_PIX_FMT_RGB565X:      printf("V4L2_PIX_FMT_RGB565X"); break;
        case V4L2_PIX_FMT_BGR24:        printf("V4L2_PIX_FMT_BGR24");   break;
        case V4L2_PIX_FMT_RGB24:        printf("V4L2_PIX_FMT_RGB24");   break;
        case V4L2_PIX_FMT_BGR32:        printf("V4L2_PIX_FMT_BGR32");   break;
        case V4L2_PIX_FMT_RGB32:        printf("V4L2_PIX_FMT_RGB32");   break;
        case V4L2_PIX_FMT_GREY: printf("V4L2_PIX_FMT_GREY");    break;
        case V4L2_PIX_FMT_YUYV: printf("V4L2_PIX_FMT_YUYV");    break;
        case V4L2_PIX_FMT_UYVY: printf("V4L2_PIX_FMT_UYVY");    break;
        case V4L2_PIX_FMT_Y41P: printf("V4L2_PIX_FMT_Y41P");    break;
        case V4L2_PIX_FMT_YVU420:       printf("V4L2_PIX_FMT_YVU420");  break;
        case V4L2_PIX_FMT_YUV420:       printf("V4L2_PIX_FMT_YUV420");  break;
        case V4L2_PIX_FMT_YVU410:       printf("V4L2_PIX_FMT_YVU410");  break;
        case V4L2_PIX_FMT_YUV410:       printf("V4L2_PIX_FMT_YUV410");  break;
        case V4L2_PIX_FMT_YUV422P:      printf("V4L2_PIX_FMT_YUV422P"); break;
        case V4L2_PIX_FMT_YUV411P:      printf("V4L2_PIX_FMT_YUV411P"); break;
        case V4L2_PIX_FMT_NV12: printf("V4L2_PIX_FMT_NV12");    break;
        case V4L2_PIX_FMT_NV21: printf("V4L2_PIX_FMT_NV21");    break;
        case V4L2_PIX_FMT_SBGGR8:       printf("V4L2_PIX_FMT_SBGGR8");  break;
        case V4L2_PIX_FMT_YYUV: printf("V4L2_PIX_FMT_YYUV");    break;
        case V4L2_PIX_FMT_HI240:        printf("V4L2_PIX_FMT_HI240");   break;
        case V4L2_PIX_FMT_MJPEG:        printf("V4L2_PIX_FMT_MJPEG");   break;
        case V4L2_PIX_FMT_JPEG: printf("V4L2_PIX_FMT_JPEG");    break;
        case V4L2_PIX_FMT_DV:   printf("V4L2_PIX_FMT_DV");      break;
        case V4L2_PIX_FMT_MPEG: printf("V4L2_PIX_FMT_MPEG");    break;
        case V4L2_PIX_FMT_WNVA: printf("V4L2_PIX_FMT_WNVA");    break;
        case V4L2_PIX_FMT_SN9C10X:      printf("V4L2_PIX_FMT_SN9C10X"); break;
        default:        printf("UNKNOWN V4L2_PIX_FMT"); break;
        }
        printf(" (%04x)\n", f->fmt.pix.pixelformat);
        printf("field: ");
        switch(f->fmt.pix.field) {
        case V4L2_FIELD_ANY:        printf("V4L2_FIELD_ANY");        break;
        case V4L2_FIELD_NONE:       printf("V4L2_FIELD_NONE");       break;
        case V4L2_FIELD_TOP:        printf("V4L2_FIELD_TOP");        break;
        case V4L2_FIELD_BOTTOM:     printf("V4L2_FIELD_BOTTOM");     break;
        case V4L2_FIELD_INTERLACED: printf("V4L2_FIELD_INTERLACED"); break;
        case V4L2_FIELD_SEQ_TB:     printf("V4L2_FIELD_SEQ_TB");     break;
        case V4L2_FIELD_SEQ_BT:     printf("V4L2_FIELD_SEQ_BT");     break;
        case V4L2_FIELD_ALTERNATE:  printf("V4L2_FIELD_ALTERNATE");  break;
        default:                    printf("UNKNOWN V4L2_FIELD");    break;
        }
        printf(" (%04x)\n", f->fmt.pix.field);
        printf("bytes per line: %d\n", f->fmt.pix.bytesperline);
        printf("image size: %d\n", f->fmt.pix.sizeimage);
        printf("colour space: ");
        switch (f->fmt.pix.colorspace) {
        case V4L2_COLORSPACE_SMPTE170M: printf("V4L2_COLORSPACE_SMPTE170M"); 
break;
        case V4L2_COLORSPACE_SMPTE240M: printf("V4L2_COLORSPACE_SMPTE240M"); 
break;
        case V4L2_COLORSPACE_REC709:    printf("V4L2_COLORSPACE_REC709");    
break;
        case V4L2_COLORSPACE_BT878:     printf("V4L2_COLORSPACE_BT878");     
break;
        case V4L2_COLORSPACE_470_SYSTEM_M:
                printf("V4L2_COLORSPACE_470_SYSTEM_M");
                break;
        case V4L2_COLORSPACE_470_SYSTEM_BG:
                printf("V4L2_COLORSPACE_470_SYSTEM_BG");
                break;
        case V4L2_COLORSPACE_JPEG:      printf("V4L2_COLORSPACE_JPEG");   break;
        case V4L2_COLORSPACE_SRGB:      printf("V4L2_COLORSPACE_SRGB");   break;
        default:                        printf("UNKNOWN V4L2_COLORSPACE"); 
break;
        }
        printf(" (%d)\n", f->fmt.pix.colorspace);
}

int
main()
{
        struct v4l2_capability capability;
        struct v4l2_format format;
        struct v4l2_fmtdesc formatdesc;
        struct v4l2_input inp;
        int videofd, filefd, devindex;
        size_t buflen;
        ssize_t rdlen, wrlen;
        uint8_t *buf;

        videofd = open("/dev/video0", O_RDWR); /* from spec, not RDONLY */
        if (videofd == -1)
                err(1, "open camera");

        MZERO(capability);
        if (ioctl(videofd, VIDIOC_QUERYCAP, &capability) == -1)
                err(1, "query capability");
        if ((capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0)
                err(1, "device doesn't capture video");
        if ((capability.capabilities & V4L2_CAP_READWRITE) == 0)
                err(1, "device doesn't support read()");

        if (ioctl(videofd, VIDIOC_G_INPUT, &devindex) == -1)
                err(1, "VIDIOC_G_INPUT");
        printf("device index: %d\n", devindex);

        MZERO(inp);
        inp.index = devindex;
        if (ioctl(videofd, VIDIOC_ENUMINPUT, &inp) == -1)
                err(1, "VIDIOC_ENUMINPUT");
        printf("input name: \"%s\" (%d)\n", inp.name, inp.status);

        MZERO(formatdesc);
        formatdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        formatdesc.index = 0;
        while (ioctl(videofd, VIDIOC_ENUM_FMT, &formatdesc) != -1) {
                printf("%3u: %s\n", formatdesc.index, formatdesc.description);
                formatdesc.index++;
        }

        MZERO(format);
        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(videofd, VIDIOC_G_FMT, &format) == -1)
                err(1, "get format");

        print_fmt(&format);

        buflen = format.fmt.pix.width * format.fmt.pix.bytesperline;
        buf = malloc(buflen);
        if (buf == NULL)
                err(1, "buf malloc failed request for %zd bytes", buflen);

        rdlen = read(videofd, buf, buflen);
        if (rdlen == -1)
                err(1, "read from camera");

        printf("Read %zu bytes (%zd) from camera\n", rdlen, buflen);

        close(videofd);

        filefd = open("image.yuv", O_WRONLY | O_CREAT, 0644);
        if (filefd == -1)
                err(1, "open file \"image.yuv\"");

        wrlen = write(filefd, buf, rdlen);
        if (wrlen == -1)
                err(1, "write to file");

        close(filefd);

        return 0;
}


Home | Main Index | Thread Index | Old Index