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 WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
12 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
13 
14 #include <deque>
15 #include <vector>
16 
17 #include "webrtc/base/constructormagic.h"
18 #include "webrtc/modules/include/module_common_types.h"
19 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
20 
21 namespace webrtc {
22 namespace rtcp {
23 
24 class PacketStatusChunk;
25 
26 class TransportFeedback : public RtcpPacket {
27  public:
28   TransportFeedback();
29   virtual ~TransportFeedback();
30 
31   void WithPacketSenderSsrc(uint32_t ssrc);
32   void WithMediaSourceSsrc(uint32_t ssrc);
33   void WithBase(uint16_t base_sequence,     // Seq# of first packet in this msg.
34                 int64_t ref_timestamp_us);  // Reference timestamp for this msg.
35   void WithFeedbackSequenceNumber(uint8_t feedback_sequence);
36   // NOTE: This method requires increasing sequence numbers (excepting wraps).
37   bool WithReceivedPacket(uint16_t sequence_number, int64_t timestamp_us);
38 
39   enum class StatusSymbol {
40     kNotReceived,
41     kReceivedSmallDelta,
42     kReceivedLargeDelta,
43   };
44 
45   uint16_t GetBaseSequence() const;
46   std::vector<TransportFeedback::StatusSymbol> GetStatusVector() const;
47   std::vector<int16_t> GetReceiveDeltas() const;
48 
49   // Get the reference time in microseconds, including any precision loss.
50   int64_t GetBaseTimeUs() const;
51   // Convenience method for getting all deltas as microseconds. The first delta
52   // is relative the base time.
53   std::vector<int64_t> GetReceiveDeltasUs() const;
54 
55   uint32_t GetPacketSenderSsrc() const;
56   uint32_t GetMediaSourceSsrc() const;
57   static const int kDeltaScaleFactor = 250;  // Convert to multiples of 0.25ms.
58   static const uint8_t kFeedbackMessageType = 15;  // TODO(sprang): IANA reg?
59   static const uint8_t kPayloadType = 205;         // RTPFB, see RFC4585.
60 
61   static rtc::scoped_ptr<TransportFeedback> ParseFrom(const uint8_t* buffer,
62                                                       size_t length);
63 
64  protected:
65   bool Create(uint8_t* packet,
66               size_t* position,
67               size_t max_length,
68               PacketReadyCallback* callback) const override;
69 
70   size_t BlockLength() const override;
71 
72  private:
73   static PacketStatusChunk* ParseChunk(const uint8_t* buffer, size_t max_size);
74 
75   int64_t Unwrap(uint16_t sequence_number);
76   bool AddSymbol(StatusSymbol symbol, int64_t seq);
77   bool Encode(StatusSymbol symbol);
78   bool HandleRleCandidate(StatusSymbol symbol,
79                           int current_capacity,
80                           int delta_size);
81   void EmitRemaining();
82   void EmitVectorChunk();
83   void EmitRunLengthChunk();
84 
85   uint32_t packet_sender_ssrc_;
86   uint32_t media_source_ssrc_;
87   int32_t base_seq_;
88   int64_t base_time_;
89   uint8_t feedback_seq_;
90   std::vector<PacketStatusChunk*> status_chunks_;
91   std::vector<int16_t> receive_deltas_;
92 
93   int64_t last_seq_;
94   int64_t last_timestamp_;
95   std::deque<StatusSymbol> symbol_vec_;
96   uint16_t first_symbol_cardinality_;
97   bool vec_needs_two_bit_symbols_;
98   uint32_t size_bytes_;
99 
100   RTC_DISALLOW_COPY_AND_ASSIGN(TransportFeedback);
101 };
102 
103 }  // namespace rtcp
104 }  // namespace webrtc
105 #endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
106