• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2015 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 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
12 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
13 
14 #include <array>
15 #include <memory>
16 #include <vector>
17 
18 #include "absl/base/attributes.h"
19 #include "api/units/time_delta.h"
20 #include "api/units/timestamp.h"
21 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
22 
23 namespace webrtc {
24 namespace rtcp {
25 class CommonHeader;
26 
27 class TransportFeedback : public Rtpfb {
28  public:
29   class ReceivedPacket {
30    public:
ReceivedPacket(uint16_t sequence_number,int16_t delta_ticks)31     ReceivedPacket(uint16_t sequence_number, int16_t delta_ticks)
32         : sequence_number_(sequence_number),
33           delta_ticks_(delta_ticks),
34           received_(true) {}
ReceivedPacket(uint16_t sequence_number)35     explicit ReceivedPacket(uint16_t sequence_number)
36         : sequence_number_(sequence_number), received_(false) {}
37     ReceivedPacket(const ReceivedPacket&) = default;
38     ReceivedPacket& operator=(const ReceivedPacket&) = default;
39 
sequence_number()40     uint16_t sequence_number() const { return sequence_number_; }
delta_ticks()41     int16_t delta_ticks() const { return delta_ticks_; }
delta()42     TimeDelta delta() const { return delta_ticks_ * kDeltaTick; }
received()43     bool received() const { return received_; }
44 
45    private:
46     uint16_t sequence_number_;
47     int16_t delta_ticks_;
48     bool received_;
49   };
50   // TODO(sprang): IANA reg?
51   static constexpr uint8_t kFeedbackMessageType = 15;
52   // Convert to multiples of 0.25ms.
53   static constexpr TimeDelta kDeltaTick = TimeDelta::Micros(250);
54   // Maximum number of packets (including missing) TransportFeedback can report.
55   static constexpr size_t kMaxReportedPackets = 0xffff;
56 
57   TransportFeedback();
58 
59   // If `include_timestamps` is set to false, the created packet will not
60   // contain the receive delta block.
61   explicit TransportFeedback(bool include_timestamps,
62                              bool include_lost = false);
63   TransportFeedback(const TransportFeedback&);
64   TransportFeedback(TransportFeedback&&);
65 
66   ~TransportFeedback() override;
67 
68   void SetBase(uint16_t base_sequence,    // Seq# of first packet in this msg.
69                Timestamp ref_timestamp);  // Reference timestamp for this msg.
70 
71   void SetFeedbackSequenceNumber(uint8_t feedback_sequence);
72   // NOTE: This method requires increasing sequence numbers (excepting wraps).
73   bool AddReceivedPacket(uint16_t sequence_number, Timestamp timestamp);
74   const std::vector<ReceivedPacket>& GetReceivedPackets() const;
75   const std::vector<ReceivedPacket>& GetAllPackets() const;
76 
77   uint16_t GetBaseSequence() const;
78 
79   // Returns number of packets (including missing) this feedback describes.
GetPacketStatusCount()80   size_t GetPacketStatusCount() const { return num_seq_no_; }
81 
82   // Get the reference time including any precision loss.
83   Timestamp BaseTime() const;
84 
85   // Get the unwrapped delta between current base time and `prev_timestamp`.
86   TimeDelta GetBaseDelta(Timestamp prev_timestamp) const;
87 
88   // Does the feedback packet contain timestamp information?
IncludeTimestamps()89   bool IncludeTimestamps() const { return include_timestamps_; }
90 
91   bool Parse(const CommonHeader& packet);
92   static std::unique_ptr<TransportFeedback> ParseFrom(const uint8_t* buffer,
93                                                       size_t length);
94   // Pre and postcondition for all public methods. Should always return true.
95   // This function is for tests.
96   bool IsConsistent() const;
97 
98   size_t BlockLength() const override;
99   size_t PaddingLength() const;
100 
101   bool Create(uint8_t* packet,
102               size_t* position,
103               size_t max_length,
104               PacketReadyCallback callback) const override;
105 
106  private:
107   // Size in bytes of a delta time in rtcp packet.
108   // Valid values are 0 (packet wasn't received), 1 or 2.
109   using DeltaSize = uint8_t;
110   // Keeps DeltaSizes that can be encoded into single chunk if it is last chunk.
111   class LastChunk {
112    public:
113     using DeltaSize = TransportFeedback::DeltaSize;
114     static constexpr size_t kMaxRunLengthCapacity = 0x1fff;
115 
116     LastChunk();
117 
118     bool Empty() const;
119     void Clear();
120     // Return if delta sizes still can be encoded into single chunk with added
121     // `delta_size`.
122     bool CanAdd(DeltaSize delta_size) const;
123     // Add `delta_size`, assumes `CanAdd(delta_size)`,
124     void Add(DeltaSize delta_size);
125     // Equivalent to calling Add(0) `num_missing` times. Assumes `Empty()`.
126     void AddMissingPackets(size_t num_missing);
127 
128     // Encode chunk as large as possible removing encoded delta sizes.
129     // Assume CanAdd() == false for some valid delta_size.
130     uint16_t Emit();
131     // Encode all stored delta_sizes into single chunk, pad with 0s if needed.
132     uint16_t EncodeLast() const;
133 
134     // Decode up to `max_size` delta sizes from `chunk`.
135     void Decode(uint16_t chunk, size_t max_size);
136     // Appends content of the Lastchunk to `deltas`.
137     void AppendTo(std::vector<DeltaSize>* deltas) const;
138 
139    private:
140     static constexpr size_t kMaxOneBitCapacity = 14;
141     static constexpr size_t kMaxTwoBitCapacity = 7;
142     static constexpr size_t kMaxVectorCapacity = kMaxOneBitCapacity;
143     static constexpr DeltaSize kLarge = 2;
144 
145     uint16_t EncodeOneBit() const;
146     void DecodeOneBit(uint16_t chunk, size_t max_size);
147 
148     uint16_t EncodeTwoBit(size_t size) const;
149     void DecodeTwoBit(uint16_t chunk, size_t max_size);
150 
151     uint16_t EncodeRunLength() const;
152     void DecodeRunLength(uint16_t chunk, size_t max_size);
153 
154     std::array<DeltaSize, kMaxVectorCapacity> delta_sizes_;
155     size_t size_;
156     bool all_same_;
157     bool has_large_delta_;
158   };
159 
160   // Reset packet to consistent empty state.
161   void Clear();
162 
163   bool AddDeltaSize(DeltaSize delta_size);
164   // Adds `num_missing_packets` deltas of size 0.
165   bool AddMissingPackets(size_t num_missing_packets);
166 
167   const bool include_lost_;
168   uint16_t base_seq_no_;
169   uint16_t num_seq_no_;
170   uint32_t base_time_ticks_;
171   uint8_t feedback_seq_;
172   bool include_timestamps_;
173 
174   Timestamp last_timestamp_;
175   std::vector<ReceivedPacket> received_packets_;
176   std::vector<ReceivedPacket> all_packets_;
177   // All but last encoded packet chunks.
178   std::vector<uint16_t> encoded_chunks_;
179   LastChunk last_chunk_;
180   size_t size_bytes_;
181 };
182 
183 }  // namespace rtcp
184 }  // namespace webrtc
185 #endif  // MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
186