diff --git a/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp index 226248c9c..ee4201ba3 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp @@ -29,7 +29,7 @@ #include using namespace std; -SrsRtcpCommon::SrsRtcpCommon() +SrsRtcpCommon::SrsRtcpCommon(): ssrc_(0), data_(NULL), nb_data_(0) { } @@ -42,18 +42,57 @@ uint8_t SrsRtcpCommon::type() const return header_.type; } +uint8_t SrsRtcpCommon::get_rc() const +{ + return header_.rc; +} + +uint32_t SrsRtcpCommon::get_ssrc() +{ + return ssrc_; +} + +void SrsRtcpCommon::set_ssrc(uint32_t ssrc) +{ + ssrc_ = ssrc; +} + +char* SrsRtcpCommon::data() +{ + return data_; +} + +int SrsRtcpCommon::size() +{ + return nb_data_; +} + srs_error_t SrsRtcpCommon::decode_header(SrsBuffer *buffer) { + if(! buffer->require(sizeof(SrsRtcpHeader) + 4)) { + return srs_error_new(ERROR_RTC_RTCP, "require %d", sizeof(SrsRtcpHeader) + 4); + } buffer->read_bytes((char*)(&header_), sizeof(SrsRtcpHeader)); header_.length = ntohs(header_.length); + int payload_len = header_.length * 4; + if (payload_len > buffer->left()) { + return srs_error_new(ERROR_RTC_RTCP, + "require payload len=%u, buffer left=%u", payload_len, buffer->left()); + } + ssrc_ = buffer->read_4bytes(); + return srs_success; } srs_error_t SrsRtcpCommon::encode_header(SrsBuffer *buffer) { + if(! buffer->require(sizeof(SrsRtcpHeader) + 4)) { + return srs_error_new(ERROR_RTC_RTCP, "require %d", sizeof(SrsRtcpHeader) + 4); + } header_.length = htons(header_.length); buffer->write_bytes((char*)(&header_), sizeof(SrsRtcpHeader)); + buffer->write_4bytes(ssrc_); return srs_success; } @@ -61,12 +100,14 @@ srs_error_t SrsRtcpCommon::encode_header(SrsBuffer *buffer) srs_error_t SrsRtcpCommon::decode(SrsBuffer *buffer) { srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); if(srs_success != (err = decode_header(buffer))) { return srs_error_wrap(err, "decode header"); } - payload_len_ = (header_.length + 1) * 4 - sizeof(SrsRtcpHeader); + payload_len_ = (header_.length + 1) * 4 - sizeof(SrsRtcpHeader) - 4; buffer->read_bytes((char *)payload_, payload_len_); return err; @@ -74,7 +115,7 @@ srs_error_t SrsRtcpCommon::decode(SrsBuffer *buffer) int SrsRtcpCommon::nb_bytes() { - return sizeof(SrsRtcpHeader) + payload_len_; + return sizeof(SrsRtcpHeader) + 4 + payload_len_; } srs_error_t SrsRtcpCommon::encode(SrsBuffer *buffer) @@ -82,8 +123,9 @@ srs_error_t SrsRtcpCommon::encode(SrsBuffer *buffer) return srs_error_new(ERROR_RTC_RTCP, "not implement"); } -SrsRtcpApp::SrsRtcpApp():ssrc_(0) +SrsRtcpApp::SrsRtcpApp() { + ssrc_ = 0; header_.padding = 0; header_.type = SrsRtcpType_app; header_.rc = 0; @@ -115,11 +157,6 @@ uint8_t SrsRtcpApp::type() const return SrsRtcpType_app; } -uint32_t SrsRtcpApp::get_ssrc() const -{ - return ssrc_; -} - uint8_t SrsRtcpApp::get_subtype() const { return header_.rc; @@ -177,29 +214,41 @@ srs_error_t SrsRtcpApp::set_payload(uint8_t* payload, int len) return srs_success; } -void SrsRtcpApp::set_ssrc(uint32_t ssrc) -{ - ssrc_ = ssrc; -} - srs_error_t SrsRtcpApp::decode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/rfc3550#section-6.7 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| subtype | PT=APP=204 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC/CSRC | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | name (ASCII) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | application-dependent data ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); if(srs_success != (err = decode_header(buffer))) { return srs_error_wrap(err, "decode header"); } - if (header_.type != SrsRtcpType_app || !buffer->require(8)) { + if (header_.type != SrsRtcpType_app || !buffer->require(4)) { return srs_error_new(ERROR_RTC_RTCP, "not rtcp app"); } - ssrc_ = buffer->read_4bytes(); buffer->read_bytes((char *)name_, sizeof(name_)); // TODO: FIXME: Should check size? - payload_len_ = (header_.length + 1) * 4 - sizeof(SrsRtcpHeader) - sizeof(name_) - sizeof(ssrc_); - buffer->read_bytes((char *)payload_, payload_len_); + payload_len_ = (header_.length + 1) * 4 - 8 - sizeof(name_); + if (payload_len_ > 0) { + buffer->read_bytes((char *)payload_, payload_len_); + } return srs_success; } @@ -211,6 +260,20 @@ int SrsRtcpApp::nb_bytes() srs_error_t SrsRtcpApp::encode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/rfc3550#section-6.7 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| subtype | PT=APP=204 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC/CSRC | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | name (ASCII) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | application-dependent data ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; if(!buffer->require(nb_bytes())) { @@ -221,7 +284,6 @@ srs_error_t SrsRtcpApp::encode(SrsBuffer *buffer) return srs_error_wrap(err, "encode header"); } - buffer->write_4bytes(ssrc_); buffer->write_bytes((char*)name_, sizeof(name_)); buffer->write_bytes((char*)payload_, payload_len_); @@ -251,11 +313,6 @@ uint8_t SrsRtcpSR::type() const return SrsRtcpType_sr; } -uint32_t SrsRtcpSR::get_sender_ssrc() const -{ - return sender_ssrc_; -} - uint64_t SrsRtcpSR::get_ntp() const { return ntp_; @@ -276,11 +333,6 @@ uint32_t SrsRtcpSR::get_rtp_send_bytes() const return send_rtp_bytes_; } -void SrsRtcpSR::set_sender_ssrc(uint32_t ssrc) -{ - sender_ssrc_ = ssrc; -} - void SrsRtcpSR::set_ntp(uint64_t ntp) { ntp_ = ntp; @@ -303,13 +355,51 @@ void SrsRtcpSR::set_rtp_send_bytes(uint32_t bytes) srs_error_t SrsRtcpSR::decode(SrsBuffer *buffer) { + /* @doc: https://tools.ietf.org/html/rfc3550#section-6.4.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +header |V=2|P| RC | PT=SR=200 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of sender | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +sender | NTP timestamp, most significant word | +info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | NTP timestamp, least significant word | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | sender's packet count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | sender's octet count | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_1 (SSRC of first source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 1 | fraction lost | cumulative number of packets lost | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | extended highest sequence number received | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | interarrival jitter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | last SR (LSR) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | delay since last SR (DLSR) | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_2 (SSRC of second source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 2 : ... : + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | profile-specific extensions | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); if(srs_success != (err = decode_header(buffer))) { return srs_error_wrap(err, "decode header"); } - sender_ssrc_ = buffer->read_4bytes(); ntp_ = buffer->read_8bytes(); rtp_ts_ = buffer->read_4bytes(); send_rtp_packets_ = buffer->read_4bytes(); @@ -331,7 +421,43 @@ int SrsRtcpSR::nb_bytes() srs_error_t SrsRtcpSR::encode(SrsBuffer *buffer) { srs_error_t err = srs_success; - + /* @doc: https://tools.ietf.org/html/rfc3550#section-6.4.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +header |V=2|P| RC | PT=SR=200 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of sender | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +sender | NTP timestamp, most significant word | +info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | NTP timestamp, least significant word | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | sender's packet count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | sender's octet count | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_1 (SSRC of first source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 1 | fraction lost | cumulative number of packets lost | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | extended highest sequence number received | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | interarrival jitter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | last SR (LSR) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | delay since last SR (DLSR) | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_2 (SSRC of second source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 2 : ... : + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | profile-specific extensions | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ if(!buffer->require(nb_bytes())) { return srs_error_new(ERROR_RTC_RTCP, "requires %d bytes", nb_bytes()); } @@ -340,7 +466,6 @@ srs_error_t SrsRtcpSR::encode(SrsBuffer *buffer) return srs_error_wrap(err, "encode header"); } - buffer->write_4bytes(sender_ssrc_); buffer->write_8bytes(ntp_); buffer->write_4bytes(rtp_ts_); buffer->write_4bytes(send_rtp_packets_); @@ -349,13 +474,14 @@ srs_error_t SrsRtcpSR::encode(SrsBuffer *buffer) return err; } -SrsRtcpRR::SrsRtcpRR(uint32_t sender_ssrc): sender_ssrc_(sender_ssrc) +SrsRtcpRR::SrsRtcpRR(uint32_t sender_ssrc) { header_.padding = 0; header_.type = SrsRtcpType_rr; header_.rc = 0; header_.version = kRtcpVersion; header_.length = 7; + ssrc_ = sender_ssrc; } SrsRtcpRR::~SrsRtcpRR() @@ -445,13 +571,43 @@ void SrsRtcpRR::set_sender_ntp(uint64_t ntp) srs_error_t SrsRtcpRR::decode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/rfc3550#section-6.4.2 + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +header |V=2|P| RC | PT=RR=201 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_1 (SSRC of first source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 1 | fraction lost | cumulative number of packets lost | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | extended highest sequence number received | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | interarrival jitter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | last SR (LSR) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | delay since last SR (DLSR) | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_2 (SSRC of second source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 2 : ... : + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | profile-specific extensions | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); if(srs_success != (err = decode_header(buffer))) { return srs_error_wrap(err, "decode header"); } - sender_ssrc_ = buffer->read_4bytes(); if(header_.rc < 1) { return err; } @@ -478,6 +634,35 @@ int SrsRtcpRR::nb_bytes() srs_error_t SrsRtcpRR::encode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/rfc3550#section-6.4.2 + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +header |V=2|P| RC | PT=RR=201 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_1 (SSRC of first source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 1 | fraction lost | cumulative number of packets lost | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | extended highest sequence number received | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | interarrival jitter | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | last SR (LSR) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | delay since last SR (DLSR) | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +report | SSRC_2 (SSRC of second source) | +block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 2 : ... : + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | profile-specific extensions | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; if(!buffer->require(nb_bytes())) { @@ -488,7 +673,6 @@ srs_error_t SrsRtcpRR::encode(SrsBuffer *buffer) if(srs_success != (err = encode_header(buffer))) { return srs_error_wrap(err, "encode header"); } - buffer->write_4bytes(sender_ssrc_); buffer->write_4bytes(rb_.ssrc); buffer->write_1bytes(rb_.fraction_lost); @@ -506,14 +690,15 @@ SrsRtcpTWCC::SrsRtcpTWCCChunk::SrsRtcpTWCCChunk() { } -SrsRtcpTWCC::SrsRtcpTWCC(uint32_t sender_ssrc) : sender_ssrc_(sender_ssrc), pkt_len(0) +SrsRtcpTWCC::SrsRtcpTWCC(uint32_t sender_ssrc) : pkt_len(0) { header_.padding = 0; header_.type = SrsRtcpType_rtpfb; header_.rc = 15; header_.version = kRtcpVersion; + ssrc_ = sender_ssrc; } - + SrsRtcpTWCC::~SrsRtcpTWCC() { } @@ -609,8 +794,50 @@ srs_error_t SrsRtcpTWCC::recv_packet(uint16_t sn, srs_utime_t ts) srs_error_t SrsRtcpTWCC::decode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT=15 | PT=205 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | base sequence number | packet status count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | reference time | fb pkt. count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | packet chunk | packet chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | packet chunk | recv delta | recv delta | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | recv delta | recv delta | zero padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; - + data_ = buffer->head(); + nb_data_ = buffer->left(); + + uint16_t base_sn_; + uint16_t packet_count_; + int32_t reference_time_; + uint8_t fb_pkt_count_; + + if(srs_success != (err = decode_header(buffer))) { + return srs_error_wrap(err, "decode header"); + } + + payload_len_ = (header_.length + 1) * 4 - sizeof(SrsRtcpHeader) - 4; + buffer->read_bytes((char *)payload_, payload_len_); + return err; } @@ -815,6 +1042,34 @@ srs_error_t SrsRtcpTWCC::encode(SrsBuffer *buffer) srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT=15 | PT=205 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | base sequence number | packet status count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | reference time | fb pkt. count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | packet chunk | packet chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | packet chunk | recv delta | recv delta | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | recv delta | recv delta | zero padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; if(!buffer->require(nb_bytes())) { @@ -880,7 +1135,6 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) if(srs_success != (err = encode_header(buffer))) { return srs_error_wrap(err, "encode header"); } - buffer->write_4bytes(sender_ssrc_); buffer->write_4bytes(media_ssrc_); buffer->write_2bytes(base_sn_); buffer->write_2bytes(packet_count_); @@ -908,12 +1162,13 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) return err; } -SrsRtcpNack::SrsRtcpNack(uint32_t sender_ssrc): sender_ssrc_(sender_ssrc) +SrsRtcpNack::SrsRtcpNack(uint32_t sender_ssrc) { header_.padding = 0; header_.type = SrsRtcpType_rtpfb; header_.rc = 1; header_.version = kRtcpVersion; + ssrc_ = sender_ssrc; } SrsRtcpNack::~SrsRtcpNack() @@ -946,13 +1201,35 @@ void SrsRtcpNack::add_lost_sn(uint16_t sn) srs_error_t SrsRtcpNack::decode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/rfc4585#section-6.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT | PT | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : Feedback Control Information (FCI) : + : : + + Generic NACK + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | PID | BLP | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); if(srs_success != (err = decode_header(buffer))) { return srs_error_wrap(err, "decode header"); } - sender_ssrc_ = buffer->read_4bytes(); media_ssrc_ = buffer->read_4bytes(); char bitmask[20]; for(int i = 0; i < (header_.length - 2); i++) { @@ -978,6 +1255,27 @@ int SrsRtcpNack::nb_bytes() srs_error_t SrsRtcpNack::encode(SrsBuffer *buffer) { + /* + @doc: https://tools.ietf.org/html/rfc4585#section-6.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT | PT | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : Feedback Control Information (FCI) : + : : + + Generic NACK + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | PID | BLP | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ srs_error_t err = srs_success; if(!buffer->require(nb_bytes())) { return srs_error_new(ERROR_RTC_RTCP, "requires %d bytes", nb_bytes()); @@ -1016,7 +1314,7 @@ srs_error_t SrsRtcpNack::encode(SrsBuffer *buffer) err = srs_error_wrap(err, "encode header"); break; } - buffer->write_4bytes(sender_ssrc_); + buffer->write_4bytes(media_ssrc_); for(vector::iterator it_chunk = chunks.begin(); it_chunk != chunks.end(); it_chunk++) { buffer->write_2bytes(it_chunk->pid); @@ -1027,7 +1325,333 @@ srs_error_t SrsRtcpNack::encode(SrsBuffer *buffer) return err; } -SrsRtcpCompound::SrsRtcpCompound(): nb_bytes_(0) +SrsRtcpPsfbCommon::SrsRtcpPsfbCommon() +{ + header_.padding = 0; + header_.type = SrsRtcpType_psfb; + header_.rc = 1; + header_.version = kRtcpVersion; + //ssrc_ = sender_ssrc; +} + +SrsRtcpPsfbCommon::~SrsRtcpPsfbCommon() +{ + +} + +uint32_t SrsRtcpPsfbCommon::get_media_ssrc() const +{ + return media_ssrc_; +} + +void SrsRtcpPsfbCommon::set_media_ssrc(uint32_t ssrc) +{ + media_ssrc_ = ssrc; +} + +srs_error_t SrsRtcpPsfbCommon::decode(SrsBuffer *buffer) +{ + /* + @doc: https://tools.ietf.org/html/rfc4585#section-6.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT | PT | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : Feedback Control Information (FCI) : + : : + */ + + srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); + + if(srs_success != (err = decode_header(buffer))) { + return srs_error_wrap(err, "decode header"); + } + + media_ssrc_ = buffer->read_4bytes(); + int len = (header_.length + 1) * 4 - 12; + buffer->skip(len); + return err; +} + +int SrsRtcpPsfbCommon::nb_bytes() +{ + return kRtcpPacketSize; +} + +srs_error_t SrsRtcpPsfbCommon::encode(SrsBuffer *buffer) +{ + return srs_error_new(ERROR_RTC_RTCP, "not support"); +} + +SrsRtcpPli::SrsRtcpPli(uint32_t sender_ssrc/*= 0*/) +{ + header_.padding = 0; + header_.type = SrsRtcpType_psfb; + header_.rc = kPLI; + header_.version = kRtcpVersion; + ssrc_ = sender_ssrc; +} + +SrsRtcpPli::~SrsRtcpPli() +{ +} + +srs_error_t SrsRtcpPli::decode(SrsBuffer *buffer) +{ + /* + @doc: https://tools.ietf.org/html/rfc4585#section-6.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT | PT | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : Feedback Control Information (FCI) : + : : + */ + + srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); + + if(srs_success != (err = decode_header(buffer))) { + return srs_error_wrap(err, "decode header"); + } + + media_ssrc_ = buffer->read_4bytes(); + return err; +} + +int SrsRtcpPli::nb_bytes() +{ + return 12; +} + +srs_error_t SrsRtcpPli::encode(SrsBuffer *buffer) +{ + /* + @doc: https://tools.ietf.org/html/rfc4585#section-6.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT | PT | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : Feedback Control Information (FCI) : + : : + */ + srs_error_t err = srs_success; + if(!buffer->require(nb_bytes())) { + return srs_error_new(ERROR_RTC_RTCP, "requires %d bytes", nb_bytes()); + } + + header_.length = 2; + if(srs_success != (err = encode_header(buffer))) { + return srs_error_wrap(err, "encode header"); + } + + buffer->write_4bytes(media_ssrc_); + + return err; +} + +SrsRtcpSli::SrsRtcpSli(uint32_t sender_ssrc/*= 0*/) +{ + header_.padding = 0; + header_.type = SrsRtcpType_psfb; + header_.rc = kSLI; + header_.version = kRtcpVersion; + ssrc_ = sender_ssrc; +} + +SrsRtcpSli::~SrsRtcpSli() +{ +} + + +srs_error_t SrsRtcpSli::decode(SrsBuffer *buffer) +{ + /* + @doc: https://tools.ietf.org/html/rfc4585#section-6.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT | PT | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : Feedback Control Information (FCI) : + : : + + + @doc: https://tools.ietf.org/html/rfc4585#section-6.3.2 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | First | Number | PictureID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); + + if(srs_success != (err = decode_header(buffer))) { + return srs_error_wrap(err, "decode header"); + } + + media_ssrc_ = buffer->read_4bytes(); + int len = (header_.length + 1) * 4 - 12; + buffer->skip(len); + return err; +} + +int SrsRtcpSli::nb_bytes() +{ + return kRtcpPacketSize; +} + +srs_error_t SrsRtcpSli::encode(SrsBuffer *buffer) +{ + srs_error_t err = srs_success; + + return err; +} + +SrsRtcpRpsi::SrsRtcpRpsi(uint32_t sender_ssrc/* = 0*/) +{ + header_.padding = 0; + header_.type = SrsRtcpType_psfb; + header_.rc = kRPSI; + header_.version = kRtcpVersion; + ssrc_ = sender_ssrc; +} + +SrsRtcpRpsi::~SrsRtcpRpsi() +{ + +} + +srs_error_t SrsRtcpRpsi::decode(SrsBuffer *buffer) +{ +/* + @doc: https://tools.ietf.org/html/rfc4585#section-6.1 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P| FMT | PT | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of packet sender | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC of media source | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : Feedback Control Information (FCI) : + : : + + + @doc: https://tools.ietf.org/html/rfc4585#section-6.3.3 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | PB |0| Payload Type| Native RPSI bit string | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | defined per codec ... | Padding (0) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); + + if(srs_success != (err = decode_header(buffer))) { + return srs_error_wrap(err, "decode header"); + } + + media_ssrc_ = buffer->read_4bytes(); + int len = (header_.length + 1) * 4 - 12; + buffer->skip(len); + return err; +} + +int SrsRtcpRpsi::nb_bytes() +{ + return kRtcpPacketSize; +} + +srs_error_t SrsRtcpRpsi::encode(SrsBuffer *buffer) +{ + srs_error_t err = srs_success; + + return err; +} + +SrsRtcpXr::SrsRtcpXr(uint32_t ssrc/*= 0*/) +{ + header_.padding = 0; + header_.type = SrsRtcpType_xr; + header_.rc = 0; + header_.version = kRtcpVersion; + ssrc_ = ssrc; +} + +SrsRtcpXr::~SrsRtcpXr() +{ +} + +srs_error_t SrsRtcpXr::decode(SrsBuffer *buffer) +{ +/* + @doc: https://tools.ietf.org/html/rfc3611#section-2 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|reserved | PT=XR=207 | length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SSRC | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : report blocks : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + srs_error_t err = srs_success; + data_ = buffer->head(); + nb_data_ = buffer->left(); + + if(srs_success != (err = decode_header(buffer))) { + return srs_error_wrap(err, "decode header"); + } + + int len = (header_.length + 1) * 4 - 8; + buffer->skip(len); + return err; +} + +int SrsRtcpXr::nb_bytes() +{ + return kRtcpPacketSize; +} + +srs_error_t SrsRtcpXr::encode(SrsBuffer *buffer) +{ + return srs_error_new(ERROR_RTC_RTCP, "not support"); +} + +SrsRtcpCompound::SrsRtcpCompound(): nb_bytes_(0), data_(NULL), nb_data_(0) { } @@ -1042,7 +1666,6 @@ SrsRtcpCommon* SrsRtcpCompound::get_next_rtcp() return NULL; } SrsRtcpCommon *rtcp = rtcps_.back(); - nb_bytes_ -= rtcp->nb_bytes(); rtcps_.pop_back(); return rtcp; } @@ -1062,31 +1685,48 @@ srs_error_t SrsRtcpCompound::add_rtcp(SrsRtcpCommon *rtcp) srs_error_t SrsRtcpCompound::decode(SrsBuffer *buffer) { srs_error_t err = srs_success; + data_ = buffer->data(); + nb_data_ = buffer->size(); - while (buffer->empty()) { + while (!buffer->empty()) { + SrsRtcpCommon* rtcp = NULL; SrsRtcpHeader* header = (SrsRtcpHeader*)(buffer->head()); if (header->type == SrsRtcpType_sr) { - SrsRtcpSR *rtcp = new SrsRtcpSR; - if(srs_success != (err = rtcp->decode(buffer))) { - return srs_error_wrap(err, "decode sr"); - } - nb_bytes_ += rtcp->nb_bytes(); - rtcps_.push_back(rtcp); + rtcp = new SrsRtcpSR(); } else if (header->type == SrsRtcpType_rr) { - SrsRtcpRR *rtcp = new SrsRtcpRR; - if(srs_success != (err = rtcp->decode(buffer))) { - return srs_error_wrap(err, "decode rr"); + rtcp = new SrsRtcpRR(); + } else if (header->type == SrsRtcpType_rtpfb) { + if(1 == header->rc) { + //nack + rtcp = new SrsRtcpNack(); + } else if (15 == header->rc) { + //twcc + rtcp = new SrsRtcpTWCC(); } - nb_bytes_ += rtcp->nb_bytes(); - rtcps_.push_back(rtcp); + } else if(header->type == SrsRtcpType_psfb) { + if(1 == header->rc) { + // pli + rtcp = new SrsRtcpPli(); + } else if(2 == header->rc) { + //sli + rtcp = new SrsRtcpSli(); + } else if(3 == header->rc) { + //rpsi + rtcp = new SrsRtcpRpsi(); + } else { + // common psfb + rtcp = new SrsRtcpPsfbCommon(); + } + } else if(header->type == SrsRtcpType_xr) { + rtcp = new SrsRtcpXr(); } else { - SrsRtcpCommon *rtcp = new SrsRtcpCommon; - if(srs_success != (err = rtcp->decode(buffer))) { - return srs_error_wrap(err, "decode type: %#x", header->type); - } - nb_bytes_ += rtcp->nb_bytes(); - rtcps_.push_back(rtcp); + rtcp = new SrsRtcpCommon(); } + if(srs_success != (err = rtcp->decode(buffer))) { + srs_freep(rtcp); + return srs_error_wrap(err, "decode rtcp type=%u rc=%u", header->type, header->rc); + } + rtcps_.push_back(rtcp); } return err; @@ -1094,7 +1734,7 @@ srs_error_t SrsRtcpCompound::decode(SrsBuffer *buffer) int SrsRtcpCompound::nb_bytes() { - return nb_bytes_; + return kRtcpPacketSize; } srs_error_t SrsRtcpCompound::encode(SrsBuffer *buffer) @@ -1127,3 +1767,14 @@ void SrsRtcpCompound::clear() rtcps_.clear(); nb_bytes_ = 0; } + +char* SrsRtcpCompound::data() +{ + return data_; +} + +int SrsRtcpCompound::size() +{ + return nb_data_; +} + diff --git a/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp index c65c656ce..b2f7c03ba 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp @@ -50,6 +50,12 @@ enum SrsRtcpType SrsRtcpType_xr = 207, }; +// @see: https://tools.ietf.org/html/rfc4585#section-6.3 +const uint8_t kPLI = 1; +const uint8_t kSLI = 2; +const uint8_t kRPSI = 3; +const uint8_t kAFB = 15; + // RTCP Header, @see http://tools.ietf.org/html/rfc3550#section-6.1 // @remark The header must be 4 bytes, which align with the max field size 2B. struct SrsRtcpHeader @@ -66,8 +72,12 @@ class SrsRtcpCommon: public ISrsCodec { protected: SrsRtcpHeader header_; + uint32_t ssrc_; uint8_t payload_[kRtcpPacketSize]; int payload_len_; + + char* data_; + int nb_data_; protected: srs_error_t decode_header(SrsBuffer *buffer); srs_error_t encode_header(SrsBuffer *buffer); @@ -75,6 +85,13 @@ public: SrsRtcpCommon(); virtual ~SrsRtcpCommon(); virtual uint8_t type() const; + virtual uint8_t get_rc() const; + + uint32_t get_ssrc(); + void set_ssrc(uint32_t ssrc); + + char* data(); + int size(); // interface ISrsCodec public: virtual srs_error_t decode(SrsBuffer *buffer); @@ -85,7 +102,6 @@ public: class SrsRtcpApp : public SrsRtcpCommon { private: - uint32_t ssrc_; uint8_t name_[4]; public: SrsRtcpApp(); @@ -95,12 +111,10 @@ public: virtual uint8_t type() const; - uint32_t get_ssrc() const; uint8_t get_subtype() const; std::string get_name() const; srs_error_t get_payload(uint8_t*& payload, int& len); - void set_ssrc(uint32_t ssrc); srs_error_t set_subtype(uint8_t type); srs_error_t set_name(std::string name); srs_error_t set_payload(uint8_t* payload, int len); @@ -125,11 +139,11 @@ struct SrsRtcpRB class SrsRtcpSR : 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: SrsRtcpSR(); virtual ~SrsRtcpSR(); @@ -137,13 +151,11 @@ public: uint8_t get_rc() const; // overload SrsRtcpCommon virtual uint8_t type() const; - uint32_t get_sender_ssrc() const; uint64_t get_ntp() const; uint32_t get_rtp_ts() const; uint32_t get_rtp_send_packets() 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); @@ -158,7 +170,6 @@ public: class SrsRtcpRR : public SrsRtcpCommon { private: - uint32_t sender_ssrc_; SrsRtcpRB rb_; public: SrsRtcpRR(uint32_t sender_ssrc = 0); @@ -235,7 +246,6 @@ public: class SrsRtcpTWCC : public SrsRtcpCommon { private: - uint32_t sender_ssrc_; uint32_t media_ssrc_; uint16_t base_sn_; uint16_t packet_count_; @@ -289,6 +299,7 @@ public: void add_recv_delta(uint16_t delta); srs_error_t recv_packet(uint16_t sn, srs_utime_t ts); + // interface ISrsCodec public: virtual srs_error_t decode(SrsBuffer *buffer); @@ -307,7 +318,6 @@ private: bool in_use; }; - uint32_t sender_ssrc_; uint32_t media_ssrc_; std::set lost_sns_; public: @@ -326,11 +336,93 @@ public: virtual srs_error_t encode(SrsBuffer *buffer); }; +class SrsRtcpPsfbCommon : public SrsRtcpCommon +{ +protected: + uint32_t media_ssrc_; +public: + SrsRtcpPsfbCommon(); + virtual ~SrsRtcpPsfbCommon(); + + uint32_t get_media_ssrc() const; + void set_media_ssrc(uint32_t ssrc); + +// interface ISrsCodec +public: + virtual srs_error_t decode(SrsBuffer *buffer); + virtual int nb_bytes(); + virtual srs_error_t encode(SrsBuffer *buffer); +}; + +class SrsRtcpPli : public SrsRtcpPsfbCommon +{ +public: + SrsRtcpPli(uint32_t sender_ssrc = 0); + virtual ~SrsRtcpPli(); + +// interface ISrsCodec +public: + virtual srs_error_t decode(SrsBuffer *buffer); + virtual int nb_bytes(); + virtual srs_error_t encode(SrsBuffer *buffer); +}; + +class SrsRtcpSli : public SrsRtcpPsfbCommon +{ +private: + uint16_t first_; + uint16_t number_; + uint8_t picture_; +public: + SrsRtcpSli(uint32_t sender_ssrc = 0); + virtual ~SrsRtcpSli(); + + // interface ISrsCodec +public: + virtual srs_error_t decode(SrsBuffer *buffer); + virtual int nb_bytes(); + virtual srs_error_t encode(SrsBuffer *buffer); +}; + +class SrsRtcpRpsi : public SrsRtcpPsfbCommon +{ +private: + uint8_t pb_; + uint8_t payload_type_; + char* native_rpsi_; + int nb_native_rpsi_; + +public: + SrsRtcpRpsi(uint32_t sender_ssrc = 0); + virtual ~SrsRtcpRpsi(); + + // interface ISrsCodec +public: + virtual srs_error_t decode(SrsBuffer *buffer); + virtual int nb_bytes(); + virtual srs_error_t encode(SrsBuffer *buffer); +}; + +class SrsRtcpXr : public SrsRtcpCommon +{ +public: + SrsRtcpXr (uint32_t ssrc = 0); + virtual ~SrsRtcpXr(); + + // interface ISrsCodec +public: + 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 rtcps_; int nb_bytes_; + char* data_; + int nb_data_; public: SrsRtcpCompound(); virtual ~SrsRtcpCompound(); @@ -338,6 +430,10 @@ public: SrsRtcpCommon* get_next_rtcp(); srs_error_t add_rtcp(SrsRtcpCommon *rtcp); void clear(); + + char* data(); + int size(); + // interface ISrsCodec public: virtual srs_error_t decode(SrsBuffer *buffer);