V4L2视频采集,mmap (0) failed: Invalid argument

时间:2022-10-14 17:16:00
Ubuntu10.04下编译,v4l2采集CMOS摄像头,ARM11板子上运行linux2.6.28系统,程序运行到这时出现问题,framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
        if (framebuf[i].start == MAP_FAILED) {
            LOG("mmap (%d) failed: %s\n", i, strerror(errno));
            return -1;
        }
出现问题:mmap (0) failed: Invalid argument
找不出什么问题,大神求助

3 个解决方案

#1


#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
//#define ANDROID_ENV

#ifdef ANDROID_ENV
#define LOG LOGV
#else
#define LOG printf
#endif
#define CAMERA_DEVICE "/dev/video0"
#define CAPTURE_FILE "frame.jpeg"
#define VIDEO_WIDTH 512
#define VIDEO_HEIGHT 400
#define VIDEO_FORMAT V4L2_PIX_FMT_YUYV
#define BUFFER_COUNT 1
struct fimc_buffer {
        int length;
        void *start;
    } framebuf[BUFFER_COUNT];
struct v4l2_buffer buf;
int main()
{
   struct v4l2_fmtdesc fmtdesc;
    int i, ret,fd;
    // Open Device

    fd = open(CAMERA_DEVICE, O_RDWR, 0);
    if(fd < 0){
        LOG("Open %s failed\n", CAMERA_DEVICE);
        return -1;
    }
    // Query Capability
    struct v4l2_capability cap;
    ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
    if (ret < 0) {
        LOG("VIDIOC_QUERYCAP failed (%d)\n", ret);
        return ret;
    }
    // Print capability infomations
    LOG("Capability Informations:\n");
    LOG(" driver: %s\n", cap.driver);
    LOG(" card: %s\n", cap.card);
    LOG(" bus_info: %s\n", cap.bus_info);
    LOG(" version: %08X\n", cap.version);
    LOG(" capabilities: %08X\n", cap.capabilities);
    // Set Stream Format
  
    struct v4l2_format fmt;
    memset(&fmt, 0, sizeof(fmt));
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = VIDEO_WIDTH;
    fmt.fmt.pix.height = VIDEO_HEIGHT;
    fmt.fmt.pix.pixelformat = VIDEO_FORMAT;
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret < 0) {
        LOG("VIDIOC_S_FMT failed (%d)\n", ret);
        return ret;
    }
    // Get Stream Format
 ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
    if (ret < 0) {
        LOG("VIDIOC_G_FMT failed (%d)\n", ret);
        return ret;
    }
    // Print Stream Format
    LOG("Stream Format Informations:\n");
    LOG(" type: %d\n", fmt.type);
    LOG(" width: %d\n", fmt.fmt.pix.width);
    LOG(" height: %d\n", fmt.fmt.pix.height);
    char fmtstr[8];
    memset(fmtstr, 0, 8);
    memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
    LOG(" pixelformat: %s\n", fmtstr);
    LOG(" field: %d\n", fmt.fmt.pix.field);
    LOG(" bytesperline: %d\n", fmt.fmt.pix.bytesperline);
    LOG(" sizeimage: %d\n", fmt.fmt.pix.sizeimage);
    LOG(" colorspace: %d\n", fmt.fmt.pix.colorspace);
    LOG(" priv: %d/n", fmt.fmt.pix.priv);
    LOG(" raw_date: %s\n", fmt.fmt.raw_data);
    // Request buffers
    struct v4l2_requestbuffers reqbuf;
    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    reqbuf.memory = V4L2_MEMORY_MMAP;
    reqbuf.count = BUFFER_COUNT;
    ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf);
    if(ret < 0) {
        LOG("VIDIOC_REQBUFS failed (%d)\n", ret);
        return ret;
    }
// Queen buffers

    for(i=0; i<BUFFER_COUNT; i++) {
        // Query buffer
        buf.index = i;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(fd , VIDIOC_QUERYBUF, &buf);
        if(ret < 0) {
            LOG("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
            return ret;
        }
        // mmap buffer
        framebuf[i].length = buf.length;
        framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
        if (framebuf[i].start == MAP_FAILED) {
            LOG("mmap (%d) failed: %s\n", i, strerror(errno));
            return -1;
        }
        // Queen buffer
        ret = ioctl(fd , VIDIOC_QBUF, &buf);
        if (ret < 0) {
            LOG("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
            return -1;
        }
        printf("my %d \n",i);
        LOG("Frame buffer %d: address=0x%x, length=%d/n", i, (unsigned int)framebuf[i].start, framebuf[i].length);
    }
    // Stream On
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd, VIDIOC_STREAMON, &type);
    if (ret < 0) {
        LOG("VIDIOC_STREAMON failed (%d)\n", ret);
        return ret;
    }
//int ret;
    // Get frame
    ret = ioctl(fd, VIDIOC_DQBUF, &buf);
    if (ret < 0) {
        LOG("VIDIOC_DQBUF failed (%d)\n", ret);
        return ret;
    }
    // Re-queen buffer
    ret = ioctl(fd, VIDIOC_QBUF, &buf);
    if (ret < 0) {
        LOG("VIDIOC_QBUF failed (%d)\n", ret);
        return ret;
    }
}

#2


大神求助啊,实在是找不出什么问题

#3


找到问题啦,是buf.length的值为0造成的

#1


#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
//#define ANDROID_ENV

#ifdef ANDROID_ENV
#define LOG LOGV
#else
#define LOG printf
#endif
#define CAMERA_DEVICE "/dev/video0"
#define CAPTURE_FILE "frame.jpeg"
#define VIDEO_WIDTH 512
#define VIDEO_HEIGHT 400
#define VIDEO_FORMAT V4L2_PIX_FMT_YUYV
#define BUFFER_COUNT 1
struct fimc_buffer {
        int length;
        void *start;
    } framebuf[BUFFER_COUNT];
struct v4l2_buffer buf;
int main()
{
   struct v4l2_fmtdesc fmtdesc;
    int i, ret,fd;
    // Open Device

    fd = open(CAMERA_DEVICE, O_RDWR, 0);
    if(fd < 0){
        LOG("Open %s failed\n", CAMERA_DEVICE);
        return -1;
    }
    // Query Capability
    struct v4l2_capability cap;
    ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
    if (ret < 0) {
        LOG("VIDIOC_QUERYCAP failed (%d)\n", ret);
        return ret;
    }
    // Print capability infomations
    LOG("Capability Informations:\n");
    LOG(" driver: %s\n", cap.driver);
    LOG(" card: %s\n", cap.card);
    LOG(" bus_info: %s\n", cap.bus_info);
    LOG(" version: %08X\n", cap.version);
    LOG(" capabilities: %08X\n", cap.capabilities);
    // Set Stream Format
  
    struct v4l2_format fmt;
    memset(&fmt, 0, sizeof(fmt));
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = VIDEO_WIDTH;
    fmt.fmt.pix.height = VIDEO_HEIGHT;
    fmt.fmt.pix.pixelformat = VIDEO_FORMAT;
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret < 0) {
        LOG("VIDIOC_S_FMT failed (%d)\n", ret);
        return ret;
    }
    // Get Stream Format
 ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
    if (ret < 0) {
        LOG("VIDIOC_G_FMT failed (%d)\n", ret);
        return ret;
    }
    // Print Stream Format
    LOG("Stream Format Informations:\n");
    LOG(" type: %d\n", fmt.type);
    LOG(" width: %d\n", fmt.fmt.pix.width);
    LOG(" height: %d\n", fmt.fmt.pix.height);
    char fmtstr[8];
    memset(fmtstr, 0, 8);
    memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
    LOG(" pixelformat: %s\n", fmtstr);
    LOG(" field: %d\n", fmt.fmt.pix.field);
    LOG(" bytesperline: %d\n", fmt.fmt.pix.bytesperline);
    LOG(" sizeimage: %d\n", fmt.fmt.pix.sizeimage);
    LOG(" colorspace: %d\n", fmt.fmt.pix.colorspace);
    LOG(" priv: %d/n", fmt.fmt.pix.priv);
    LOG(" raw_date: %s\n", fmt.fmt.raw_data);
    // Request buffers
    struct v4l2_requestbuffers reqbuf;
    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    reqbuf.memory = V4L2_MEMORY_MMAP;
    reqbuf.count = BUFFER_COUNT;
    ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf);
    if(ret < 0) {
        LOG("VIDIOC_REQBUFS failed (%d)\n", ret);
        return ret;
    }
// Queen buffers

    for(i=0; i<BUFFER_COUNT; i++) {
        // Query buffer
        buf.index = i;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(fd , VIDIOC_QUERYBUF, &buf);
        if(ret < 0) {
            LOG("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
            return ret;
        }
        // mmap buffer
        framebuf[i].length = buf.length;
        framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
        if (framebuf[i].start == MAP_FAILED) {
            LOG("mmap (%d) failed: %s\n", i, strerror(errno));
            return -1;
        }
        // Queen buffer
        ret = ioctl(fd , VIDIOC_QBUF, &buf);
        if (ret < 0) {
            LOG("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
            return -1;
        }
        printf("my %d \n",i);
        LOG("Frame buffer %d: address=0x%x, length=%d/n", i, (unsigned int)framebuf[i].start, framebuf[i].length);
    }
    // Stream On
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd, VIDIOC_STREAMON, &type);
    if (ret < 0) {
        LOG("VIDIOC_STREAMON failed (%d)\n", ret);
        return ret;
    }
//int ret;
    // Get frame
    ret = ioctl(fd, VIDIOC_DQBUF, &buf);
    if (ret < 0) {
        LOG("VIDIOC_DQBUF failed (%d)\n", ret);
        return ret;
    }
    // Re-queen buffer
    ret = ioctl(fd, VIDIOC_QBUF, &buf);
    if (ret < 0) {
        LOG("VIDIOC_QBUF failed (%d)\n", ret);
        return ret;
    }
}

#2


大神求助啊,实在是找不出什么问题

#3


找到问题啦,是buf.length的值为0造成的