RTCP is the Real-Time Control Protocol
This page hosts a formal specification of rtcp network payload (single udp packet) using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All parsing code for C++98/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream
). One can open local file for that, or use existing std::string
or char*
buffer.
#include <fstream>
std::ifstream is("path/to/local/file.bin", std::ifstream::binary);
#include <sstream>
std::istringstream is(str);
#include <sstream>
const char buf[] = { ... };
std::string str(buf, sizeof buf);
std::istringstream is(str);
#include "kaitai/kaitaistream.h"
kaitai::kstream ks(&is);
rtcp_payload_t data(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.rtcp_packets() // => get rtcp packets
#ifndef RTCP_PAYLOAD_H_
#define RTCP_PAYLOAD_H_
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <vector>
#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif
/**
* RTCP is the Real-Time Control Protocol
* \sa https://www.rfc-editor.org/rfc/rfc3550 Source
*/
class rtcp_payload_t : public kaitai::kstruct {
public:
class psfb_afb_remb_packet_t;
class sr_packet_t;
class rr_packet_t;
class rtcp_packet_t;
class sdes_tlv_t;
class report_block_t;
class rtpfb_transport_feedback_packet_t;
class psfb_packet_t;
class source_chunk_t;
class sdes_packet_t;
class rtpfb_packet_t;
class packet_status_chunk_t;
class psfb_afb_packet_t;
enum payload_type_t {
PAYLOAD_TYPE_FIR = 192,
PAYLOAD_TYPE_NACK = 193,
PAYLOAD_TYPE_IJ = 195,
PAYLOAD_TYPE_SR = 200,
PAYLOAD_TYPE_RR = 201,
PAYLOAD_TYPE_SDES = 202,
PAYLOAD_TYPE_BYE = 203,
PAYLOAD_TYPE_APP = 204,
PAYLOAD_TYPE_RTPFB = 205,
PAYLOAD_TYPE_PSFB = 206,
PAYLOAD_TYPE_XR = 207,
PAYLOAD_TYPE_AVB = 208,
PAYLOAD_TYPE_RSI = 209
};
enum sdes_subtype_t {
SDES_SUBTYPE_PAD = 0,
SDES_SUBTYPE_CNAME = 1,
SDES_SUBTYPE_NAME = 2,
SDES_SUBTYPE_EMAIL = 3,
SDES_SUBTYPE_PHONE = 4,
SDES_SUBTYPE_LOC = 5,
SDES_SUBTYPE_TOOL = 6,
SDES_SUBTYPE_NOTE = 7,
SDES_SUBTYPE_PRIV = 8
};
enum psfb_subtype_t {
PSFB_SUBTYPE_PLI = 1,
PSFB_SUBTYPE_SLI = 2,
PSFB_SUBTYPE_RPSI = 3,
PSFB_SUBTYPE_FIR = 4,
PSFB_SUBTYPE_TSTR = 5,
PSFB_SUBTYPE_TSTN = 6,
PSFB_SUBTYPE_VBCM = 7,
PSFB_SUBTYPE_AFB = 15
};
enum rtpfb_subtype_t {
RTPFB_SUBTYPE_NACK = 1,
RTPFB_SUBTYPE_TMMBR = 3,
RTPFB_SUBTYPE_TMMBN = 4,
RTPFB_SUBTYPE_RRR = 5,
RTPFB_SUBTYPE_TRANSPORT_FEEDBACK = 15
};
rtcp_payload_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~rtcp_payload_t();
class psfb_afb_remb_packet_t : public kaitai::kstruct {
public:
psfb_afb_remb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::psfb_afb_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~psfb_afb_remb_packet_t();
private:
bool f_max_total_bitrate;
int32_t m_max_total_bitrate;
public:
int32_t max_total_bitrate();
private:
uint8_t m_num_ssrc;
uint64_t m_br_exp;
uint64_t m_br_mantissa;
std::vector<uint32_t>* m_ssrc_list;
rtcp_payload_t* m__root;
rtcp_payload_t::psfb_afb_packet_t* m__parent;
public:
uint8_t num_ssrc() const { return m_num_ssrc; }
uint64_t br_exp() const { return m_br_exp; }
uint64_t br_mantissa() const { return m_br_mantissa; }
std::vector<uint32_t>* ssrc_list() const { return m_ssrc_list; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::psfb_afb_packet_t* _parent() const { return m__parent; }
};
class sr_packet_t : public kaitai::kstruct {
public:
sr_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~sr_packet_t();
private:
bool f_ntp;
int32_t m_ntp;
public:
int32_t ntp();
private:
uint32_t m_ssrc;
uint32_t m_ntp_msw;
uint32_t m_ntp_lsw;
uint32_t m_rtp_timestamp;
uint32_t m_sender_packet_count;
uint32_t m_sender_octet_count;
std::vector<report_block_t*>* m_report_block;
rtcp_payload_t* m__root;
rtcp_payload_t::rtcp_packet_t* m__parent;
public:
uint32_t ssrc() const { return m_ssrc; }
uint32_t ntp_msw() const { return m_ntp_msw; }
uint32_t ntp_lsw() const { return m_ntp_lsw; }
uint32_t rtp_timestamp() const { return m_rtp_timestamp; }
uint32_t sender_packet_count() const { return m_sender_packet_count; }
uint32_t sender_octet_count() const { return m_sender_octet_count; }
std::vector<report_block_t*>* report_block() const { return m_report_block; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::rtcp_packet_t* _parent() const { return m__parent; }
};
class rr_packet_t : public kaitai::kstruct {
public:
rr_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~rr_packet_t();
private:
uint32_t m_ssrc;
std::vector<report_block_t*>* m_report_block;
rtcp_payload_t* m__root;
rtcp_payload_t::rtcp_packet_t* m__parent;
public:
uint32_t ssrc() const { return m_ssrc; }
std::vector<report_block_t*>* report_block() const { return m_report_block; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::rtcp_packet_t* _parent() const { return m__parent; }
};
class rtcp_packet_t : public kaitai::kstruct {
public:
rtcp_packet_t(kaitai::kstream* p__io, rtcp_payload_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~rtcp_packet_t();
private:
uint64_t m_version;
bool m_padding;
uint64_t m_subtype;
payload_type_t m_payload_type;
uint16_t m_length;
kaitai::kstruct* m_body;
bool n_body;
public:
bool _is_null_body() { body(); return n_body; };
private:
rtcp_payload_t* m__root;
rtcp_payload_t* m__parent;
std::string m__raw_body;
kaitai::kstream* m__io__raw_body;
public:
uint64_t version() const { return m_version; }
bool padding() const { return m_padding; }
uint64_t subtype() const { return m_subtype; }
payload_type_t payload_type() const { return m_payload_type; }
uint16_t length() const { return m_length; }
kaitai::kstruct* body() const { return m_body; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t* _parent() const { return m__parent; }
std::string _raw_body() const { return m__raw_body; }
kaitai::kstream* _io__raw_body() const { return m__io__raw_body; }
};
class sdes_tlv_t : public kaitai::kstruct {
public:
sdes_tlv_t(kaitai::kstream* p__io, rtcp_payload_t::source_chunk_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~sdes_tlv_t();
private:
sdes_subtype_t m_type;
uint8_t m_length;
bool n_length;
public:
bool _is_null_length() { length(); return n_length; };
private:
std::string m_value;
bool n_value;
public:
bool _is_null_value() { value(); return n_value; };
private:
rtcp_payload_t* m__root;
rtcp_payload_t::source_chunk_t* m__parent;
public:
sdes_subtype_t type() const { return m_type; }
uint8_t length() const { return m_length; }
std::string value() const { return m_value; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::source_chunk_t* _parent() const { return m__parent; }
};
class report_block_t : public kaitai::kstruct {
public:
report_block_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~report_block_t();
private:
bool f_fraction_lost;
int32_t m_fraction_lost;
public:
int32_t fraction_lost();
private:
bool f_cumulative_packets_lost;
int32_t m_cumulative_packets_lost;
public:
int32_t cumulative_packets_lost();
private:
uint32_t m_ssrc_source;
uint8_t m_lost_val;
uint32_t m_highest_seq_num_received;
uint32_t m_interarrival_jitter;
uint32_t m_lsr;
uint32_t m_dlsr;
rtcp_payload_t* m__root;
kaitai::kstruct* m__parent;
public:
uint32_t ssrc_source() const { return m_ssrc_source; }
uint8_t lost_val() const { return m_lost_val; }
uint32_t highest_seq_num_received() const { return m_highest_seq_num_received; }
uint32_t interarrival_jitter() const { return m_interarrival_jitter; }
uint32_t lsr() const { return m_lsr; }
uint32_t dlsr() const { return m_dlsr; }
rtcp_payload_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
class rtpfb_transport_feedback_packet_t : public kaitai::kstruct {
public:
rtpfb_transport_feedback_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtpfb_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~rtpfb_transport_feedback_packet_t();
private:
bool f_reference_time;
int32_t m_reference_time;
public:
int32_t reference_time();
private:
bool f_fb_pkt_count;
int32_t m_fb_pkt_count;
public:
int32_t fb_pkt_count();
private:
bool f_packet_status;
std::string m_packet_status;
public:
std::string packet_status();
private:
bool f_recv_delta;
std::string m_recv_delta;
public:
std::string recv_delta();
private:
uint16_t m_base_sequence_number;
uint16_t m_packet_status_count;
uint32_t m_b4;
std::string m_remaining;
rtcp_payload_t* m__root;
rtcp_payload_t::rtpfb_packet_t* m__parent;
public:
uint16_t base_sequence_number() const { return m_base_sequence_number; }
uint16_t packet_status_count() const { return m_packet_status_count; }
uint32_t b4() const { return m_b4; }
std::string remaining() const { return m_remaining; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::rtpfb_packet_t* _parent() const { return m__parent; }
};
class psfb_packet_t : public kaitai::kstruct {
public:
psfb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~psfb_packet_t();
private:
bool f_fmt;
psfb_subtype_t m_fmt;
public:
psfb_subtype_t fmt();
private:
uint32_t m_ssrc;
uint32_t m_ssrc_media_source;
psfb_afb_packet_t* m_fci_block;
bool n_fci_block;
public:
bool _is_null_fci_block() { fci_block(); return n_fci_block; };
private:
rtcp_payload_t* m__root;
rtcp_payload_t::rtcp_packet_t* m__parent;
std::string m__raw_fci_block;
kaitai::kstream* m__io__raw_fci_block;
public:
uint32_t ssrc() const { return m_ssrc; }
uint32_t ssrc_media_source() const { return m_ssrc_media_source; }
psfb_afb_packet_t* fci_block() const { return m_fci_block; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::rtcp_packet_t* _parent() const { return m__parent; }
std::string _raw_fci_block() const { return m__raw_fci_block; }
kaitai::kstream* _io__raw_fci_block() const { return m__io__raw_fci_block; }
};
class source_chunk_t : public kaitai::kstruct {
public:
source_chunk_t(kaitai::kstream* p__io, rtcp_payload_t::sdes_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~source_chunk_t();
private:
uint32_t m_ssrc;
std::vector<sdes_tlv_t*>* m_sdes_tlv;
rtcp_payload_t* m__root;
rtcp_payload_t::sdes_packet_t* m__parent;
public:
uint32_t ssrc() const { return m_ssrc; }
std::vector<sdes_tlv_t*>* sdes_tlv() const { return m_sdes_tlv; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::sdes_packet_t* _parent() const { return m__parent; }
};
class sdes_packet_t : public kaitai::kstruct {
public:
sdes_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~sdes_packet_t();
private:
bool f_source_count;
uint64_t m_source_count;
public:
uint64_t source_count();
private:
std::vector<source_chunk_t*>* m_source_chunk;
rtcp_payload_t* m__root;
rtcp_payload_t::rtcp_packet_t* m__parent;
public:
std::vector<source_chunk_t*>* source_chunk() const { return m_source_chunk; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::rtcp_packet_t* _parent() const { return m__parent; }
};
class rtpfb_packet_t : public kaitai::kstruct {
public:
rtpfb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~rtpfb_packet_t();
private:
bool f_fmt;
rtpfb_subtype_t m_fmt;
public:
rtpfb_subtype_t fmt();
private:
uint32_t m_ssrc;
uint32_t m_ssrc_media_source;
rtpfb_transport_feedback_packet_t* m_fci_block;
bool n_fci_block;
public:
bool _is_null_fci_block() { fci_block(); return n_fci_block; };
private:
rtcp_payload_t* m__root;
rtcp_payload_t::rtcp_packet_t* m__parent;
std::string m__raw_fci_block;
kaitai::kstream* m__io__raw_fci_block;
public:
uint32_t ssrc() const { return m_ssrc; }
uint32_t ssrc_media_source() const { return m_ssrc_media_source; }
rtpfb_transport_feedback_packet_t* fci_block() const { return m_fci_block; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::rtcp_packet_t* _parent() const { return m__parent; }
std::string _raw_fci_block() const { return m__raw_fci_block; }
kaitai::kstream* _io__raw_fci_block() const { return m__io__raw_fci_block; }
};
class packet_status_chunk_t : public kaitai::kstruct {
public:
packet_status_chunk_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~packet_status_chunk_t();
private:
bool f_s;
int32_t m_s;
public:
int32_t s();
private:
bool m_t;
uint64_t m_s2;
bool n_s2;
public:
bool _is_null_s2() { s2(); return n_s2; };
private:
bool m_s1;
bool n_s1;
public:
bool _is_null_s1() { s1(); return n_s1; };
private:
uint64_t m_rle;
bool n_rle;
public:
bool _is_null_rle() { rle(); return n_rle; };
private:
uint64_t m_symbol_list;
bool n_symbol_list;
public:
bool _is_null_symbol_list() { symbol_list(); return n_symbol_list; };
private:
rtcp_payload_t* m__root;
kaitai::kstruct* m__parent;
public:
bool t() const { return m_t; }
uint64_t s2() const { return m_s2; }
bool s1() const { return m_s1; }
uint64_t rle() const { return m_rle; }
uint64_t symbol_list() const { return m_symbol_list; }
rtcp_payload_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
class psfb_afb_packet_t : public kaitai::kstruct {
public:
psfb_afb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::psfb_packet_t* p__parent = 0, rtcp_payload_t* p__root = 0);
private:
void _read();
void _clean_up();
public:
~psfb_afb_packet_t();
private:
uint32_t m_uid;
psfb_afb_remb_packet_t* m_contents;
bool n_contents;
public:
bool _is_null_contents() { contents(); return n_contents; };
private:
rtcp_payload_t* m__root;
rtcp_payload_t::psfb_packet_t* m__parent;
std::string m__raw_contents;
kaitai::kstream* m__io__raw_contents;
public:
uint32_t uid() const { return m_uid; }
psfb_afb_remb_packet_t* contents() const { return m_contents; }
rtcp_payload_t* _root() const { return m__root; }
rtcp_payload_t::psfb_packet_t* _parent() const { return m__parent; }
std::string _raw_contents() const { return m__raw_contents; }
kaitai::kstream* _io__raw_contents() const { return m__io__raw_contents; }
};
private:
std::vector<rtcp_packet_t*>* m_rtcp_packets;
rtcp_payload_t* m__root;
kaitai::kstruct* m__parent;
public:
std::vector<rtcp_packet_t*>* rtcp_packets() const { return m_rtcp_packets; }
rtcp_payload_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
#endif // RTCP_PAYLOAD_H_
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "rtcp_payload.h"
rtcp_payload_t::rtcp_payload_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = this;
m_rtcp_packets = 0;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::_read() {
m_rtcp_packets = new std::vector<rtcp_packet_t*>();
{
int i = 0;
while (!m__io->is_eof()) {
m_rtcp_packets->push_back(new rtcp_packet_t(m__io, this, m__root));
i++;
}
}
}
rtcp_payload_t::~rtcp_payload_t() {
_clean_up();
}
void rtcp_payload_t::_clean_up() {
if (m_rtcp_packets) {
for (std::vector<rtcp_packet_t*>::iterator it = m_rtcp_packets->begin(); it != m_rtcp_packets->end(); ++it) {
delete *it;
}
delete m_rtcp_packets; m_rtcp_packets = 0;
}
}
rtcp_payload_t::psfb_afb_remb_packet_t::psfb_afb_remb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::psfb_afb_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_ssrc_list = 0;
f_max_total_bitrate = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::psfb_afb_remb_packet_t::_read() {
m_num_ssrc = m__io->read_u1();
m_br_exp = m__io->read_bits_int_be(6);
m_br_mantissa = m__io->read_bits_int_be(18);
m__io->align_to_byte();
m_ssrc_list = new std::vector<uint32_t>();
const int l_ssrc_list = num_ssrc();
for (int i = 0; i < l_ssrc_list; i++) {
m_ssrc_list->push_back(m__io->read_u4be());
}
}
rtcp_payload_t::psfb_afb_remb_packet_t::~psfb_afb_remb_packet_t() {
_clean_up();
}
void rtcp_payload_t::psfb_afb_remb_packet_t::_clean_up() {
if (m_ssrc_list) {
delete m_ssrc_list; m_ssrc_list = 0;
}
}
int32_t rtcp_payload_t::psfb_afb_remb_packet_t::max_total_bitrate() {
if (f_max_total_bitrate)
return m_max_total_bitrate;
m_max_total_bitrate = (br_mantissa() * (1 << br_exp()));
f_max_total_bitrate = true;
return m_max_total_bitrate;
}
rtcp_payload_t::sr_packet_t::sr_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_report_block = 0;
f_ntp = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::sr_packet_t::_read() {
m_ssrc = m__io->read_u4be();
m_ntp_msw = m__io->read_u4be();
m_ntp_lsw = m__io->read_u4be();
m_rtp_timestamp = m__io->read_u4be();
m_sender_packet_count = m__io->read_u4be();
m_sender_octet_count = m__io->read_u4be();
m_report_block = new std::vector<report_block_t*>();
const int l_report_block = _parent()->subtype();
for (int i = 0; i < l_report_block; i++) {
m_report_block->push_back(new report_block_t(m__io, this, m__root));
}
}
rtcp_payload_t::sr_packet_t::~sr_packet_t() {
_clean_up();
}
void rtcp_payload_t::sr_packet_t::_clean_up() {
if (m_report_block) {
for (std::vector<report_block_t*>::iterator it = m_report_block->begin(); it != m_report_block->end(); ++it) {
delete *it;
}
delete m_report_block; m_report_block = 0;
}
}
int32_t rtcp_payload_t::sr_packet_t::ntp() {
if (f_ntp)
return m_ntp;
m_ntp = ((ntp_msw() << 32) & ntp_lsw());
f_ntp = true;
return m_ntp;
}
rtcp_payload_t::rr_packet_t::rr_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_report_block = 0;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::rr_packet_t::_read() {
m_ssrc = m__io->read_u4be();
m_report_block = new std::vector<report_block_t*>();
const int l_report_block = _parent()->subtype();
for (int i = 0; i < l_report_block; i++) {
m_report_block->push_back(new report_block_t(m__io, this, m__root));
}
}
rtcp_payload_t::rr_packet_t::~rr_packet_t() {
_clean_up();
}
void rtcp_payload_t::rr_packet_t::_clean_up() {
if (m_report_block) {
for (std::vector<report_block_t*>::iterator it = m_report_block->begin(); it != m_report_block->end(); ++it) {
delete *it;
}
delete m_report_block; m_report_block = 0;
}
}
rtcp_payload_t::rtcp_packet_t::rtcp_packet_t(kaitai::kstream* p__io, rtcp_payload_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m__io__raw_body = 0;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::rtcp_packet_t::_read() {
m_version = m__io->read_bits_int_be(2);
m_padding = m__io->read_bits_int_be(1);
m_subtype = m__io->read_bits_int_be(5);
m__io->align_to_byte();
m_payload_type = static_cast<rtcp_payload_t::payload_type_t>(m__io->read_u1());
m_length = m__io->read_u2be();
n_body = true;
switch (payload_type()) {
case rtcp_payload_t::PAYLOAD_TYPE_SR: {
n_body = false;
m__raw_body = m__io->read_bytes((4 * length()));
m__io__raw_body = new kaitai::kstream(m__raw_body);
m_body = new sr_packet_t(m__io__raw_body, this, m__root);
break;
}
case rtcp_payload_t::PAYLOAD_TYPE_PSFB: {
n_body = false;
m__raw_body = m__io->read_bytes((4 * length()));
m__io__raw_body = new kaitai::kstream(m__raw_body);
m_body = new psfb_packet_t(m__io__raw_body, this, m__root);
break;
}
case rtcp_payload_t::PAYLOAD_TYPE_RR: {
n_body = false;
m__raw_body = m__io->read_bytes((4 * length()));
m__io__raw_body = new kaitai::kstream(m__raw_body);
m_body = new rr_packet_t(m__io__raw_body, this, m__root);
break;
}
case rtcp_payload_t::PAYLOAD_TYPE_RTPFB: {
n_body = false;
m__raw_body = m__io->read_bytes((4 * length()));
m__io__raw_body = new kaitai::kstream(m__raw_body);
m_body = new rtpfb_packet_t(m__io__raw_body, this, m__root);
break;
}
case rtcp_payload_t::PAYLOAD_TYPE_SDES: {
n_body = false;
m__raw_body = m__io->read_bytes((4 * length()));
m__io__raw_body = new kaitai::kstream(m__raw_body);
m_body = new sdes_packet_t(m__io__raw_body, this, m__root);
break;
}
default: {
m__raw_body = m__io->read_bytes((4 * length()));
break;
}
}
}
rtcp_payload_t::rtcp_packet_t::~rtcp_packet_t() {
_clean_up();
}
void rtcp_payload_t::rtcp_packet_t::_clean_up() {
if (!n_body) {
if (m__io__raw_body) {
delete m__io__raw_body; m__io__raw_body = 0;
}
if (m_body) {
delete m_body; m_body = 0;
}
}
}
rtcp_payload_t::sdes_tlv_t::sdes_tlv_t(kaitai::kstream* p__io, rtcp_payload_t::source_chunk_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::sdes_tlv_t::_read() {
m_type = static_cast<rtcp_payload_t::sdes_subtype_t>(m__io->read_u1());
n_length = true;
if (type() != rtcp_payload_t::SDES_SUBTYPE_PAD) {
n_length = false;
m_length = m__io->read_u1();
}
n_value = true;
if (type() != rtcp_payload_t::SDES_SUBTYPE_PAD) {
n_value = false;
m_value = m__io->read_bytes(length());
}
}
rtcp_payload_t::sdes_tlv_t::~sdes_tlv_t() {
_clean_up();
}
void rtcp_payload_t::sdes_tlv_t::_clean_up() {
if (!n_length) {
}
if (!n_value) {
}
}
rtcp_payload_t::report_block_t::report_block_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_fraction_lost = false;
f_cumulative_packets_lost = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::report_block_t::_read() {
m_ssrc_source = m__io->read_u4be();
m_lost_val = m__io->read_u1();
m_highest_seq_num_received = m__io->read_u4be();
m_interarrival_jitter = m__io->read_u4be();
m_lsr = m__io->read_u4be();
m_dlsr = m__io->read_u4be();
}
rtcp_payload_t::report_block_t::~report_block_t() {
_clean_up();
}
void rtcp_payload_t::report_block_t::_clean_up() {
}
int32_t rtcp_payload_t::report_block_t::fraction_lost() {
if (f_fraction_lost)
return m_fraction_lost;
m_fraction_lost = (lost_val() >> 24);
f_fraction_lost = true;
return m_fraction_lost;
}
int32_t rtcp_payload_t::report_block_t::cumulative_packets_lost() {
if (f_cumulative_packets_lost)
return m_cumulative_packets_lost;
m_cumulative_packets_lost = (lost_val() & 16777215);
f_cumulative_packets_lost = true;
return m_cumulative_packets_lost;
}
rtcp_payload_t::rtpfb_transport_feedback_packet_t::rtpfb_transport_feedback_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtpfb_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_reference_time = false;
f_fb_pkt_count = false;
f_packet_status = false;
f_recv_delta = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::rtpfb_transport_feedback_packet_t::_read() {
m_base_sequence_number = m__io->read_u2be();
m_packet_status_count = m__io->read_u2be();
m_b4 = m__io->read_u4be();
m_remaining = m__io->read_bytes_full();
}
rtcp_payload_t::rtpfb_transport_feedback_packet_t::~rtpfb_transport_feedback_packet_t() {
_clean_up();
}
void rtcp_payload_t::rtpfb_transport_feedback_packet_t::_clean_up() {
if (f_packet_status) {
}
if (f_recv_delta) {
}
}
int32_t rtcp_payload_t::rtpfb_transport_feedback_packet_t::reference_time() {
if (f_reference_time)
return m_reference_time;
m_reference_time = (b4() >> 8);
f_reference_time = true;
return m_reference_time;
}
int32_t rtcp_payload_t::rtpfb_transport_feedback_packet_t::fb_pkt_count() {
if (f_fb_pkt_count)
return m_fb_pkt_count;
m_fb_pkt_count = (b4() & 255);
f_fb_pkt_count = true;
return m_fb_pkt_count;
}
std::string rtcp_payload_t::rtpfb_transport_feedback_packet_t::packet_status() {
if (f_packet_status)
return m_packet_status;
m_packet_status = m__io->read_bytes(0);
f_packet_status = true;
return m_packet_status;
}
std::string rtcp_payload_t::rtpfb_transport_feedback_packet_t::recv_delta() {
if (f_recv_delta)
return m_recv_delta;
m_recv_delta = m__io->read_bytes(0);
f_recv_delta = true;
return m_recv_delta;
}
rtcp_payload_t::psfb_packet_t::psfb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m__io__raw_fci_block = 0;
f_fmt = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::psfb_packet_t::_read() {
m_ssrc = m__io->read_u4be();
m_ssrc_media_source = m__io->read_u4be();
n_fci_block = true;
switch (fmt()) {
case rtcp_payload_t::PSFB_SUBTYPE_AFB: {
n_fci_block = false;
m__raw_fci_block = m__io->read_bytes_full();
m__io__raw_fci_block = new kaitai::kstream(m__raw_fci_block);
m_fci_block = new psfb_afb_packet_t(m__io__raw_fci_block, this, m__root);
break;
}
default: {
m__raw_fci_block = m__io->read_bytes_full();
break;
}
}
}
rtcp_payload_t::psfb_packet_t::~psfb_packet_t() {
_clean_up();
}
void rtcp_payload_t::psfb_packet_t::_clean_up() {
if (!n_fci_block) {
if (m__io__raw_fci_block) {
delete m__io__raw_fci_block; m__io__raw_fci_block = 0;
}
if (m_fci_block) {
delete m_fci_block; m_fci_block = 0;
}
}
}
rtcp_payload_t::psfb_subtype_t rtcp_payload_t::psfb_packet_t::fmt() {
if (f_fmt)
return m_fmt;
m_fmt = static_cast<rtcp_payload_t::psfb_subtype_t>(_parent()->subtype());
f_fmt = true;
return m_fmt;
}
rtcp_payload_t::source_chunk_t::source_chunk_t(kaitai::kstream* p__io, rtcp_payload_t::sdes_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_sdes_tlv = 0;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::source_chunk_t::_read() {
m_ssrc = m__io->read_u4be();
m_sdes_tlv = new std::vector<sdes_tlv_t*>();
{
int i = 0;
while (!m__io->is_eof()) {
m_sdes_tlv->push_back(new sdes_tlv_t(m__io, this, m__root));
i++;
}
}
}
rtcp_payload_t::source_chunk_t::~source_chunk_t() {
_clean_up();
}
void rtcp_payload_t::source_chunk_t::_clean_up() {
if (m_sdes_tlv) {
for (std::vector<sdes_tlv_t*>::iterator it = m_sdes_tlv->begin(); it != m_sdes_tlv->end(); ++it) {
delete *it;
}
delete m_sdes_tlv; m_sdes_tlv = 0;
}
}
rtcp_payload_t::sdes_packet_t::sdes_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_source_chunk = 0;
f_source_count = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::sdes_packet_t::_read() {
m_source_chunk = new std::vector<source_chunk_t*>();
const int l_source_chunk = source_count();
for (int i = 0; i < l_source_chunk; i++) {
m_source_chunk->push_back(new source_chunk_t(m__io, this, m__root));
}
}
rtcp_payload_t::sdes_packet_t::~sdes_packet_t() {
_clean_up();
}
void rtcp_payload_t::sdes_packet_t::_clean_up() {
if (m_source_chunk) {
for (std::vector<source_chunk_t*>::iterator it = m_source_chunk->begin(); it != m_source_chunk->end(); ++it) {
delete *it;
}
delete m_source_chunk; m_source_chunk = 0;
}
}
uint64_t rtcp_payload_t::sdes_packet_t::source_count() {
if (f_source_count)
return m_source_count;
m_source_count = _parent()->subtype();
f_source_count = true;
return m_source_count;
}
rtcp_payload_t::rtpfb_packet_t::rtpfb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::rtcp_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m__io__raw_fci_block = 0;
f_fmt = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::rtpfb_packet_t::_read() {
m_ssrc = m__io->read_u4be();
m_ssrc_media_source = m__io->read_u4be();
n_fci_block = true;
switch (fmt()) {
case rtcp_payload_t::RTPFB_SUBTYPE_TRANSPORT_FEEDBACK: {
n_fci_block = false;
m__raw_fci_block = m__io->read_bytes_full();
m__io__raw_fci_block = new kaitai::kstream(m__raw_fci_block);
m_fci_block = new rtpfb_transport_feedback_packet_t(m__io__raw_fci_block, this, m__root);
break;
}
default: {
m__raw_fci_block = m__io->read_bytes_full();
break;
}
}
}
rtcp_payload_t::rtpfb_packet_t::~rtpfb_packet_t() {
_clean_up();
}
void rtcp_payload_t::rtpfb_packet_t::_clean_up() {
if (!n_fci_block) {
if (m__io__raw_fci_block) {
delete m__io__raw_fci_block; m__io__raw_fci_block = 0;
}
if (m_fci_block) {
delete m_fci_block; m_fci_block = 0;
}
}
}
rtcp_payload_t::rtpfb_subtype_t rtcp_payload_t::rtpfb_packet_t::fmt() {
if (f_fmt)
return m_fmt;
m_fmt = static_cast<rtcp_payload_t::rtpfb_subtype_t>(_parent()->subtype());
f_fmt = true;
return m_fmt;
}
rtcp_payload_t::packet_status_chunk_t::packet_status_chunk_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_s = false;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::packet_status_chunk_t::_read() {
m_t = m__io->read_bits_int_be(1);
n_s2 = true;
if (((t()) ? 1 : 0) == 0) {
n_s2 = false;
m_s2 = m__io->read_bits_int_be(2);
}
n_s1 = true;
if (((t()) ? 1 : 0) == 1) {
n_s1 = false;
m_s1 = m__io->read_bits_int_be(1);
}
n_rle = true;
if (((t()) ? 1 : 0) == 0) {
n_rle = false;
m_rle = m__io->read_bits_int_be(13);
}
n_symbol_list = true;
if (((t()) ? 1 : 0) == 1) {
n_symbol_list = false;
m_symbol_list = m__io->read_bits_int_be(14);
}
}
rtcp_payload_t::packet_status_chunk_t::~packet_status_chunk_t() {
_clean_up();
}
void rtcp_payload_t::packet_status_chunk_t::_clean_up() {
if (!n_s2) {
}
if (!n_s1) {
}
if (!n_rle) {
}
if (!n_symbol_list) {
}
}
int32_t rtcp_payload_t::packet_status_chunk_t::s() {
if (f_s)
return m_s;
m_s = ((((t()) ? 1 : 0) == 0) ? (s2()) : (((((s1()) ? 1 : 0) == 0) ? (1) : (0))));
f_s = true;
return m_s;
}
rtcp_payload_t::psfb_afb_packet_t::psfb_afb_packet_t(kaitai::kstream* p__io, rtcp_payload_t::psfb_packet_t* p__parent, rtcp_payload_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m__io__raw_contents = 0;
try {
_read();
} catch(...) {
_clean_up();
throw;
}
}
void rtcp_payload_t::psfb_afb_packet_t::_read() {
m_uid = m__io->read_u4be();
n_contents = true;
switch (uid()) {
case 1380273474: {
n_contents = false;
m__raw_contents = m__io->read_bytes_full();
m__io__raw_contents = new kaitai::kstream(m__raw_contents);
m_contents = new psfb_afb_remb_packet_t(m__io__raw_contents, this, m__root);
break;
}
default: {
m__raw_contents = m__io->read_bytes_full();
break;
}
}
}
rtcp_payload_t::psfb_afb_packet_t::~psfb_afb_packet_t() {
_clean_up();
}
void rtcp_payload_t::psfb_afb_packet_t::_clean_up() {
if (!n_contents) {
if (m__io__raw_contents) {
delete m__io__raw_contents; m__io__raw_contents = 0;
}
if (m_contents) {
delete m_contents; m_contents = 0;
}
}
}