tmmbn.cc (4303B)
1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbn.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 16 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h" 17 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h" 18 #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" 19 #include "rtc_base/checks.h" 20 #include "rtc_base/logging.h" 21 22 namespace webrtc { 23 namespace rtcp { 24 // RFC 4585: Feedback format. 25 // Common packet format: 26 // 27 // 0 1 2 3 28 // 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 29 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 30 // |V=2|P| FMT | PT | length | 31 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 // | SSRC of packet sender | 33 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 34 // | SSRC of media source (unused) = 0 | 35 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 36 // : Feedback Control Information (FCI) : 37 // : : 38 // Temporary Maximum Media Stream Bit Rate Notification (TMMBN) (RFC 5104). 39 // The Feedback Control Information (FCI) consists of zero, one, or more 40 // TMMBN FCI entries. 41 // 0 1 2 3 42 // 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 43 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 44 // | SSRC | 45 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 46 // | MxTBR Exp | MxTBR Mantissa |Measured Overhead| 47 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 48 49 Tmmbn::Tmmbn() = default; 50 51 Tmmbn::~Tmmbn() = default; 52 53 bool Tmmbn::Parse(const CommonHeader& packet) { 54 RTC_DCHECK_EQ(packet.type(), kPacketType); 55 RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType); 56 57 if (packet.payload_size_bytes() < kCommonFeedbackLength) { 58 RTC_LOG(LS_WARNING) << "Payload length " << packet.payload_size_bytes() 59 << " is too small for TMMBN."; 60 return false; 61 } 62 size_t items_size_bytes = packet.payload_size_bytes() - kCommonFeedbackLength; 63 if (items_size_bytes % TmmbItem::kLength != 0) { 64 RTC_LOG(LS_WARNING) << "Payload length " << packet.payload_size_bytes() 65 << " is not valid for TMMBN."; 66 return false; 67 } 68 ParseCommonFeedback(packet.payload()); 69 const uint8_t* next_item = packet.payload() + kCommonFeedbackLength; 70 71 size_t number_of_items = items_size_bytes / TmmbItem::kLength; 72 items_.resize(number_of_items); 73 for (TmmbItem& item : items_) { 74 if (!item.Parse(next_item)) 75 return false; 76 next_item += TmmbItem::kLength; 77 } 78 return true; 79 } 80 81 void Tmmbn::AddTmmbr(const TmmbItem& item) { 82 items_.push_back(item); 83 } 84 85 size_t Tmmbn::BlockLength() const { 86 return kHeaderLength + kCommonFeedbackLength + 87 TmmbItem::kLength * items_.size(); 88 } 89 90 bool Tmmbn::Create(uint8_t* packet, 91 size_t* index, 92 size_t max_length, 93 PacketReadyCallback callback) const { 94 while (*index + BlockLength() > max_length) { 95 if (!OnBufferFull(packet, index, callback)) 96 return false; 97 } 98 const size_t index_end = *index + BlockLength(); 99 100 CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet, 101 index); 102 RTC_DCHECK_EQ(0, Rtpfb::media_ssrc()); 103 CreateCommonFeedback(packet + *index); 104 *index += kCommonFeedbackLength; 105 for (const TmmbItem& item : items_) { 106 item.Create(packet + *index); 107 *index += TmmbItem::kLength; 108 } 109 RTC_CHECK_EQ(index_end, *index); 110 return true; 111 } 112 } // namespace rtcp 113 } // namespace webrtc