Chromium Code Reviews| Index: webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc |
| diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc |
| index 4df167de79ebffc8f6597d3aa00b75ce181f50ea..a03093f5cb22ae834d9463387633534ebd3717cc 100644 |
| --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc |
| +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc |
| @@ -10,96 +10,92 @@ |
| #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.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::RTCPPacketRTPFBTMMBR; |
| -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; |
| -} |
| +// 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 Request (TMMBR) (RFC 5104). |
| +// The Feedback Control Information (FCI) for the TMMBR |
| +// consists of one or more FCI entries. |
| +// FCI: |
| +// 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 Tmmbr::Parse(const RtcpCommonHeader& header, const uint8_t* payload) { |
| + RTC_CHECK(header.packet_type == kPacketType); |
| + RTC_CHECK(header.count_or_format == kFeedbackMessageType); |
| -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; |
| - } |
| + if (header.payload_size_bytes < kCommonFeedbackLength + TmmbItem::kLength) { |
| + LOG(LS_WARNING) << "Payload length " << header.payload_size_bytes |
| + << " is too small for a TMBBR."; |
|
åsapersson
2016/02/05 11:30:18
TMBBR->TMMBR
danilchap
2016/02/05 11:38:11
oops, thank you!
|
| + return false; |
| } |
| - *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); |
| + 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 a TMBBR."; |
|
åsapersson
2016/02/05 11:30:18
TMBBR->TMMBR
danilchap
2016/02/05 11:38:11
Done.
|
| + return false; |
| + } |
| + ParseCommonFeedback(payload); |
| - 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); |
| + 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; |
| } |
| -// Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104). |
| -// |
| -// FCI: |
| -// |
| -// 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| |
| -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| - |
| -void CreateTmmbr(const RTCPPacketRTPFBTMMBR& tmmbr, |
| - const RTCPPacketRTPFBTMMBRItem& tmmbr_item, |
| - uint8_t* buffer, |
| - size_t* pos) { |
| - AssignUWord32(buffer, pos, tmmbr.SenderSSRC); |
| - AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0); |
| - CreateTmmbrItem(tmmbr_item, buffer, pos); |
| +void Tmmbr::WithTmmbr(const TmmbItem& item) { |
| + items_.push_back(item); |
| } |
| -} // namespace |
| bool Tmmbr::Create(uint8_t* packet, |
| size_t* index, |
| size_t max_length, |
| RtcpPacket::PacketReadyCallback* callback) const { |
| + RTC_DCHECK(!items_.empty()); |
| while (*index + BlockLength() > max_length) { |
| if (!OnBufferFull(packet, index, callback)) |
| return false; |
| } |
| - const uint8_t kFmt = 3; |
| - CreateHeader(kFmt, PT_RTPFB, HeaderLength(), packet, index); |
| - CreateTmmbr(tmmbr_, tmmbr_item_, 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 |