mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
rtc: support parse rtp packet extension
This commit is contained in:
parent
69e4a1b5e7
commit
705843b512
2 changed files with 161 additions and 16 deletions
|
@ -51,6 +51,47 @@ int32_t srs_seq_distance(uint16_t value, uint16_t pre_value) {
|
||||||
return srs_rtp_seq_distance(pre_value, value);
|
return srs_rtp_seq_distance(pre_value, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsRtpHeaderExtensionMap::SrsRtpHeaderExtensionMap(){
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsRtpHeaderExtensionMap::~SrsRtpHeaderExtensionMap(){
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SrsRtpHeaderExtensionMap::register_by_uri(int id, std::string uri) {
|
||||||
|
for (int i = 0; i < sizeof(kExtensions); ++i) {
|
||||||
|
if (kExtensions[i].uri == uri) {
|
||||||
|
return register_id(id, kExtensions[i].type, kExtensions[i].uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SrsRtpHeaderExtensionMap::register_id(int id, SrsRtpExtensionType type, std::string uri) {
|
||||||
|
if (id < 1 || id > 255) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ids_[type] = static_cast<uint8_t>(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsRtpExtensionType SrsRtpHeaderExtensionMap::get_type(int id) const {
|
||||||
|
for (int type = kRtpExtensionNone + 1; type < kRtpExtensionNumberOfExtensions; ++type) {
|
||||||
|
if (ids_[type] == id) {
|
||||||
|
return static_cast<SrsRtpExtensionType>(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kInvalidType;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsRtpHeaderExtension::SrsRtpHeaderExtension() {
|
||||||
|
has_transport_sequence_number = false;
|
||||||
|
transport_sequence_number = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsRtpHeaderExtension::~SrsRtpHeaderExtension() {
|
||||||
|
}
|
||||||
|
|
||||||
SrsRtpHeader::SrsRtpHeader()
|
SrsRtpHeader::SrsRtpHeader()
|
||||||
{
|
{
|
||||||
padding_length = 0;
|
padding_length = 0;
|
||||||
|
@ -68,7 +109,63 @@ SrsRtpHeader::~SrsRtpHeader()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsRtpHeader::decode(SrsBuffer* buf)
|
srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf, const SrsRtpHeaderExtensionMap *extension_map) {
|
||||||
|
srs_error_t err = srs_success;
|
||||||
|
uint16_t profile_id = buf->read_2bytes();
|
||||||
|
uint16_t extension_length = buf->read_2bytes();
|
||||||
|
|
||||||
|
if (!extension_map) {
|
||||||
|
buf->skip(extension_length * 4);
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
srs_trace("extension_map uri : %d", extension_map->get_type(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
// @see: https://tools.ietf.org/html/rfc5285#section-4.2
|
||||||
|
if (profile_id == 0xBEDE) {
|
||||||
|
uint32_t xlen = extension_length * 4;
|
||||||
|
while (xlen > 0) {
|
||||||
|
// parse id and len
|
||||||
|
uint8_t id_len = buf->read_1bytes();
|
||||||
|
xlen--;
|
||||||
|
if(id_len == 0) {
|
||||||
|
// padding, ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 0
|
||||||
|
// 0 1 2 3 4 5 6 7
|
||||||
|
// +-+-+-+-+-+-+-+-+
|
||||||
|
// | ID | len |
|
||||||
|
// +-+-+-+-+-+-+-+-+
|
||||||
|
// Note that 'len' is the header extension element length, which is the
|
||||||
|
// number of bytes - 1.
|
||||||
|
uint8_t id = (id_len & 0xF0) >> 4;
|
||||||
|
uint8_t len = (id_len & 0x0F);
|
||||||
|
|
||||||
|
SrsRtpExtensionType xtype = extension_map->get_type(id);
|
||||||
|
if (xtype == kRtpExtensionTransportSequenceNumber) {
|
||||||
|
// 0 1 2
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | ID | L=1 |transport wide sequence number |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
header_extension.has_transport_sequence_number = true;
|
||||||
|
header_extension.transport_sequence_number = buf->read_2bytes();
|
||||||
|
srs_trace("get twcc sn:%d", header_extension.transport_sequence_number);
|
||||||
|
} else {
|
||||||
|
buf->skip(len + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (profile_id == 0x1000) {
|
||||||
|
buf->skip(extension_length * 4);
|
||||||
|
} else {
|
||||||
|
return srs_error_new(ERROR_RTC_RTP_MUXER, "fail to parse extension");
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_error_t SrsRtpHeader::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
@ -114,16 +211,17 @@ srs_error_t SrsRtpHeader::decode(SrsBuffer* buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extension) {
|
if (extension) {
|
||||||
uint16_t profile_id = buf->read_2bytes();
|
/* RTP header extension, RFC 3550.
|
||||||
extension_length = buf->read_2bytes();
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
// TODO: FIXME: Read extensions.
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
// @see: https://tools.ietf.org/html/rfc3550#section-5.3.1
|
| defined by profile | length |
|
||||||
buf->skip(extension_length * 4);
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| header extension |
|
||||||
// @see: https://tools.ietf.org/html/rfc5285#section-4.2
|
| .... |
|
||||||
if (profile_id == 0xBEDE) {
|
*/
|
||||||
// TODO: FIXME: Implements it.
|
if ((err = parse_extension(buf, extmap)) != srs_success) {
|
||||||
|
return srs_error_wrap(err, "fail to parse extension");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +299,15 @@ srs_error_t SrsRtpHeader::encode(SrsBuffer* buf)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srs_error_t SrsRtpHeader::get_twcc_sequence_number(uint16_t& twcc_sn)
|
||||||
|
{
|
||||||
|
if (header_extension.has_transport_sequence_number == true) {
|
||||||
|
twcc_sn = header_extension.transport_sequence_number;
|
||||||
|
return srs_success;
|
||||||
|
}
|
||||||
|
return srs_error_new(ERROR_RTC_RTP_MUXER, "not find twcc sequence number");
|
||||||
|
}
|
||||||
|
|
||||||
int SrsRtpHeader::nb_bytes()
|
int SrsRtpHeader::nb_bytes()
|
||||||
{
|
{
|
||||||
return kRtpHeaderFixedSize + cc * 4 + (extension ? (extension_length + 1) * 4 : 0);
|
return kRtpHeaderFixedSize + cc * 4 + (extension ? (extension_length + 1) * 4 : 0);
|
||||||
|
@ -375,7 +482,7 @@ srs_error_t SrsRtpPacket2::encode(SrsBuffer* buf)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf)
|
srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,41 @@ bool srs_seq_is_newer(uint16_t value, uint16_t pre_value);
|
||||||
bool srs_seq_is_rollback(uint16_t value, uint16_t pre_value);
|
bool srs_seq_is_rollback(uint16_t value, uint16_t pre_value);
|
||||||
int32_t srs_seq_distance(uint16_t value, uint16_t pre_value);
|
int32_t srs_seq_distance(uint16_t value, uint16_t pre_value);
|
||||||
|
|
||||||
|
enum SrsRtpExtensionType : int {
|
||||||
|
kRtpExtensionNone,
|
||||||
|
kRtpExtensionTransportSequenceNumber,
|
||||||
|
kRtpExtensionNumberOfExtensions // Must be the last entity in the enum.
|
||||||
|
};
|
||||||
|
struct SrsExtensionInfo {
|
||||||
|
SrsRtpExtensionType type;
|
||||||
|
std::string uri;
|
||||||
|
};
|
||||||
|
const SrsExtensionInfo kExtensions[] = {
|
||||||
|
{kRtpExtensionTransportSequenceNumber, std::string("http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01")}
|
||||||
|
};
|
||||||
|
class SrsRtpHeaderExtensionMap{
|
||||||
|
public:
|
||||||
|
static const SrsRtpExtensionType kInvalidType = kRtpExtensionNone;
|
||||||
|
static const int kInvalidId = 0;
|
||||||
|
public:
|
||||||
|
bool register_by_uri(int id, std::string uri);
|
||||||
|
SrsRtpExtensionType get_type(int id) const;
|
||||||
|
public:
|
||||||
|
SrsRtpHeaderExtensionMap();
|
||||||
|
virtual ~SrsRtpHeaderExtensionMap();
|
||||||
|
private:
|
||||||
|
bool register_id(int id, SrsRtpExtensionType type, std::string uri);
|
||||||
|
private:
|
||||||
|
uint8_t ids_[kRtpExtensionNumberOfExtensions];
|
||||||
|
};
|
||||||
|
class SrsRtpHeaderExtension{
|
||||||
|
public:
|
||||||
|
bool has_transport_sequence_number;
|
||||||
|
uint16_t transport_sequence_number;
|
||||||
|
public:
|
||||||
|
SrsRtpHeaderExtension();
|
||||||
|
virtual ~SrsRtpHeaderExtension();
|
||||||
|
};
|
||||||
class SrsRtpHeader
|
class SrsRtpHeader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -95,12 +130,14 @@ private:
|
||||||
uint32_t ssrc;
|
uint32_t ssrc;
|
||||||
uint32_t csrc[15];
|
uint32_t csrc[15];
|
||||||
uint16_t extension_length;
|
uint16_t extension_length;
|
||||||
// TODO:extension field.
|
SrsRtpHeaderExtension header_extension;
|
||||||
public:
|
public:
|
||||||
SrsRtpHeader();
|
SrsRtpHeader();
|
||||||
virtual ~SrsRtpHeader();
|
virtual ~SrsRtpHeader();
|
||||||
|
private:
|
||||||
|
srs_error_t parse_extension(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extension_map);
|
||||||
public:
|
public:
|
||||||
virtual srs_error_t decode(SrsBuffer* buf);
|
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = nullptr);
|
||||||
virtual srs_error_t encode(SrsBuffer* buf);
|
virtual srs_error_t encode(SrsBuffer* buf);
|
||||||
virtual int nb_bytes();
|
virtual int nb_bytes();
|
||||||
public:
|
public:
|
||||||
|
@ -116,6 +153,7 @@ public:
|
||||||
uint32_t get_ssrc() const;
|
uint32_t get_ssrc() const;
|
||||||
void set_padding(uint8_t v);
|
void set_padding(uint8_t v);
|
||||||
uint8_t get_padding() const;
|
uint8_t get_padding() const;
|
||||||
|
srs_error_t get_twcc_sequence_number(uint16_t& twcc_sn);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ISrsRtpPayloader : public ISrsCodec
|
class ISrsRtpPayloader : public ISrsCodec
|
||||||
|
@ -175,7 +213,7 @@ public:
|
||||||
public:
|
public:
|
||||||
virtual int nb_bytes();
|
virtual int nb_bytes();
|
||||||
virtual srs_error_t encode(SrsBuffer* buf);
|
virtual srs_error_t encode(SrsBuffer* buf);
|
||||||
virtual srs_error_t decode(SrsBuffer* buf);
|
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Single payload data.
|
// Single payload data.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue