#ifndef _RTP_RECEIVER_H_ #define _RTP_RECEIVER_H_ #include "buffer.h" #include "demuxer.h" #include "rtppacket.h" #include #include #include #include #include typedef unsigned char BYTE; using namespace jrtplib; using namespace std; /** 视频数据回调 * * @param videoType [in] 视频类型 音频-0xC0、h264-0x1B、MPEG4-0x01、SVAC-0x80 * @param data [in] 视频数据 * @param len [in] 视频数据长度 * @param isKey [in] 是否为关键帧 * @param pts [in] 时间戳 */ typedef void(*CallBack_Stream)(void* userdata, int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts); /** 录像回放完成回调消息通知 */ typedef void(*CallBack_VodFileEnd)(void* userdata); /** * 请求流 */ typedef bool(*CallBack_Request_Stream)(const char* deviceId); // 标识帧, 注意buffer需要自己开辟和释放 struct Frame { Frame() { buf_ = NULL; len_ = 0; } ~Frame() { if (buf_ != nullptr) { free(buf_); buf_ = nullptr; } } Frame(BYTE* buf, int len, bool key) : buf_(buf), len_(len), key_(key) {} BYTE* buf_; int len_; bool key_{}; }; class FrameToDecode { public: FrameToDecode() : m_SliceBuf(0) , m_localPts(0) , m_LastPTS(-1) , m_LastIsKeyFrame(0) {} FrameToDecode(unsigned char m_streamId) : m_SliceBuf(0) , m_localPts(0) , m_LastPTS(-1) , m_LastIsKeyFrame(0) , m_streamId (m_streamId) {} void operator=(FrameToDecode &temp) { m_SliceBuf = temp.m_SliceBuf; m_streamId = temp.m_streamId; m_localPts = temp.m_localPts; m_LastPTS = temp.m_LastPTS; m_LastIsKeyFrame = temp.m_LastIsKeyFrame; } CBuffer m_SliceBuf; unsigned char m_streamId{}; uint64_t m_localPts; uint64_t m_LastPTS; bool m_LastIsKeyFrame; }; class RTPReceiver{ public: RTPReceiver(); virtual ~RTPReceiver(); virtual bool Open(uint16_t localPort) = 0; virtual bool IsOpened() = 0; virtual void Close() = 0; void SetVodEndCallback(CallBack_VodFileEnd cb, void* param); void SetOutputCallback(CallBack_Stream cb, void* param); void SetRequestStreamCallback(CallBack_Request_Stream cb); void SetDeviceID(string deviceID); int GetPsFrameListSize(); public: void OnPsDemux(unsigned char streamId, BYTE *data, int len, bool key, uint64_t pts, uint64_t localPts); int OnPsProcess(); void ClearPsVideoFrameList(); int ParsePacket(RTPPacket* packet); public: int InitPS(); void ClosePsThread(); void *GetUsrParam(){ return m_usrParam; } public: CBuffer m_SliceBuf; uint64_t m_LastPTS; bool m_LastIsKeyFrame; unsigned char m_LastStreamType; int64_t m_notToDecodCount{0};//线程计数,用来代表多长时间没有调用解码回调,针对大华相机 void* m_usrParam; CallBack_Stream m_h264DataFunc; // 视频流回调 std::queue m_psVideoFrames; mutex m_psFrameMutex; string m_deviceID; CMpeg2Demux m_psParser; std::atomic_bool m_bPsExit; // 标识PS解包线程关闭 uint32_t lastPts{0}; uint64_t last_recv_ts{0}; int offset{0}; int mark{0}; BYTE* recvTmpBuf{nullptr}; std::thread* m_psThreadPtr; // PS解包线程 CallBack_VodFileEnd m_hVodEndFunc; // 录像流结束回调 CallBack_Request_Stream m_callback_request_stream; //请求流回调 }; #endif // _RTP_RECEIVER_H_