【问题标题】:setting/getting camera jpeg compression quality in v4l2 with JPEG pixel format via C/C++通过 C/C++ 在 v4l2 中使用 JPEG 像素格式设置/获取相机 jpeg 压缩质量
【发布时间】:2016-06-26 17:56:18
【问题描述】:

您能否展示如何通过 C++ 在 V4L2 中获取和设置 JPEG 压缩质量(JPEG 像素格式)?

我可以检测到相机支持的各种像素格式以及相应的分辨率和帧率。我还可以选择它们并相应地捕获 JPEG 图像。但是我无法设置和获取 jpeg 质量。

我正在使用 Linux Mint 和罗技 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

【问题讨论】:

    标签: c++ camera capture v4l2 video4linux


    【解决方案1】:
    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;
        }
    }
    

    【讨论】:

    • 您能否添加一些关于您在此处执行的操作的描述,包括代码中的 cmets,以便实际赋予您的建议一些意义?
    【解决方案2】:

    这将以十六进制打印映射控件的列表,如 v4l2-controls.h

    V4L2_CID_JPEG_COMPRESSION_QUALITY 未映射

    你可以把它映射到

    https://www.kernel.org/doc/html/latest/media/v4l-drivers/uvcvideo.html

    29.1.5。 IOCTL 参考 29.1.5.1。 UVCIOC_CTRL_MAP - 将 UVC 控件映射到 V4L2 控件

    【讨论】:

      【解决方案3】:

      您可以使用 lsusb -v 查看相机支持的参数。 ioctl VIDIOC_G_JPEGCOMP 或 VIDIOC_G_JPEGCOMP 不会出现在 v4l2 驱动程序中。我认为它们没有被使用,因为相机不支持它们。大多数相机流式传输 MJPEG 会自动控制质量以提供目标比特率。他们似乎不支持在 MJPEG 中更改 QP 或比特率。我认为这个想法是相机提供高比特率,然后使用 ffmpeg 重新编码为 H264。

      【讨论】:

        猜你喜欢
        • 2010-12-12
        • 2018-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多