#ifndef __RTPONEROAD_H__ #define __RTPONEROAD_H__ #include "GlobalVariable.h" #include "BaseRecordThread.h" #include "AudioData.h" #include "RingQueue.hpp" #include #include #include #include #include #include #include "Rtpcommon.h" /** 一路RTP数据发送服务,一路表示的是一个录音通道,也是一个子线程 工作方式: 1、这个其实也是一个录音处理线程,分派录音的线程给这里传递数据 2、这个线程有一个UDP会话列表,会挨个往监听的客户端发送数据,如果客户端列表为空 则不再接收原始音频数据 3、这个线程在打开一个录音通道后就会创建,在后台运行,直到RTP服务设置进来一个UDP会话 4、这个线程类会被 RTPServer 线程和 AssignSrcData 线程调用 5、这个线程添加会话后会占用一个本地的UDP端口,所有会话移除掉后会释放这个端口 */ class RTPOneRoadThread : public QObject, public BaseRecordThread { Q_OBJECT public: RTPOneRoadThread(RecordThreadInfo_t& threadInfo); ~RTPOneRoadThread() override; /* 停止线程 */ void stopThread() override; /* 设置数据 */ bool setData(const AudioSrcData& srcData) override; /* 添加一个UDP会话 */ bool addUdpSession(const RtpSendClientInfo_t& udpSession); /* 删除一个会话 */ bool removeUdpSession(QString clientIP, quint16 clientPort); signals: /* 一个UDP关闭了,通知RTP服务,释放掉了一个本地端口 */ void signal_udpClosed(int soundCardNum, int roadNum, int localPort); protected: /* 任务函数 */ void task() override; /* 初始化数据 */ bool initData() override; /* 清除数据*/ void clearData() override; /* 处理UDP状态 */ bool processUdpState(); /* 发送数据 */ bool sendData(); private slots: /* 定时发送数据 */ void do_timerSendData(); /* UDP错误槽函数 */ void do_udpError(QAbstractSocket::SocketError socketError); private: /* 事件循环 */ QEventLoop m_eventLoop; QTimer m_sendTimer; /* 定时器,用于定时发送数据 */ QUdpSocket* m_udpSocket = nullptr; /* 用于发送数据的UDP套接字 */ QString m_localIP; /* 本地IP */ int m_localPort = -1; /* 本地发送数据的UDP端口 */ eUDPState m_udpState = eUDPState::eUDP_None; /* UDP状态 */ /* UDP会话列表 */ std::atomic_bool m_isRecvData = false; /* 是否接收数据的标志 */ std::mutex m_lockUdpSockets; /* 用于保护UDP套接字列表的读写锁 */ QList m_listClients; /* 用于发送数据的客户端信息列表 */ RingQueue m_ringQueue; /* 用于存储音频数据的环形队列 */ }; #endif // __RTPONEROAD_H__