153 lines
5.1 KiB
C
Raw Normal View History

2026-06-26 17:55:15 +08:00
#ifndef DRONESCREWCTRL_PRESENTER_H
#define DRONESCREWCTRL_PRESENTER_H
#include <QObject>
#include <QImage>
#include <QSize>
2026-06-26 17:55:15 +08:00
#include <QString>
#include <QTimer>
#include <QMutex>
#include <atomic>
#include <map>
2026-06-26 17:55:15 +08:00
#include "IVrConfig.h"
#include "IYDroneScrewCtrlStatus.h"
#include "IVrFFMediaPuller.h"
#include "IWDRemoteReceiver.h"
/**
* @brief Presenter
*
* 访 WDRemoteReceiver
* - REQ-REP
* - PUB-SUB
* - PUB-SUB
*
* Presenter
* - IVrFFMediaPuller RTSP
* - IWDRemoteReceiver
* - + IYDroneScrewCtrlStatus
*/
class DroneScrewCtrlPresenter : public QObject
{
Q_OBJECT
public:
explicit DroneScrewCtrlPresenter(QObject* parent = nullptr);
~DroneScrewCtrlPresenter() override;
void SetStatusReceiver(IYDroneScrewCtrlStatus* receiver) { m_pReceiver = receiver; }
void ApplyConfig(const DroneScrewCtrlConfigResult& cfg);
int InitApp();
void DeinitApp();
bool TriggerSingleDetection();
bool StartLiveStream();
bool StopLiveStream();
bool StartDetection();
bool StopDetection();
bool StopAll(); // 同时停止实时推流与检测(主开关停止用)
bool SetServerExposure(double exposureTime);
bool SetServerGain(double gain);
bool PushAlgoParams(const DroneScrewAlgoUiParams& params);
QImage GetLastDisplayImage() const;
signals:
void displayFrameReady(const QImage& img,
const QSize& sourceSize,
qint64 frameId,
bool rtspFrame,
const CtrlDetectionFrame& result,
bool hasResult);
2026-06-26 17:55:15 +08:00
void detectionResultReady(const CtrlDetectionFrame& result);
void serverConnectionChanged(bool connected);
void statusMessage(const QString& msg);
void serverInfoReceived(const WDRemoteServerInfo& info); // 服务器参数更新
private slots:
void onReconnectTimer();
void onOverlayFrameReady(const QImage& img,
const QSize& sourceSize,
qint64 frameId,
bool rtspFrame,
const CtrlDetectionFrame& result,
bool hasResult);
2026-06-26 17:55:15 +08:00
void onResultReceived(const CtrlDetectionFrame& result);
private:
// RTSP 拉流回调
void onRtspFrame(const VrFFPulledFrame& frame);
bool initPuller(const QString& streamUrl, bool quiet = false);
bool startPullerOnce(const QString& streamUrl, bool quiet = false);
bool waitForRtspFirstFrame(int timeoutMs);
bool startPullerWithRetry(const QString& streamUrl);
2026-06-26 17:55:15 +08:00
void releasePuller();
QString resolveStreamUrl(const QString& streamUrl) const;
2026-06-26 17:55:15 +08:00
void updateStreamInfo(const WDRemoteServerInfo& info);
// WDRemoteReceiver 回调
void onRemoteDetection(const WDRemoteDetectionFrame& frame);
void onRemoteRawImage (const WDRemoteBinocularRawImage& img); // 检测模式下的图像ZMQ 原始图通道)
void onRemoteEvent (WDRemoteEventType ev, const std::string& msg);
void overlayDetectionBoxes(QImage& img, const CtrlDetectionFrame& frame, const QSize& sourceSize);
void clearCachedDisplayState();
void prunePendingMatchesLocked();
2026-06-26 17:55:15 +08:00
static CtrlDetectionFrame toCtrlFrame(const WDRemoteDetectionFrame& f);
private:
struct DisplayFrame
{
QImage image;
QSize sourceSize;
};
struct PendingRawFrame
{
DisplayFrame frame;
qint64 receivedAtMs{0};
};
struct PendingDetectionResult
{
CtrlDetectionFrame result;
qint64 receivedAtMs{0};
};
2026-06-26 17:55:15 +08:00
DroneScrewCtrlConfigResult m_cfg;
IVrFFMediaPuller* m_pPuller{nullptr};
IWDRemoteReceiver* m_pRemote{nullptr};
QString m_streamUrl;
IYDroneScrewCtrlStatus* m_pReceiver{nullptr};
std::atomic<bool> m_bConnected{false};
std::atomic<bool> m_bRunning{false};
std::atomic<bool> m_liveStreamMode{false};
std::atomic<bool> m_rtspReceiving{false};
std::atomic<bool> m_rtspFirstFrameReported{false};
2026-06-26 17:55:15 +08:00
QTimer* m_pReconnectTimer{nullptr};
// 最近检测结果(用于叠加显示)
mutable QMutex m_lastResultMutex;
CtrlDetectionFrame m_lastResult;
bool m_bHasResult{false};
// 最近显示帧
mutable QMutex m_lastImgMutex;
QImage m_lastSourceImage;
qint64 m_lastSourceFrameId{-1};
bool m_lastSourceIsRtsp{false};
2026-06-26 17:55:15 +08:00
QImage m_lastDisplay;
std::map<qint64, PendingRawFrame> m_pendingRawFrames;
std::map<qint64, PendingDetectionResult> m_pendingDetectionResults;
2026-06-26 17:55:15 +08:00
};
#endif // DRONESCREWCTRL_PRESENTER_H