2016-03-11 120 views
1

您能否介紹如何通過C++在V4L2中獲得並設置JPEG壓縮質量(使用JPEG像素格式)?通過C/C++設置/使用JPEG像素格式在v4l2中獲取相機jpeg壓縮質量

我可以檢測相機支持的各種像素格式以及相應的分辨率和幀速率。我也可以選擇它們並相應地捕捉JPEG圖像。但是,我無法設置和獲得JPEG質量。

我正在使用Linux Mint和Logitech c910相機。

相機似乎自

v4l2-ctl --all 

產生

JPEG Compression Controls 

     compression_quality (int) : min=50 max=87 step=1 default=75 value=75 
[...] 

但是,代碼

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/ioctl.h> 
#include <linux/videodev2.h> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    int fd = open("/dev/video0", O_RDWR); 
    if (fd == -1) 
    { 
     perror("open: "); return 1; 
    } 

    { 
     // first option 
     v4l2_jpegcompression ctrl={0}; 
     if(ioctl(fd, VIDIOC_G_JPEGCOMP, &ctrl)<0) 
     { 
      perror("VIDIOC_G_JPEGCOMP:"); 
     } 
     else 
     { 
      cout<<"QUALITY:"<<ctrl.quality<<endl; 
     } 
    } 

    { 
     // second option 
     v4l2_ext_control extCtrl={0}; 
     extCtrl.id = V4L2_CID_JPEG_COMPRESSION_QUALITY; 
     extCtrl.size = 0; 
     extCtrl.value = 100; 

     v4l2_ext_controls extCtrls={0}; 
     extCtrls.controls = &extCtrl; 
     extCtrls.count = 1; 
     extCtrls.ctrl_class = V4L2_CTRL_CLASS_JPEG; 

     if(ioctl(fd, VIDIOC_G_EXT_CTRLS, &extCtrls)<0) 
     { 
      perror("VIDIOC_G_EXT_CTRLS:"); 
     } 
    } 

    { 
     // third option 
     v4l2_ext_control extCtrl={0}; 
     extCtrl.id = V4L2_CID_JPEG_COMPRESSION_QUALITY; 
     extCtrl.size = 0; 
     extCtrl.value = 100; 

     v4l2_ext_controls extCtrls={0}; 
     extCtrls.controls = &extCtrl; 
     extCtrls.count = 1; 
     extCtrls.ctrl_class = V4L2_CID_JPEG_CLASS; 

     if(ioctl(fd, VIDIOC_G_EXT_CTRLS, &extCtrls)<0) 
     { 
      perror("VIDIOC_G_EXT_CTRLS V4L2_CID_JPEG_CLASS:"); 
     } 
    } 

    close(fd); 
    return 0; 
} 

其可經由

g++ query.cpp -o query.out 
被編譯,以暴露該參數

生產:

VIDIOC_G_JPEGCOMP:: Inappropriate ioctl for device 
VIDIOC_G_EXT_CTRLS:: Invalid argument 
VIDIOC_G_EXT_CTRLS V4L2_CID_JPEG_CLASS:: Invalid argument 

回答

0
void check_controls(int fd) { 

    struct v4l2_queryctrl qctrl; 

    memset(&qctrl, 0, sizeof(qctrl)); 

    qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; 
    while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) { 

     printf("ID = %08x\n", qctrl.id); 
     /* ... */ 
     qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; 
    } 
} 
+0

請問您可以在這裏添加一些關於您在這裏做什麼的描述,包括代碼中的註釋,以便給您的建議提供一些意義? – LordWilmore

0

您可以使用lsusb -v查看相機支持哪些參數。 ioctl VIDIOC_G_JPEGCOMP或VIDIOC_G_JPEGCOMP未出現在v4l2驅動程序中。我認爲他們沒有使用,因爲相機不支持它們。大多數攝像機會自動控制MJPEG質量以提供目標比特率。他們似乎不支持在MJPEG中更改QP或比特率。我認爲這個想法是,相機提供了高比特率,然後使用ffmpeg重新編碼爲H264。