настройка / получение качества сжатия jpeg камеры в v4l2 в формате пикселей JPEG через C / Stack Overflow

Не могли бы вы показать, как получить и установить качество сжатия JPEG (с пиксельным форматом JPEG) в V4L2 через C ++?

Я могу определить различные форматы пикселей, поддерживаемые камерой, и соответствующие разрешения и частоты кадров. Я также могу выбрать их и соответственно захватывать изображения 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

2

Решение

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

Другие решения

Это выведет в шестнадцатеричном виде список сопоставленных элементов управления, как в 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

0

Вы можете проверить, какие параметры поддерживает камера, используя lsusb -v.
Ioctl VIDIOC_G_JPEGCOMP или VIDIOC_G_JPEGCOMP не отображается в драйвере v4l2. Я думаю, что они не используются, так как камеры их не поддерживают. Большинство камер транслируют MJPEG, автоматически контролируя качество, чтобы обеспечить целевой битрейт. Кажется, они не поддерживают изменение QP или битрейта в MJPEG. Я думаю, что идея заключается в том, что камера выдает высокий битрейт, а затем использует ffmpeg для перекодирования, например, в H264.

0
По вопросам рекламы [email protected]