146 lines
4.3 KiB
C++
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
|