| Index: webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
|
| diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
|
| index fd0219cf82076a7227cb3188d558e252856365f1..ec3b42803931bdcc566dea7c74523d50e24695ef 100644
|
| --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
|
| +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
|
| @@ -10,97 +10,69 @@
|
|
|
| #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
|
|
|
| +#include "webrtc/base/checks.h"
|
| #include "webrtc/base/logging.h"
|
| #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
|
|
| -using webrtc::RTCPUtility::PT_RTPFB;
|
| -using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN;
|
| -using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem;
|
| +using webrtc::RTCPUtility::RtcpCommonHeader;
|
|
|
| namespace webrtc {
|
| namespace rtcp {
|
| -namespace {
|
| -const uint32_t kUnusedMediaSourceSsrc0 = 0;
|
| -void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) {
|
| - buffer[(*offset)++] = value;
|
| -}
|
| -void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
|
| - ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value);
|
| - *offset += 4;
|
| -}
|
| -
|
| -void ComputeMantissaAnd6bitBase2Exponent(uint32_t input_base10,
|
| - uint8_t bits_mantissa,
|
| - uint32_t* mantissa,
|
| - uint8_t* exp) {
|
| - // input_base10 = mantissa * 2^exp
|
| - assert(bits_mantissa <= 32);
|
| - uint32_t mantissa_max = (1 << bits_mantissa) - 1;
|
| - uint8_t exponent = 0;
|
| - for (uint32_t i = 0; i < 64; ++i) {
|
| - if (input_base10 <= (mantissa_max << i)) {
|
| - exponent = i;
|
| - break;
|
| - }
|
| - }
|
| - *exp = exponent;
|
| - *mantissa = (input_base10 >> exponent);
|
| -}
|
| -
|
| -void CreateTmmbrItem(const RTCPPacketRTPFBTMMBRItem& tmmbr_item,
|
| - uint8_t* buffer,
|
| - size_t* pos) {
|
| - uint32_t bitrate_bps = tmmbr_item.MaxTotalMediaBitRate * 1000;
|
| - uint32_t mantissa = 0;
|
| - uint8_t exp = 0;
|
| - ComputeMantissaAnd6bitBase2Exponent(bitrate_bps, 17, &mantissa, &exp);
|
| -
|
| - AssignUWord32(buffer, pos, tmmbr_item.SSRC);
|
| - AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 15) & 0x03));
|
| - AssignUWord8(buffer, pos, mantissa >> 7);
|
| - AssignUWord8(buffer, pos, (mantissa << 1) +
|
| - ((tmmbr_item.MeasuredOverhead >> 8) & 0x01));
|
| - AssignUWord8(buffer, pos, tmmbr_item.MeasuredOverhead);
|
| -}
|
| -
|
| -// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
|
| -//
|
| -// FCI:
|
| +// RFC 4585: Feedback format.
|
| +// Common packet format:
|
| //
|
| // 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 (unused) = 0 |
|
| +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| +// : Feedback Control Information (FCI) :
|
| +// : :
|
| +// Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104).
|
| +// The Feedback Control Information (FCI) consists of zero, one, or more
|
| +// TMMBN FCI entries.
|
| +// 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
|
| +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| // | SSRC |
|
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| // | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
|
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| +bool Tmmbn::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
|
| + RTC_CHECK(header.packet_type == kPacketType);
|
| + RTC_CHECK(header.count_or_format == kFeedbackMessageType);
|
|
|
| -void CreateTmmbn(const RTCPPacketRTPFBTMMBN& tmmbn,
|
| - const std::vector<RTCPPacketRTPFBTMMBRItem>& tmmbn_items,
|
| - uint8_t* buffer,
|
| - size_t* pos) {
|
| - AssignUWord32(buffer, pos, tmmbn.SenderSSRC);
|
| - AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0);
|
| - for (uint8_t i = 0; i < tmmbn_items.size(); ++i) {
|
| - CreateTmmbrItem(tmmbn_items[i], buffer, pos);
|
| + if (header.payload_size_bytes < kCommonFeedbackLength) {
|
| + LOG(LS_WARNING) << "Payload length " << header.payload_size_bytes
|
| + << " is too small for TMMBN.";
|
| + return false;
|
| }
|
| -}
|
| -} // namespace
|
| -
|
| -bool Tmmbn::WithTmmbr(uint32_t ssrc, uint32_t bitrate_kbps, uint16_t overhead) {
|
| - assert(overhead <= 0x1ff);
|
| - if (tmmbn_items_.size() >= kMaxNumberOfTmmbrs) {
|
| - LOG(LS_WARNING) << "Max TMMBN size reached.";
|
| + size_t items_size_bytes = header.payload_size_bytes - kCommonFeedbackLength;
|
| + if (items_size_bytes % TmmbItem::kLength != 0) {
|
| + LOG(LS_WARNING) << "Payload length " << header.payload_size_bytes
|
| + << " is not valid for TMMBN.";
|
| return false;
|
| }
|
| - RTCPPacketRTPFBTMMBRItem tmmbn_item;
|
| - tmmbn_item.SSRC = ssrc;
|
| - tmmbn_item.MaxTotalMediaBitRate = bitrate_kbps;
|
| - tmmbn_item.MeasuredOverhead = overhead;
|
| - tmmbn_items_.push_back(tmmbn_item);
|
| + ParseCommonFeedback(payload);
|
| + const uint8_t* next_item = payload + kCommonFeedbackLength;
|
| +
|
| + size_t number_of_items = items_size_bytes / TmmbItem::kLength;
|
| + items_.resize(number_of_items);
|
| + for (TmmbItem& item : items_) {
|
| + item.Parse(next_item);
|
| + next_item += TmmbItem::kLength;
|
| + }
|
| return true;
|
| }
|
|
|
| +void Tmmbn::WithTmmbr(const TmmbItem& item) {
|
| + items_.push_back(item);
|
| +}
|
| +
|
| bool Tmmbn::Create(uint8_t* packet,
|
| size_t* index,
|
| size_t max_length,
|
| @@ -109,11 +81,19 @@ bool Tmmbn::Create(uint8_t* packet,
|
| if (!OnBufferFull(packet, index, callback))
|
| return false;
|
| }
|
| - const uint8_t kFmt = 4;
|
| - CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index);
|
| - CreateTmmbn(tmmbn_, tmmbn_items_, packet, index);
|
| + const size_t index_end = *index + BlockLength();
|
| +
|
| + CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
|
| + index);
|
| + RTC_DCHECK_EQ(0u, Rtpfb::media_ssrc());
|
| + CreateCommonFeedback(packet + *index);
|
| + *index += kCommonFeedbackLength;
|
| + for (const TmmbItem& item : items_) {
|
| + item.Create(packet + *index);
|
| + *index += TmmbItem::kLength;
|
| + }
|
| + RTC_CHECK_EQ(index_end, *index);
|
| return true;
|
| }
|
| -
|
| } // namespace rtcp
|
| } // namespace webrtc
|
|
|