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
21namespace webrtc {
22namespace rtcp {
23
24class PacketStatusChunk;
25
26class 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