add rtcp support

pull/1809/head
莫战 5 years ago
parent 1b08fb6b6e
commit a72dce494d

2
trunk/configure vendored

@ -213,7 +213,7 @@ MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer"
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
"srs_kernel_stream" "srs_kernel_balance" "srs_kernel_mp4" "srs_kernel_file")
if [[ $SRS_RTC == YES ]]; then
MODULE_FILES+=("srs_kernel_rtp")
MODULE_FILES+=("srs_kernel_rtp" "srs_kernel_rtcp")
fi
KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh
KERNEL_OBJS="${MODULE_OBJS[@]}"

@ -0,0 +1,637 @@
#include <srs_kernel_rtcp.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
using namespace std;
SrsRTCPCommon::SrsRTCPCommon()
{
}
SrsRTCPCommon::~SrsRTCPCommon()
{
}
srs_error_t SrsRTCPCommon::decode_header(SrsBuffer *buffer)
{
buffer->read_bytes((char*)(&header_), sizeof(srs_rtcp_header_t));
header_.length = ntohs(header_.length);
return srs_success;
}
srs_error_t SrsRTCPCommon::encode_header(SrsBuffer *buffer)
{
header_.length = htons(header_.length);
buffer->write_bytes((char*)(&header_), sizeof(srs_rtcp_header_t));
return srs_success;
}
srs_error_t SrsRTCPCommon::decode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
err = decode_header(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to parse rtcp header");
}
payload_len_ = (header_.length + 1) * 4 - sizeof(srs_rtcp_header_t);
buffer->read_bytes((char *)payload_, payload_len_);
return srs_success;
}
int SrsRTCPCommon::nb_bytes()
{
return sizeof(srs_rtcp_header_t) + payload_len_;
}
srs_error_t SrsRTCPCommon::encode(SrsBuffer *buffer)
{
return srs_error_new(ERROR_RTC_RTCP, "not implement");
}
SrsRTCP_SR::SrsRTCP_SR()
{
header_.padding = 0;
header_.type = RTCP_SR;
header_.rc = 0;
header_.version = kRtcpVersion;
header_.length = 6;
}
SrsRTCP_SR::~SrsRTCP_SR()
{
}
const uint32_t SrsRTCP_SR::get_sender_ssrc() const
{
return sender_ssrc_;
}
const uint64_t SrsRTCP_SR::get_ntp() const
{
return ntp_;
}
const uint32_t SrsRTCP_SR::get_rtp_ts() const
{
return rtp_ts_;
}
const uint32_t SrsRTCP_SR::get_rtp_send_packets() const
{
return send_rtp_packets_;
}
const uint32_t SrsRTCP_SR::get_rtp_send_bytes() const
{
return send_rtp_bytes_;
}
void SrsRTCP_SR::set_sender_ssrc(uint32_t ssrc)
{
sender_ssrc_ = ssrc;
}
void SrsRTCP_SR::set_ntp(uint64_t ntp)
{
ntp_ = ntp;
}
void SrsRTCP_SR::set_rtp_ts(uint32_t ts)
{
rtp_ts_ = ts;
}
void SrsRTCP_SR::set_rtp_send_packets(uint32_t packets)
{
send_rtp_packets_ = packets;
}
void SrsRTCP_SR::set_rtp_send_bytes(uint32_t bytes)
{
send_rtp_bytes_ = bytes;
}
srs_error_t SrsRTCP_SR::decode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
err = decode_header(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to parse rtcp header");
}
sender_ssrc_ = buffer->read_4bytes();
ntp_ = buffer->read_8bytes();
rtp_ts_ = buffer->read_4bytes();
send_rtp_packets_ = buffer->read_4bytes();
send_rtp_bytes_ = buffer->read_4bytes();
if(header_.rc > 0) {
char buf[1500];
buffer->read_bytes(buf, header_.rc * 24);
}
return err;
}
int SrsRTCP_SR::nb_bytes()
{
return (header_.length + 1) * 4;
}
srs_error_t SrsRTCP_SR::encode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
if(! buffer->require(nb_bytes())) {
return srs_error_new(ERROR_RTC_RTCP,
"the size of buffer is not enough. buffer:%d, required:%d", buffer->left(), nb_bytes());
}
err = encode_header(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to encode rtcp header");
}
buffer->write_4bytes(sender_ssrc_);
buffer->write_8bytes(ntp_);
buffer->write_4bytes(rtp_ts_);
buffer->write_4bytes(send_rtp_packets_);
buffer->write_4bytes(send_rtp_bytes_);
return err;
}
SrsRTCP_RR::SrsRTCP_RR(uint32_t sender_ssrc/*=0*/): sender_ssrc_(sender_ssrc)
{
header_.padding = 0;
header_.type = RTCP_RR;
header_.rc = 0;
header_.version = kRtcpVersion;
header_.length = 7;
}
SrsRTCP_RR::~SrsRTCP_RR()
{
}
const uint32_t SrsRTCP_RR::get_rb_ssrc() const
{
return rb_.ssrc;
}
const float SrsRTCP_RR::get_lost_rate() const
{
return rb_.fraction_lost / 256;
}
const uint32_t SrsRTCP_RR::get_lost_packets() const
{
return rb_.lost_packets;
}
const uint32_t SrsRTCP_RR::get_highest_sn() const
{
return rb_.highest_sn;
}
const uint32_t SrsRTCP_RR::get_jitter() const
{
return rb_.jitter;
}
const uint32_t SrsRTCP_RR::get_lsr() const
{
return rb_.lsr;
}
const uint32_t SrsRTCP_RR::get_dlsr() const
{
return rb_.dlsr;
}
void SrsRTCP_RR::set_rb_ssrc(uint32_t ssrc)
{
rb_.ssrc = ssrc;
}
void SrsRTCP_RR::set_lost_rate(float rate)
{
rb_.fraction_lost = rate * 256;
}
void SrsRTCP_RR::set_lost_packets(uint32_t count)
{
rb_.lost_packets = count;
}
void SrsRTCP_RR::set_highest_sn(uint32_t sn)
{
rb_.highest_sn = sn;
}
void SrsRTCP_RR::set_jitter(uint32_t jitter)
{
rb_.jitter = jitter;
}
void SrsRTCP_RR::set_lsr(uint32_t lsr)
{
rb_.lsr = lsr;
}
void SrsRTCP_RR::set_dlsr(uint32_t dlsr)
{
rb_.dlsr = dlsr;
}
void SrsRTCP_RR::set_sender_ntp(uint64_t ntp)
{
uint32_t lsr = (uint32_t)((ntp >> 16) & 0x00000000FFFFFFFF);
rb_.lsr = lsr;
}
srs_error_t SrsRTCP_RR::decode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
err = decode_header(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to parse rtcp header");
}
sender_ssrc_ = buffer->read_4bytes();
if(header_.rc < 1) {
return srs_success;
}
rb_.ssrc = buffer->read_4bytes();
rb_.fraction_lost = buffer->read_1bytes();
rb_.lost_packets = buffer->read_3bytes();
rb_.highest_sn = buffer->read_4bytes();
rb_.jitter = buffer->read_4bytes();
rb_.lsr = buffer->read_4bytes();
rb_.dlsr = buffer->read_4bytes();
if(header_.rc > 1) {
char buf[1500];
buffer->read_bytes(buf, (header_.rc -1 ) * 24);
}
return err;
}
int SrsRTCP_RR::nb_bytes()
{
return (header_.length + 1) * 4;
}
srs_error_t SrsRTCP_RR::encode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
if(! buffer->require(nb_bytes())) {
return srs_error_new(ERROR_RTC_RTCP,
"the size of buffer is not enough. buffer:%d, required:%d", buffer->left(), nb_bytes());
}
header_.rc = 1;
err = encode_header(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to encode rtcp header");
}
buffer->write_4bytes(sender_ssrc_);
buffer->write_4bytes(rb_.ssrc);
buffer->write_1bytes(rb_.fraction_lost);
buffer->write_3bytes(rb_.lost_packets);
buffer->write_4bytes(rb_.highest_sn);
buffer->write_4bytes(rb_.jitter);
buffer->write_4bytes(rb_.lsr);
buffer->write_4bytes(rb_.dlsr);
return err;
}
SrsRTCP_TWCC::SrsRTCP_TWCC(uint32_t sender_ssrc/*=0*/) : sender_ssrc_(sender_ssrc)
{
header_.padding = 0;
header_.type = RTCP_RTPFB;
header_.rc = 15;
header_.version = kRtcpVersion;
}
SrsRTCP_TWCC::~SrsRTCP_TWCC()
{
}
const uint32_t SrsRTCP_TWCC::get_media_ssrc() const
{
return media_ssrc_;
}
const uint16_t SrsRTCP_TWCC::get_base_sn() const
{
return base_sn_;
}
const uint32_t SrsRTCP_TWCC::get_reference_time() const
{
return reference_time_;
}
const uint8_t SrsRTCP_TWCC::get_feedback_count() const
{
return fb_pkt_count_;
}
const uint16_t SrsRTCP_TWCC::get_packet_status_count() const
{
return recv_deltas_.size();
}
const vector<uint16_t> SrsRTCP_TWCC::get_packet_chucks() const
{
return packet_chucks_;
}
const vector<uint8_t> SrsRTCP_TWCC::get_recv_deltas() const
{
return recv_deltas_;
}
void SrsRTCP_TWCC::set_media_ssrc(uint32_t ssrc)
{
media_ssrc_ = ssrc;
}
void SrsRTCP_TWCC::set_base_sn(uint16_t sn)
{
base_sn_ = sn;
}
void SrsRTCP_TWCC::set_reference_time(uint32_t time)
{
reference_time_ = time;
}
void SrsRTCP_TWCC::set_feedback_count(uint8_t count)
{
fb_pkt_count_ = count;
}
void SrsRTCP_TWCC::add_packet_chuck(uint16_t chunk)
{
packet_chucks_.push_back(chunk);
}
void SrsRTCP_TWCC::add_recv_delta(uint8_t delta)
{
recv_deltas_.push_back(delta);
}
srs_error_t SrsRTCP_TWCC::decode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
return err;
}
int SrsRTCP_TWCC::nb_bytes()
{
return kRtcpPacketSize;
}
srs_error_t SrsRTCP_TWCC::encode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
return err;
}
SrsRTCP_Nack::SrsRTCP_Nack(uint32_t sender_ssrc /*= 0*/): sender_ssrc_(sender_ssrc)
{
header_.padding = 0;
header_.type = RTCP_RTPFB;
header_.rc = 1;
header_.version = kRtcpVersion;
}
SrsRTCP_Nack::~SrsRTCP_Nack()
{
}
const uint32_t SrsRTCP_Nack::get_media_ssrc() const
{
return media_ssrc_;
}
const vector<uint16_t> SrsRTCP_Nack::get_lost_sns() const
{
vector<uint16_t> sn;
for(auto it : lost_sns_) {
sn.push_back(it);
}
return sn;
}
void SrsRTCP_Nack::set_media_ssrc(uint32_t ssrc)
{
media_ssrc_ = ssrc;
}
void SrsRTCP_Nack::add_lost_sn(uint16_t sn)
{
lost_sns_.insert(sn);
}
srs_error_t SrsRTCP_Nack::decode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
err = decode_header(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to parse rtcp header");
}
sender_ssrc_ = buffer->read_4bytes();
media_ssrc_ = buffer->read_4bytes();
char bitmask[20];
for(int i = 0; i < (header_.length - 2); i++) {
uint16_t pid = buffer->read_2bytes();
uint16_t blp = buffer->read_2bytes();
lost_sns_.insert(pid);
memset(bitmask, 0, 20);
for(int j=0; j<16; j++) {
bitmask[j] = (blp & ( 1 << j )) >> j ? '1' : '0';
if((blp & ( 1 << j )) >> j)
lost_sns_.insert(pid+j+1);
}
bitmask[16] = '\n';
srs_info("[%d] %d / %s", i, pid, bitmask);
}
return err;
}
int SrsRTCP_Nack::nb_bytes()
{
return kRtcpPacketSize;
}
srs_error_t SrsRTCP_Nack::encode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
if(! buffer->require(nb_bytes())) {
return srs_error_new(ERROR_RTC_RTCP,
"the size of buffer is not enough. buffer:%d, required:%d", buffer->left(), nb_bytes());
}
vector<pid_blp_t*> chunks;
do {
pid_blp_t *chunk = NULL;
uint16_t pid = 0;
for(auto sn : lost_sns_) {
if(NULL == chunk) {
chunk = new pid_blp_t;
chunk->pid = sn;
chunk->blp = 0;
pid = sn;
continue;
}
if((sn - pid) < 1) {
srs_info("Skipping PID to NACK (%d already added)...\n", sn);
} else if( (sn - pid) > 16) {
// add new chunk
chunks.push_back(chunk);
chunk = NULL;
} else {
chunk->blp |= 1 << (sn-pid-1);
}
}
header_.length = 2 + chunks.size();
err = encode_header(buffer);
if(srs_success != err) {
err = srs_error_wrap(err, "fail to encode rtcp header");
break;
}
buffer->write_4bytes(sender_ssrc_);
buffer->write_4bytes(media_ssrc_);
for(auto chunk : chunks) {
buffer->write_2bytes(chunk->pid);
buffer->write_2bytes(chunk->blp);
delete chunk;
chunk = NULL;
}
} while(0);
for(auto chunk : chunks) {
delete chunk;
chunk = NULL;
}
return err;
}
SrsRTCPCompound::SrsRTCPCompound(): nb_bytes_(0)
{
}
SrsRTCPCompound::~SrsRTCPCompound()
{
clear();
}
SrsRTCPCommon* SrsRTCPCompound::get_next_rtcp()
{
if(rtcps_.empty()) {
return NULL;
}
SrsRTCPCommon *rtcp = rtcps_.back();
nb_bytes_ -= rtcp->nb_bytes();
rtcps_.pop_back();
return rtcp;
}
srs_error_t SrsRTCPCompound::add_rtcp(SrsRTCPCommon *rtcp)
{
int new_len = rtcp->nb_bytes();
if((new_len + nb_bytes_) > kRtcpPacketSize) {
return srs_error_new(ERROR_RTC_RTCP, "exceed the rtcp max size. new rtcp: %d, current: %d", new_len, nb_bytes_);
}
nb_bytes_ += new_len;
rtcps_.push_back(rtcp);
return srs_success;
}
srs_error_t SrsRTCPCompound::decode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
while(0 != buffer->left()) {
srs_rtcp_header_t* header = (srs_rtcp_header_t *)(buffer->head());
switch (header->type)
{
case RTCP_SR:
{
SrsRTCP_SR *rtcp = new SrsRTCP_SR;
err = rtcp->decode(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to decode rtcp sr");
}
nb_bytes_ += rtcp->nb_bytes();
rtcps_.push_back(rtcp);
break;
}
case RTCP_RR:
{
SrsRTCP_RR *rtcp = new SrsRTCP_RR;
err = rtcp->decode(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to decode rtcp rr");
}
nb_bytes_ += rtcp->nb_bytes();
rtcps_.push_back(rtcp);
break;
}
default:
{
SrsRTCPCommon *rtcp = new SrsRTCPCommon;
err = rtcp->decode(buffer);
if(srs_success != err) {
return srs_error_wrap(err, "fail to decode rtcp type:%d", header->type);
}
nb_bytes_ += rtcp->nb_bytes();
rtcps_.push_back(rtcp);
break;
}
}
}
return err;
}
int SrsRTCPCompound::nb_bytes()
{
return nb_bytes_;
}
srs_error_t SrsRTCPCompound::encode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
if(false == buffer->require(nb_bytes_)) {
return srs_error_new(ERROR_RTC_RTCP,
"the left size of buffer is not enough. buffer:%d, required:%d", buffer->left(), nb_bytes_);
}
vector<SrsRTCPCommon*>::iterator it;
for(it = rtcps_.begin(); it != rtcps_.end(); ++it) {
SrsRTCPCommon *rtcp = *it;
err = rtcp->encode(buffer);
if(err != srs_success) {
return srs_error_wrap(err, "fail to encode rtcp compound. type:%d", rtcp->type());
}
}
clear();
return err;
}
void SrsRTCPCompound::clear()
{
vector<SrsRTCPCommon*>::iterator it;
for(it = rtcps_.begin(); it != rtcps_.end(); ++it) {
SrsRTCPCommon *rtcp = *it;
delete rtcp;
rtcp = NULL;
}
rtcps_.clear();
nb_bytes_ = 0;
}

@ -0,0 +1,232 @@
#ifndef SRS_KERNEL_RTCP_HPP
#define SRS_KERNEL_RTCP_HPP
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_rtp.hpp>
#include <vector>
#include <set>
const int kRtcpPacketSize = 1500;
const uint8_t kRtcpVersion = 0x2;
/*! \brief RTCP Packet Types (http://www.networksorcery.com/enp/protocol/rtcp.htm) */
typedef enum {
RTCP_FIR = 192,
RTCP_SR = 200,
RTCP_RR = 201,
RTCP_SDES = 202,
RTCP_BYE = 203,
RTCP_APP = 204,
RTCP_RTPFB = 205,
RTCP_PSFB = 206,
RTCP_XR = 207,
} srs_rtcp_type_t;
/*! \brief RTCP Header (http://tools.ietf.org/html/rfc3550#section-6.1) */
typedef struct srs_rtcp_header_s
{
uint16_t rc:5;
uint16_t padding:1;
uint16_t version:2;
uint16_t type:8;
uint16_t length:16;
} srs_rtcp_header_t;
class SrsRTCPCommon: public ISrsCodec
{
protected:
srs_rtcp_header_t header_;
uint8_t payload_[kRtcpPacketSize];
int payload_len_;
protected:
srs_error_t decode_header(SrsBuffer *buffer);
srs_error_t encode_header(SrsBuffer *buffer);
public:
SrsRTCPCommon();
virtual ~SrsRTCPCommon();
virtual const uint8_t type() const { return header_.type; }
public:
// ISrsCodec
virtual srs_error_t decode(SrsBuffer *buffer);
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer *buffer);
};
typedef struct srs_rtcp_report_block_s {
uint32_t ssrc;
uint8_t fraction_lost;
uint32_t lost_packets;
uint32_t highest_sn;
uint32_t jitter;
uint32_t lsr;
uint32_t dlsr;
}srs_rtcp_rb_t;
class SrsRTCP_SR : public SrsRTCPCommon
{
private:
uint32_t sender_ssrc_;
uint64_t ntp_;
uint32_t rtp_ts_;
uint32_t send_rtp_packets_;
uint32_t send_rtp_bytes_;
public:
SrsRTCP_SR();
virtual ~SrsRTCP_SR();
const uint8_t get_rc() const { return header_.rc; }
// overload SrsRTCPCommon
virtual const uint8_t type() const { return RTCP_SR; }
const uint32_t get_sender_ssrc() const;
const uint64_t get_ntp() const;
const uint32_t get_rtp_ts() const;
const uint32_t get_rtp_send_packets() const;
const uint32_t get_rtp_send_bytes() const;
void set_sender_ssrc(uint32_t ssrc);
void set_ntp(uint64_t ntp);
void set_rtp_ts(uint32_t ts);
void set_rtp_send_packets(uint32_t packets);
void set_rtp_send_bytes(uint32_t bytes);
public:
// ISrsCodec
virtual srs_error_t decode(SrsBuffer *buffer);
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer *buffer);
};
class SrsRTCP_RR : public SrsRTCPCommon
{
private:
uint32_t sender_ssrc_;
srs_rtcp_rb_t rb_;
public:
SrsRTCP_RR(uint32_t sender_ssrc = 0);
virtual ~SrsRTCP_RR();
// overload SrsRTCPCommon
virtual const uint8_t type() const { return RTCP_RR; }
const uint32_t get_rb_ssrc() const;
const float get_lost_rate() const;
const uint32_t get_lost_packets() const;
const uint32_t get_highest_sn() const;
const uint32_t get_jitter() const;
const uint32_t get_lsr() const;
const uint32_t get_dlsr() const;
void set_rb_ssrc(uint32_t ssrc);
void set_lost_rate(float rate);
void set_lost_packets(uint32_t count);
void set_highest_sn(uint32_t sn);
void set_jitter(uint32_t jitter);
void set_lsr(uint32_t lsr);
void set_dlsr(uint32_t dlsr);
void set_sender_ntp(uint64_t ntp);
public:
// ISrsCodec
virtual srs_error_t decode(SrsBuffer *buffer);
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer *buffer);
};
class SrsRTCP_TWCC : public SrsRTCPCommon
{
private:
uint32_t sender_ssrc_;
uint32_t media_ssrc_;
uint16_t base_sn_;
uint32_t reference_time_;
uint8_t fb_pkt_count_;
std::vector<uint16_t> packet_chucks_;
std::vector<uint8_t> recv_deltas_;
public:
SrsRTCP_TWCC(uint32_t sender_ssrc = 0);
virtual ~SrsRTCP_TWCC();
const uint32_t get_media_ssrc() const;
const uint16_t get_base_sn() const;
const uint32_t get_reference_time() const;
const uint8_t get_feedback_count() const;
const uint16_t get_packet_status_count() const;
const std::vector<uint16_t> get_packet_chucks() const;
const std::vector<uint8_t> get_recv_deltas() const;
void set_media_ssrc(uint32_t ssrc);
void set_base_sn(uint16_t sn);
void set_reference_time(uint32_t time);
void set_feedback_count(uint8_t count);
void add_packet_chuck(uint16_t chuck);
void add_recv_delta(uint8_t delta);
public:
// ISrsCodec
virtual srs_error_t decode(SrsBuffer *buffer);
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer *buffer);
};
struct less_compare {
bool operator()(const uint16_t &lhs, const uint16_t &rhs) const {
return SnCompare(rhs, lhs);
}
};
class SrsRTCP_Nack : public SrsRTCPCommon
{
private:
typedef struct pid_blp_s {
uint16_t pid;
uint16_t blp;
}pid_blp_t;
uint32_t sender_ssrc_;
uint32_t media_ssrc_;
std::set<uint16_t, less_compare> lost_sns_;
public:
SrsRTCP_Nack(uint32_t sender_ssrc = 0);
virtual ~SrsRTCP_Nack();
const uint32_t get_media_ssrc() const;
const std::vector<uint16_t> get_lost_sns() const;
void set_media_ssrc(uint32_t ssrc);
void add_lost_sn(uint16_t sn);
public:
// ISrsCodec
virtual srs_error_t decode(SrsBuffer *buffer);
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer *buffer);
};
class SrsRTCPCompound : public ISrsCodec
{
private:
std::vector<SrsRTCPCommon* > rtcps_;
int nb_bytes_;
public:
SrsRTCPCompound();
virtual ~SrsRTCPCompound();
SrsRTCPCommon* get_next_rtcp();
srs_error_t add_rtcp(SrsRTCPCommon *rtcp);
void clear();
public:
// ISrsCodec
virtual srs_error_t decode(SrsBuffer *buffer);
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer *buffer);
};
#endif

@ -32,6 +32,56 @@ using namespace std;
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_utility.hpp>
//sn comparisonif current_sn is more than last_snreturn trueelse return false
bool SnCompare(uint16_t current_sn, uint16_t last_sn) {
if(current_sn > last_sn) {
//current_sn 65533 last_sn 5
if(current_sn - last_sn > 0x8000) {
return false;
} else {
return true;
}
} else {
//current_sn 2 last_sn 65535
if(current_sn - last_sn < -0x8000) {
return true;
} else {
return false;
}
}
}
bool SnRollback(uint16_t current_sn, uint16_t last_sn)
{
if(SnCompare(current_sn, last_sn)) {
if((last_sn > current_sn)) {
return true;
}
}
return false;
}
// caculate the difference between sn. If current_sn is more then last_sn, return positive difference, else return negative difference.
int32_t SnDiff(uint16_t current_sn, uint16_t last_sn) {
if(current_sn > last_sn) {
//current_sn 65535 last_sn 0
if(current_sn - last_sn > 0x8000) {
return (current_sn - last_sn - 1 - 65535);
} else {
return (current_sn - last_sn);
}
} else {
//current_sn 0 last_sn 65535
if(current_sn - last_sn < -0x8000) {
return (current_sn - last_sn + 65535 + 1);
} else {
return (current_sn - last_sn);
// current_sn 15039 last_sn 15042
//return last_sn - current_sn;
}
}
}
SrsRtpHeader::SrsRtpHeader()
{
padding = false;

@ -54,6 +54,10 @@ class SrsBuffer;
class SrsRtpRawPayload;
class SrsRtpFUAPayload2;
bool SnCompare(uint16_t current_sn, uint16_t last_sn);
bool SnRollback(uint16_t current_sn, uint16_t last_sn);
int32_t SnDiff(uint16_t current_sn, uint16_t last_sn);
class SrsRtpHeader
{
private:

Loading…
Cancel
Save