2016-03-30 12 views
1

Ich habe ein einfaches Programm in C99 für v4l2 schreiben und nach vielen Linux-Bücher sollte es funktionieren, aber ich bekomme Invalid argument Fehler für lesen API. was habe ich vergessen?lesen Funktion für Webcam Gerät in v4l2 schlägt mit ungültigem 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; 
} 

Ich bin sicher, dass die webcame arbeitet und v4l2 Bibliothek ist in meinem Linux installiert finden Sie die komplette Ausgabe:

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

und Sie '' gdb' 'verwendet, um bis zum 'Lesen (fd, buf, imageSize)' zu verfolgen und dbl-check, dass diese Variablen gültige Werte haben? ; -? Scheint der wahrscheinlichste Ort um anzufangen. Dann zurück von dort auf ungültige Werte. Viel Glück! – shellter

+0

Ich verfolgte das bereits und es gab kein Problem mit ihren Werten, sogar Auswahl gibt einen zurück, der der erwartete Wert ist. – AMCoded

+0

In der Zukunft sollten Sie am besten einige Details in Ihr Q einbeziehen, was Sie versucht haben und was Sie gefunden haben. Viel Glück! – shellter

Antwort

1

Sie sollten das folgende Codefragment verwenden, um Videodaten

zu erfassen
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

Ich weiß über diesen Codeblock und ich habe ihn bereits benutzt, es ist, wenn Sie Doppel-oder Multi-Pufferung Kamera-Capture verwenden möchten. aber der obige Code, den ich erwähnt habe, sollte auch funktionieren und ich weiß nicht, warum das nicht so ist. – AMCoded