154 lines
5.2 KiB
C++
154 lines
5.2 KiB
C++
#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
|