Files
uartscope/include/videowidget.h
2026-08-18 07:34:20 +02:00

80 lines
2.3 KiB
C++

#pragma once
#include <QWidget>
#include <QImage>
#include <QSize>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QThread>
#include <QProcess>
#include "v4l2worker.h"
// VideoWidget shows the live V4L2 preview and can additionally record it
// to an MP4 file. Recording works by piping raw BGRA frames into an
// external `ffmpeg` process (via QProcess/stdin), which encodes them to
// H.264/MP4 - this avoids reimplementing video encoding and just needs
// ffmpeg to be installed and on PATH.
class VideoWidget : public QWidget
{
Q_OBJECT
public:
explicit VideoWidget(QWidget *parent = nullptr);
~VideoWidget();
public:
void shutdown(); // safe to call multiple times, called from MainWindow::closeEvent
public slots:
void onNewFrame(const QImage &frame);
void clearFrame(); // blanks the preview (used on ANSI clear-screen)
private slots:
void onStartStop();
void onFreeze(bool frozen);
void onScreenshot();
void onRecordToggled(bool checked);
void refreshDeviceList();
protected:
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
private:
void setupUi();
void startCapture();
void stopCapture();
void updateScaled();
void startRecording();
void stopRecording();
void writeRecordingFrame(const QImage &frame);
QThread *m_thread = nullptr;
V4l2Worker *m_worker = nullptr;
QImage m_frame;
QImage m_scaled;
bool m_frozen = false;
bool m_running = false;
bool m_shutdownDone = false;
QComboBox *m_deviceCombo = nullptr;
QPushButton *m_startBtn = nullptr;
QPushButton *m_freezeBtn = nullptr;
QPushButton *m_screenshotBtn = nullptr;
QPushButton *m_recordBtn = nullptr;
QLabel *m_infoLabel = nullptr;
// Recording state. m_recordProcess is the running ffmpeg instance (or
// nullptr when not recording); m_recordSize is the frame size the
// recording was started with, so a mid-stream resolution change (which
// ffmpeg's raw pipe can't handle) can be detected and the recording
// stopped cleanly instead of corrupting the output file.
QProcess *m_recordProcess = nullptr;
bool m_recording = false;
QSize m_recordSize;
};