Files
utun2/tools/chatgui/src/call_camera_capture.h
T

51 lines
4.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* GUI-обёртка камеры: автоматически запускает отдельный процесс для опроса устройств, захвата и конвертации.
* Создавать/вызывать/уничтожать в GUI-потоке при работающем Qt event loop; аппаратные вызовы не выполняются в GUI.
* configure меняет поколение, старые кадры отбрасываются. Внешний main должен обработать --call-camera-worker
* через call_camera_worker_main до обычной инициализации приложения. */
#pragma once
#include <QObject>
#include <QImage>
#include <QList>
#include "stream_video_modes.h"
/* Снимок устройства от camera worker; содержит только аппаратные размеры, допустимые для видеозвонка. */
struct CallCameraDevice {
QString name; // Отображаемое имя устройства.
QByteArray id; // Непрозрачный идентификатор Qt backend.
QList<StreamVideoMode> modes; // Чётные размеры до 1920x1080 в обеих ориентациях; FPS передачи 1..60, capture может быть быстрее.
};
using CallCameraDevices = QList<CallCameraDevice>;
constexpr qint64 CallCameraMaxFrameAgeUs = 250000; // Предел возраста кадра в микросекундах при конвертации и приёме GUI.
class CallCameraCapture : public QObject {
Q_OBJECT
public:
/* Создаёт сессию и откладывает запуск worker до event loop; без configure только опрашивает устройства. */
explicit CallCameraCapture(QObject* parent = nullptr);
/* Отвязывает GUI-владельца и запрашивает асинхронный Quit; сессия сама дождётся выхода/убьёт зависший worker. */
~CallCameraCapture() override;
/* enabled включает/выключает захват; device — точный id из devicesChanged, пустой id не выбирает камеру автоматически.
* width/height должны пройти CallCameraProtocol::validSize, fps=1..60 — предел выдачи, не команда драйверу.
* Параметры проверяются и при enabled=false; повтор тех же параметров без ошибки ничего не меняет.
* Смена конфигурации асинхронна; после failed явный configure(true, ...) допускает перезапуск процесса. */
void configure(bool enabled, const QByteArray& device = {}, int width = 640, int height = 480, int fps = 30);
signals:
/* Полный список устройств/режимов после опроса и при изменениях backend, независимо от enabled. */
void devicesChanged(const CallCameraDevices& devices);
/* Текущий свежий RGB32-кадр в собственной CPU-памяти GUI; image можно сохранить копированием QImage.
* pts — монотонное время захвата в микросекундах (шкала call_video_playout_now_us), correction — накопленное
* уменьшение опережения исходных PTS. Ack worker отправлен до сигнала, mapping больше не удерживается. */
void frameReady(const QImage& image, qint64 pts, qint64 correction);
/* Ошибка запуска/IPC/драйвера/параметров или watchdog: процесс останавливается, захват отключается.
* Watchdog: отсутствие прогресса/свежих кадров около 5 с, остановка — около 1.5 с, проверка каждые 250 мс. */
void failed(const QString& error);
private:
struct Session;
Session* m; // Независимый QObject с QPointer на владельца; после shutdown живёт до завершения worker/event loop.
};
/* Entry point дочернего процесса: argc=3, argv[2] — endpoint, создаёт QGuiApplication и запускает worker event loop.
* Вызывается до обычной инициализации приложения, конфига, БД и single-instance lock.
* Возвращает код event loop; без HAVE_STREAM_CAPTURE или с неверным argc — 2. */
int call_camera_worker_main(int argc, char** argv);