2016-03-30 15 views
1

で失敗し、私はV4L2のためにC99で簡単なプログラムを作成しており、多くのLinuxの本によると、それは動作するはずですが、私は、読み取りAPIのInvalid argumentエラーが発生します。 私は何を忘れていますか?読み取り機能が無効な引数

int main(int argc, char** argv) 
{ 
    int fd = open("/dev/video0", O_RDWR); 
    if (fd == -1) { 
     perror("Error opening"); 
     exit(EXIT_FAILURE); 
    } 


    struct v4l2_format format; //Query Format structure 
    memset(&format, 0, sizeof(format)); 
    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    int status = ioctl(fd, VIDIOC_G_FMT, &format); 
    if (status == -1) { 
     perror("Error querying format"); 
     exit(EXIT_FAILURE); 
    } 

    size_t width = format.fmt.pix.width; //Image width 
    size_t height = format.fmt.pix.height; //Image height 
    size_t imageSize = format.fmt.pix.sizeimage; // Total image size in bytes 
    size_t pixelFmt = format.fmt.pix.pixelformat; // Pixel format 
    printf("width:%u, height:%u, size:%u", width, height, imageSize); 
    switch(pixelFmt) { 
    case V4L2_PIX_FMT_YUYV: 
     printf(" & format: YuYv\n"); 
     break; 
    case V4L2_PIX_FMT_RGB24: 
     printf(" & format: RGB24\n"); 
     break; 
    default: 
     printf(" & format: %u\n", pixelFmt); 
    } 

    char* buf = malloc(imageSize); // Image buffer 
    if(buf == NULL) { 
     perror("Error allocating buffer"); 
     exit(EXIT_FAILURE); 
    } 

    fd_set fds; //Select descriptors 
    FD_ZERO(&fds); 
    FD_SET(fd, &fds); 

    struct timeval tv; //Timeout specification structure 
    tv.tv_sec = 20; 
    tv.tv_usec = 0; 

    while(true) { 

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

     if (status == -1) { 
      perror("Error selecting"); 
      exit(EXIT_FAILURE); 
     } else if(status == 0) { 
      perror("Select timeout"); 
      exit(EXIT_FAILURE); 
     } 

     status = read(fd, buf, imageSize); 
     if (status == -1) { 
      perror("Error reading"); 
      exit(EXIT_FAILURE); 
     } 

    } 

    free(buf); 
    close(fd); 

    return EXIT_SUCCESS; 
} 

私はwebcameが働いているとV4L2ライブラリは、以下の私のLinuxにインストールされていることを確信していますが、完全な出力です:

width:640, height:480, size:614400 & format: YuYv 
Error reading: Invalid argument 
+0

、あなたは '読む(FD、BUF、IMAGESIZE)'を持って、あなたはこれらのVARSは、有効な値を持っていることを確認し、DBLまではスルートレースする 'gdb'を使用? ; - ?始める可能性が最も高いと思われます。その後、そこから無効な値をバックトラックします。がんばろう! – shellter

+0

私はすでにそれをトレースしていて、その値に問題はなく、selectでも期待値を返します。 – AMCoded

+0

今後、あなたが試したことや見つけたことについて、あなたのQにいくつかの詳細を含めることをお勧めします。がんばろう! – shellter

答えて

1

あなたは

ビデオデータをキャプチャするために次のコードを使用する必要があります
struct v4l2_requestbuffers reqbuf; 
reqbuf.count = BUFFER_COUNT; 
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
reqbuf.memory = V4L2_MEMORY_MMAP; 

ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf); 
if(ret < 0) { 
    perror("VIDIOC_REQBUFS: "); 
    return ret; 
} 

struct v4l2_buffer buf; 
for (i = 0; i < reqbuf.count; i++) { 
    buf.index = i; 
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    buf.memory = V4L2_MEMORY_MMAP; 
    ret = ioctl(fd , VIDIOC_QUERYBUF, &buf); 
    if(ret < 0) { 
     perror("VIDIOC_QUERYBUF: "); 
     return ret; 
    } 
    framebuf[i].length = buf.length; 
    framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset); 
} 

enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
ret = ioctl(fd, VIDIOC_STREAMON, &type); 
if (ret < 0) { 
    perror("VIDIOC_STREAMON: "); 
    return ret; 
} 

ret = ioctl(fd, VIDIOC_DQBUF, &buf); 
if (ret < 0) { 
    perror("VIDIOC_DQBUF "); 
    return ret; 
} 

// access the captured data via framebuf[buf.index].start 
+0

私は、このコードブロックについて知っていると私はすでにあなたが二重またはマルチバッファリングのカメラのキャプチャを使用する場合それは、それを使用しています。私が言及した上記のコードもうまくいくはずですが、なぜそうではないのかわかりません。 – AMCoded

関連する問題