rtcp network payload (single udp packet): C++98/STL parsing library

RTCP is the Real-Time Control Protocol

KS implementation details

License: CC0-1.0
Minimal Kaitai Struct required: 0.7

References

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.

Usage

Runtime 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.

Code

Using Kaitai Struct in C++/STL usually consists of 3 steps.

  1. We need to create an STL input stream (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);
    
  2. We need to wrap our input stream into Kaitai stream:
    #include "kaitai/kaitaistream.h"
    
    kaitai::kstream ks(&is);
    
  3. And finally, we can invoke the parsing:
    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

C++98/STL source code to parse rtcp network payload (single udp packet)

rtcp_payload.h

#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_

rtcp_payload.cpp

// 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;
        }
    }
}