Skip to content

Instantly share code, notes, and snippets.

@Circuitsoft
Created August 4, 2011 22:02
Show Gist options
  • Save Circuitsoft/1126411 to your computer and use it in GitHub Desktop.
Save Circuitsoft/1126411 to your computer and use it in GitHub Desktop.

Revisions

  1. Circuitsoft revised this gist Aug 4, 2011. 1 changed file with 27 additions and 0 deletions.
    27 changes: 27 additions & 0 deletions Output
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    Driver Caps:
    Driver: "omap3"
    Card: "omap3/mt9v032//"
    Bus: ""
    Version: 0.0
    Capabilities: 04000001
    Camera Cropping:
    Bounds: 752x480+0+0
    Default: 752x480+0+0
    Aspect: 1/1
    FMT : CE Desc
    --------------------
    UYVY: UYVY, packed
    YUYV: YUYV (YUV 4:2:2), packed
    BA10: Bayer10 (GrR/BGb)
    Selected Camera Mode:
    Width: 752
    Height: 480
    PixFmt: BA10
    Field: 1
    Length: 724992
    Address: 0x40156000
    Image Length: 0
    omap-iommu omap-iommu.0: omap2_iommu_fault_isr: da:000c0000 translation fault
    omap-iommu omap-iommu.0: iommu_fault_handler: da:000c0000 pgd:dfd10000 *pgd:9f4d1c01 pte:df4d1f00 *pte:00000000
    omap-iommu omap-iommu.0: omap2_iommu_fault_isr: da:000c0000 translation fault
    omap-iommu omap-iommu.0: iommu_fault_handler: da:000c0000 pgd:dfd10000 *pgd:9f4d1c01 pte:df4d1f00 *pte:00000000
  2. Circuitsoft created this gist Aug 4, 2011.
    207 changes: 207 additions & 0 deletions vidtest.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,207 @@
    #include <errno.h>
    #include <fcntl.h>
    #include <linux/videodev2.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <unistd.h>

    uint8_t *buffer;

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

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

    return r;
    }

    int print_caps(int fd)
    {
    struct v4l2_capability caps = {};
    if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &caps))
    {
    perror("Querying Capabilities");
    return 1;
    }

    printf( "Driver Caps:\n"
    " Driver: \"%s\"\n"
    " Card: \"%s\"\n"
    " Bus: \"%s\"\n"
    " Version: %d.%d\n"
    " Capabilities: %08x\n",
    caps.driver,
    caps.card,
    caps.bus_info,
    (caps.version>>16)&&0xff,
    (caps.version>>24)&&0xff,
    caps.capabilities);


    struct v4l2_cropcap cropcap = {0};
    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (-1 == xioctl (fd, VIDIOC_CROPCAP, &cropcap))
    {
    perror("Querying Cropping Capabilities");
    return 1;
    }

    printf( "Camera Cropping:\n"
    " Bounds: %dx%d+%d+%d\n"
    " Default: %dx%d+%d+%d\n"
    " Aspect: %d/%d\n",
    cropcap.bounds.width, cropcap.bounds.height, cropcap.bounds.left, cropcap.bounds.top,
    cropcap.defrect.width, cropcap.defrect.height, cropcap.defrect.left, cropcap.defrect.top,
    cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator);

    int support_grbg10 = 0;

    struct v4l2_fmtdesc fmtdesc = {0};
    fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    char fourcc[5] = {0};
    char c, e;
    printf(" FMT : CE Desc\n--------------------\n");
    while (0 == xioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc))
    {
    strncpy(fourcc, (char *)&fmtdesc.pixelformat, 4);
    if (fmtdesc.pixelformat == V4L2_PIX_FMT_SGRBG10)
    support_grbg10 = 1;
    c = fmtdesc.flags & 1? 'C' : ' ';
    e = fmtdesc.flags & 2? 'E' : ' ';
    printf(" %s: %c%c %s\n", fourcc, c, e, fmtdesc.description);
    fmtdesc.index++;
    }

    if (!support_grbg10)
    {
    printf("Doesn't support GRBG10.\n");
    return 1;
    }

    struct v4l2_format fmt = {0};
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = 752;
    fmt.fmt.pix.height = 480;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SGRBG10;
    fmt.fmt.pix.field = V4L2_FIELD_NONE;

    if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
    {
    perror("Setting Pixel Format");
    return 1;
    }

    strncpy(fourcc, (char *)&fmt.fmt.pix.pixelformat, 4);
    printf( "Selected Camera Mode:\n"
    " Width: %d\n"
    " Height: %d\n"
    " PixFmt: %s\n"
    " Field: %d\n",
    fmt.fmt.pix.width,
    fmt.fmt.pix.height,
    fourcc,
    fmt.fmt.pix.field);
    return 0;
    }

    int init_mmap(int fd)
    {
    struct v4l2_requestbuffers req = {0};
    req.count = 1;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;

    if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
    {
    perror("Requesting Buffer");
    return 1;
    }

    struct v4l2_buffer buf = {0};
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    buf.index = 0;
    if(-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
    {
    perror("Querying Buffer");
    return 1;
    }

    buffer = mmap (NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
    printf("Length: %d\nAddress: %p\n", buf.length, buffer);
    printf("Image Length: %d\n", buf.bytesused);

    return 0;
    }

    int capture_image(int fd)
    {
    struct v4l2_buffer buf = {0};
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    buf.index = 0;
    if(-1 == xioctl(fd, VIDIOC_QBUF, &buf))
    {
    perror("Query Buffer");
    return 1;
    }

    if(-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type))
    {
    perror("Start Capture");
    return 1;
    }

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(fd, &fds);
    struct timeval tv = {0};
    tv.tv_sec = 2;
    int r = select(fd+1, &fds, NULL, NULL, &tv);
    if(-1 == r)
    {
    perror("Waiting for Frame");
    return 1;
    }

    if(-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
    {
    perror("Retrieving Frame");
    return 1;
    }

    int outfd = open("out.img", O_RDWR);
    write(outfd, buffer, buf.bytesused);
    close(outfd);

    return 0;
    }

    int main()
    {
    int fd;

    fd = open("/dev/video0", O_RDWR);
    if (fd == -1)
    {
    perror("Opening video device");
    return 1;
    }

    if(print_caps(fd))
    return 1;

    if(init_mmap(fd))
    return 1;

    if(capture_image(fd))
    return 1;

    close(fd);
    return 0;
    }