2026-07-01 18:16:18 +08:00

154 lines
5.2 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.

#ifndef DRONESCREWCTRL_PRESENTER_H
#define DRONESCREWCTRL_PRESENTER_H
#include <QObject>
#include <QImage>
#include <QSize>
#include <QString>
#include <QTimer>
#include <QMutex>
#include <atomic>
#include <map>
#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);
void UpdateDisplayOptions(const DroneScrewDisplayOption& options);
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);
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);
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);
void releasePuller();
QString resolveStreamUrl(const QString& streamUrl) const;
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();
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};
};
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};
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};
QImage m_lastDisplay;
std::map<qint64, PendingRawFrame> m_pendingRawFrames;
std::map<qint64, PendingDetectionResult> m_pendingDetectionResults;
};
#endif // DRONESCREWCTRL_PRESENTER_H