2016-03-30 6 views
1

V4l2 için C99'da basit bir program yazdım ve birçok Linux kitabına göre çalışması gerekiyor ama api okumak için Invalid argument hatası alıyorum. Neyi unuttum?v4l2'deki web kamerası cihazı için okuma işlevi geçersiz bağımsız değişkenle başarısız oluyor

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; 
} 

Ben webcame çalıştığından emin değilim ve V4L2 kütüphanesi aşağıdaki benim Linux yüklü tam çıktısı:

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

ve "gdb" yi (fd, buf, imageSize) okumaya başlayana kadar izlemek için kullandınız ve bu varsların geçerli değerlere sahip olduğunu kontrol ettiniz? ; -? Başlamak için en muhtemel yer gibi görünüyor. Daha sonra geçersiz değerlerde oradan geri dönün. İyi şanslar! – shellter

+0

Bunu zaten takip ettim ve değerleri ile ilgili bir problem olmadı, hatta seçim değeri beklenen değer olanı döndürür. – AMCoded

+0

Gelecekte, en iyi ne denediğiniz ve ne bulduğunuz konusunda Q'nizde bazı detayları eklemek. İyi şanslar! – shellter

cevap

1

video verilerini yakalamak için aşağıdaki kod parçasını kullanmalıdır

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

Bu kod bloğunu biliyorum ve bunu zaten kullandım, çift veya çoklu tamponlama kamera çekimini kullanmak istediğiniz zamandır. ama bahsettiğim yukarıdaki kod da çalışmalı ve neden olmadığını bilmiyorum. – AMCoded

İlgili konular