zoneminder/src/zm_rtp_ctrl.h

146 lines
4.3 KiB
C++

//
// ZoneMinder RTCP Class Interface, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
#ifndef ZM_RTP_CTRL_H
#define ZM_RTP_CTRL_H
#include <atomic>
#include <sys/types.h>
#include <thread>
// Defined in ffmpeg rtp.h
//#define RTP_MAX_SDES 255 // maximum text length for SDES
// Big-endian mask for version, padding bit and packet type pair
#define RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe)
#define RTCP_VALID_VALUE ((RTP_VERSION << 14) | RTCP_SR)
class RtspThread;
class RtpSource;
class RtpCtrlThread {
friend class RtspThread;
private:
typedef enum {
RTCP_SR = 200,
RTCP_RR = 201,
RTCP_SDES = 202,
RTCP_BYE = 203,
RTCP_APP = 204
} RtcpType;
typedef enum {
RTCP_SDES_END = 0,
RTCP_SDES_CNAME = 1,
RTCP_SDES_NAME = 2,
RTCP_SDES_EMAIL = 3,
RTCP_SDES_PHONE = 4,
RTCP_SDES_LOC = 5,
RTCP_SDES_TOOL = 6,
RTCP_SDES_NOTE = 7,
RTCP_SDES_PRIV = 8
} RtcpSdesType;
struct RtcpCommonHeader {
uint8_t count:5; // varies by packet type
uint8_t p:1; // padding flag
uint8_t version:2; // protocol version
uint8_t pt; // RTCP packet type
uint16_t lenN; // pkt len in words, w/o this word, network order
};
// Reception report block
struct RtcpRr {
uint32_t ssrcN; // data source being reported
int32_t lost:24; // cumul. no. pkts lost (signed!)
uint32_t fraction:8; // fraction lost since last SR/RR
uint32_t lastSeqN; // extended last seq. no. received, network order
uint32_t jitterN; // interarrival jitter, network order
uint32_t lsrN; // last SR packet from this source, network order
uint32_t dlsrN; // delay since last SR packet, network order
};
// SDES item
struct RtcpSdesItem {
uint8_t type; // type of item (rtcp_sdes_type_t)
uint8_t len; // length of item (in octets)
char data[]; // text, not null-terminated
};
// RTCP packet
struct RtcpPacket {
RtcpCommonHeader header; // common header
union {
// Sender Report (SR)
struct Sr {
uint32_t ssrcN; // sender generating this report, network order
uint32_t ntpSecN; // NTP timestamp, network order
uint32_t ntpFracN;
uint32_t rtpTsN; // RTP timestamp, network order
uint32_t pSentN; // packets sent, network order
uint32_t oSentN; // octets sent, network order
RtcpRr rr[]; // variable-length list
} sr;
// Reception Report (RR)
struct Rr {
uint32_t ssrcN; // receiver generating this report
RtcpRr rr[]; // variable-length list
} rr;
// source description (SDES)
struct Sdes {
uint32_t srcN; // first SSRC/CSRC
RtcpSdesItem item[]; // list of SDES items
} sdes;
// BYE
struct {
uint32_t srcN[]; // list of sources
// can't express trailing text for reason (what does this mean? it's not even english!)
} bye;
} body;
};
private:
RtspThread &mRtspThread;
RtpSource &mRtpSource;
int mPort;
std::atomic<bool> mTerminate;
std::thread mThread;
private:
int recvPacket( const unsigned char *packet, ssize_t packetLen );
int generateRr( const unsigned char *packet, ssize_t packetLen );
int generateSdes( const unsigned char *packet, ssize_t packetLen );
int generateBye( const unsigned char *packet, ssize_t packetLen );
int recvPackets( unsigned char *buffer, ssize_t nBytes );
void Run();
public:
RtpCtrlThread( RtspThread &rtspThread, RtpSource &rtpSource );
~RtpCtrlThread();
void Stop() { mTerminate = true; }
};
#endif // ZM_RTP_CTRL_H