2 changed files with 70 additions and 0 deletions
@ -0,0 +1,63 @@
|
||||
#pragma once |
||||
#include <QByteArray> |
||||
#include "debug_config.h" |
||||
#ifdef Q_OS_LINUX |
||||
#include <fcntl.h> |
||||
#include <unistd.h> |
||||
#include <sys/ioctl.h> |
||||
#include <linux/videodev2.h> |
||||
#include <cerrno> |
||||
#include <cstring> |
||||
#endif |
||||
|
||||
// Qt задаёт 30 fps, но UVC auto-exposure может разрешить камере снижать их до 16–17.
|
||||
// Меняем только этот флаг на время захвата; сама автоэкспозиция остаётся включённой.
|
||||
class CallCameraRate { |
||||
#ifdef Q_OS_LINUX |
||||
int fd = -1; |
||||
#endif |
||||
public: |
||||
~CallCameraRate() { restore(); } |
||||
void restore() { |
||||
#ifdef Q_OS_LINUX |
||||
if (fd < 0) return; |
||||
v4l2_control control{}; control.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY; control.value = 1; |
||||
if (ioctl(fd, VIDIOC_S_CTRL, &control) < 0) |
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call camera dynamic fps restore failed: %s", std::strerror(errno)); |
||||
else DEBUG_INFO(DEBUG_CATEGORY_CALL, "call camera dynamic fps restored=1"); |
||||
::close(fd); fd = -1; |
||||
#endif |
||||
} |
||||
void activate(const QByteArray& device) { |
||||
restore(); |
||||
#ifdef Q_OS_LINUX |
||||
if (!device.startsWith("/dev/video")) { |
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "call camera fps policy unavailable device=%s", device.constData()); return; |
||||
} |
||||
int camera = ::open(device.constData(), O_RDWR | O_NONBLOCK | O_CLOEXEC); |
||||
if (camera < 0) { |
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call camera fps control open failed device=%s: %s", device.constData(), std::strerror(errno)); |
||||
return; |
||||
} |
||||
v4l2_control control{}; control.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY; |
||||
if (ioctl(camera, VIDIOC_G_CTRL, &control) < 0) { |
||||
if (errno == EINVAL) DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "call camera dynamic fps control unsupported device=%s", device.constData()); |
||||
else DEBUG_WARN(DEBUG_CATEGORY_CALL, "call camera fps control read failed: %s", std::strerror(errno)); |
||||
} else if (!control.value) { |
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "call camera dynamic fps already disabled device=%s", device.constData()); |
||||
} else { |
||||
control.value = 0; |
||||
if (ioctl(camera, VIDIOC_S_CTRL, &control) < 0) |
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call camera dynamic fps disable failed: %s", std::strerror(errno)); |
||||
else { |
||||
fd = camera; |
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "call camera dynamic fps disabled device=%s; auto exposure retained", device.constData()); |
||||
return; |
||||
} |
||||
} |
||||
::close(camera); |
||||
#else |
||||
Q_UNUSED(device); |
||||
#endif |
||||
} |
||||
}; |
||||
Loading…
Reference in new issue