/* FFmpeg live encoder: один worker владеет контекстом, конвертером и decoder configuration. * open/encode/close последовательны; каждый KEY содержит uAV2 envelope. Пакеты имеют capture PTS. * Backend ограничивает перебор: HardwareOnly никогда не открывает software encoder. * Профили звонка проверяются по bitstream; допустим задержанный выход GPU без B-кадров. * encode выдаёт все готовые кадры сразу. До восьми входных PTS сохраняются до выхода; * QSV использует 90kHz внутри codec, наружу возвращается точный исходный capture PTS. */ #pragma once #include #include #include #include #include #include enum class LiveVideoProfile { Automatic, H264ConstrainedBaseline, H265Main }; struct LiveVideoConfig { int width = 1280, height = 720, fps = 30, bitrate = 2500000, codec = 1, rotation = 0; LiveVideoProfile profile = LiveVideoProfile::Automatic; int level = 0, references = 0, vbvBits = 0; // level: AVC level_idc / HEVC general_level_idc; 0 — auto. int maxQp = -1; // Потолок QP для H.264/H.265: 0..51, -1 — настройки encoder. Профили звонка не используют. QString backend; // Пусто — проба доступных; непусто — только уже проверенный encoder. bool operator==(const LiveVideoConfig&) const = default; }; struct LiveEncodedFrame { QByteArray data; uint64_t pts = 0; bool key = false; }; class LiveVideoEncoder { public: enum class Backend { Automatic, HardwareOnly, SoftwareOnly }; LiveVideoEncoder(); ~LiveVideoEncoder(); bool open(const LiveVideoConfig& config, Backend backend = Backend::Automatic); bool setBitrate(int bitrate); // true — изменение на следующем кадре; false — нужна смена видеоконтекста bool canSetMaxQp() const; // Поддерживается изменение потолка без пересоздания encoder. bool setMaxQp(int qp); // 0..51, применяется при следующей подаче кадра; false — ошибка/нет поддержки. void close(); bool encode(const QImage& image, uint64_t pts, bool key, QList& output); QString error() const; QString name() const; static QList available(Backend backend = Backend::Automatic); // Установленные кодеки, без открытия и кодирования. static QString codecName(int codec); private: struct Impl; std::unique_ptr m; };