RTP rewrite using generic RTP::toDTSC class
This commit is contained in:
parent
9bcd365361
commit
7a03d3e96c
4 changed files with 904 additions and 510 deletions
143
lib/rtp.h
143
lib/rtp.h
|
@ -1,9 +1,12 @@
|
|||
#pragma once
|
||||
#include "dtsc.h"
|
||||
#include "h264.h"
|
||||
#include "h265.h"
|
||||
#include "json.h"
|
||||
#include "mp4.h"
|
||||
#include "mp4_generic.h"
|
||||
#include "socket.h"
|
||||
#include "util.h"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <deque>
|
||||
|
@ -30,9 +33,8 @@ namespace RTP{
|
|||
class Packet{
|
||||
private:
|
||||
bool managed;
|
||||
char *data; ///<The actual RTP packet that is being sent
|
||||
char *data; ///< The actual RTP packet that is being sent
|
||||
uint32_t maxDataLen; ///< Amount of reserved bytes for the packet(s)
|
||||
unsigned int datalen; ///<Size of rtp packet
|
||||
int sentPackets;
|
||||
int sentBytes; // Because ugly is beautiful
|
||||
public:
|
||||
|
@ -47,26 +49,29 @@ namespace RTP{
|
|||
unsigned int getMarker() const;
|
||||
unsigned int getPayloadType() const;
|
||||
unsigned int getSequence() const;
|
||||
unsigned int getTimeStamp() const;
|
||||
uint32_t getTimeStamp() const;
|
||||
void setSequence(unsigned int seq);
|
||||
unsigned int getSSRC() const;
|
||||
void setSSRC(unsigned long ssrc);
|
||||
|
||||
void setTimestamp(unsigned int t);
|
||||
void setTimestamp(uint32_t t);
|
||||
void increaseSequence();
|
||||
void sendH264(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel);
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel, bool lastOfAccesUnit);
|
||||
void sendVP8(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel);
|
||||
void sendH265(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel);
|
||||
void sendMPEG2(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel);
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel);
|
||||
void sendData(void *socket, void callBack(void *, char *, unsigned int, unsigned int),
|
||||
const char *payload, unsigned int payloadlen, unsigned int channel,
|
||||
std::string codec);
|
||||
void sendRTCP_SR(long long &connectedAt, void *socket, unsigned int tid, DTSC::Meta &metadata,
|
||||
void callBack(void *, char *, unsigned int, unsigned int));
|
||||
void sendRTCP_RR(long long &connectedAt, SDP::Track & sTrk, unsigned int tid, DTSC::Meta &metadata,
|
||||
void callBack(void *, char *, unsigned int, unsigned int));
|
||||
void callBack(void *, char *, unsigned int, unsigned int));
|
||||
void sendRTCP_RR(long long &connectedAt, SDP::Track &sTrk, unsigned int tid,
|
||||
DTSC::Meta &metadata,
|
||||
void callBack(void *, char *, unsigned int, unsigned int));
|
||||
|
||||
Packet();
|
||||
Packet(unsigned int pt, unsigned int seq, unsigned int ts, unsigned int ssr,
|
||||
|
@ -76,37 +81,105 @@ namespace RTP{
|
|||
~Packet();
|
||||
Packet(const char *dat, unsigned int len);
|
||||
char *getData();
|
||||
char *ptr() const { return data; }
|
||||
};
|
||||
|
||||
|
||||
/// Sorts RTP packets, outputting them through a callback in correct order.
|
||||
/// Also keeps track of statistics, which it expects to be read/reset externally (for now).
|
||||
/// Optionally can be inherited from with the outPacket function overridden to not use a callback.
|
||||
class Sorter{
|
||||
public:
|
||||
Sorter();
|
||||
void addPacket(const char *dat, unsigned int len);
|
||||
void addPacket(const Packet & pack);
|
||||
void setCallback(uint64_t track, void (*callback)(const uint64_t track, const Packet &p));
|
||||
uint16_t rtpSeq;
|
||||
int32_t lostTotal, lostCurrent;
|
||||
uint32_t packTotal, packCurrent;
|
||||
private:
|
||||
uint64_t packTrack;
|
||||
std::map<uint16_t, Packet> packBuffer;
|
||||
void (*callback)(const uint64_t track, const Packet &p);
|
||||
public:
|
||||
Sorter(uint64_t trackId = 0, void (*callback)(const uint64_t track, const Packet &p) = 0);
|
||||
bool wantSeq(uint16_t seq) const;
|
||||
void addPacket(const char *dat, unsigned int len);
|
||||
void addPacket(const Packet &pack);
|
||||
// By default, calls the callback function, if set.
|
||||
virtual void outPacket(const uint64_t track, const Packet &p){
|
||||
if (callback){callback(track, p);}
|
||||
}
|
||||
void setCallback(uint64_t track, void (*callback)(const uint64_t track, const Packet &p));
|
||||
uint16_t rtpSeq;
|
||||
int32_t lostTotal, lostCurrent;
|
||||
uint32_t packTotal, packCurrent;
|
||||
|
||||
private:
|
||||
uint64_t packTrack;
|
||||
std::map<uint16_t, Packet> packBuffer;
|
||||
std::map<uint16_t, Packet> packetHistory;
|
||||
void (*callback)(const uint64_t track, const Packet &p);
|
||||
};
|
||||
|
||||
class MPEGVideoHeader{
|
||||
public:
|
||||
MPEGVideoHeader(char * d);
|
||||
void clear();
|
||||
uint16_t getTotalLen() const;
|
||||
std::string toString() const;
|
||||
void setTempRef(uint16_t ref);
|
||||
void setPictureType(uint8_t pType);
|
||||
void setSequence();
|
||||
void setBegin();
|
||||
void setEnd();
|
||||
private:
|
||||
char * data;
|
||||
public:
|
||||
MPEGVideoHeader(char *d);
|
||||
void clear();
|
||||
uint16_t getTotalLen() const;
|
||||
std::string toString() const;
|
||||
void setTempRef(uint16_t ref);
|
||||
void setPictureType(uint8_t pType);
|
||||
void setSequence();
|
||||
void setBegin();
|
||||
void setEnd();
|
||||
|
||||
private:
|
||||
char *data;
|
||||
};
|
||||
|
||||
}
|
||||
/// Converts (sorted) RTP packets into DTSC packets.
|
||||
/// Outputs DTSC packets through a callback function or overridden virtual function.
|
||||
/// Updates init data through a callback function or overridden virtual function.
|
||||
class toDTSC{
|
||||
public:
|
||||
toDTSC();
|
||||
void setProperties(const uint64_t track, const std::string &codec, const std::string &type,
|
||||
const std::string &init, const double multiplier);
|
||||
void setProperties(const DTSC::Track &Trk);
|
||||
void setCallbacks(void (*cbPack)(const DTSC::Packet &pkt),
|
||||
void (*cbInit)(const uint64_t track, const std::string &initData));
|
||||
void addRTP(const RTP::Packet &rPkt);
|
||||
virtual void outPacket(const DTSC::Packet &pkt){
|
||||
if (cbPack){cbPack(pkt);}
|
||||
}
|
||||
virtual void outInit(const uint64_t track, const std::string &initData){
|
||||
if (cbInit){cbInit(track, initData);}
|
||||
}
|
||||
|
||||
public:
|
||||
uint64_t trackId;
|
||||
double multiplier; ///< Multiplier to convert from millis to RTP time
|
||||
std::string codec; ///< Codec of this track
|
||||
std::string type; ///< Type of this track
|
||||
std::string init; ///< Init data of this track
|
||||
unsigned int lastSeq; ///< Last sequence number seen
|
||||
uint64_t packCount; ///< Amount of DTSC packets outputted, for H264/HEVC
|
||||
double fps; ///< Framerate, for H264, HEVC
|
||||
uint32_t wrapArounds; ///< Counter for RTP timestamp wrapArounds
|
||||
bool recentWrap; ///< True if a wraparound happened recently.
|
||||
uint32_t prevTime;
|
||||
uint64_t firstTime;
|
||||
void (*cbPack)(const DTSC::Packet &pkt);
|
||||
void (*cbInit)(const uint64_t track, const std::string &initData);
|
||||
// Codec-specific handlers
|
||||
void handleAAC(uint64_t msTime, char *pl, uint32_t plSize);
|
||||
void handleMP2(uint64_t msTime, char *pl, uint32_t plSize);
|
||||
void handleMPEG2(uint64_t msTime, char *pl, uint32_t plSize);
|
||||
void handleHEVC(uint64_t msTime, char *pl, uint32_t plSize, bool missed);
|
||||
void handleHEVCSingle(uint64_t ts, const char *buffer, const uint32_t len, bool isKey);
|
||||
h265::initData hevcInfo; ///< For HEVC init parsing
|
||||
Util::ResizeablePointer fuaBuffer; ///< For H264/HEVC FU-A packets
|
||||
Util::ResizeablePointer packBuffer; ///< For H264/HEVC regular and STAP packets
|
||||
void handleH264(uint64_t msTime, char *pl, uint32_t plSize, bool missed, bool hasPadding);
|
||||
void handleH264Single(uint64_t ts, const char *buffer, const uint32_t len, bool isKey);
|
||||
void handleH264Multi(uint64_t ts, char *buffer, const uint32_t len);
|
||||
std::string spsData; ///< SPS for H264
|
||||
std::string ppsData; ///< PPS for H264
|
||||
void handleVP8(uint64_t msTime, const char *buffer, const uint32_t len, bool missed,
|
||||
bool hasPadding);
|
||||
Util::ResizeablePointer
|
||||
vp8FrameBuffer; ///< Stores successive VP8 payload data. We always start with the first
|
||||
///< partition; but we might be missing other partitions when they were
|
||||
///< lost. (a partition is basically what's called a slice in H264).
|
||||
bool vp8BufferHasKeyframe;
|
||||
};
|
||||
}// namespace RTP
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue