summaryrefslogtreecommitdiffstats
path: root/media/cast/net/rtcp/rtcp_utility.h
blob: ec59c08cff1cb655edea387066252bf63870eca6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CAST_NET_RTCP_RTCP_UTILITY_H_
#define MEDIA_CAST_NET_RTCP_RTCP_UTILITY_H_

#include <stddef.h>
#include <stdint.h>

#include "base/big_endian.h"
#include "base/macros.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/rtcp/rtcp_defines.h"

namespace media {
namespace cast {

// RFC 3550 page 44, including end null.
static const size_t kRtcpCnameSize = 256;

static const uint32_t kCast = ('C' << 24) + ('A' << 16) + ('S' << 8) + 'T';

static const uint8_t kReceiverLogSubtype = 2;

static const size_t kRtcpMaxReceiverLogMessages = 256;
static const size_t kRtcpMaxCastLossFields = 100;

struct RtcpCommonHeader {
  uint8_t V;   // Version.
  bool P;    // Padding.
  uint8_t IC;  // Item count / subtype.
  uint8_t PT;  // Packet Type.
  size_t length_in_octets;
};

class RtcpParser {
 public:
  RtcpParser(uint32_t local_ssrc, uint32_t remote_ssrc);
  ~RtcpParser();

  bool Parse(base::BigEndianReader* reader);

  bool has_sender_report() const { return has_sender_report_; }
  const RtcpSenderInfo& sender_report() const {
    return sender_report_;
  }

  bool has_last_report() const { return has_last_report_; }
  uint32_t last_report() const { return last_report_; }
  uint32_t delay_since_last_report() const { return delay_since_last_report_; }

  bool has_receiver_log() const { return !receiver_log_.empty(); }
  const RtcpReceiverLogMessage& receiver_log() const { return receiver_log_; }
  RtcpReceiverLogMessage* mutable_receiver_log() { return & receiver_log_; }

  bool has_cast_message() const { return has_cast_message_; }
  const RtcpCastMessage& cast_message() const { return cast_message_; }
  RtcpCastMessage* mutable_cast_message() { return &cast_message_; }

  bool has_receiver_reference_time_report() const {
    return has_receiver_reference_time_report_;
  }
  const RtcpReceiverReferenceTimeReport&
  receiver_reference_time_report() const {
    return receiver_reference_time_report_;
  }

 private:
  bool ParseCommonHeader(base::BigEndianReader* reader,
                         RtcpCommonHeader* parsed_header);
  bool ParseSR(base::BigEndianReader* reader,
               const RtcpCommonHeader& header);
  bool ParseRR(base::BigEndianReader* reader,
               const RtcpCommonHeader& header);
  bool ParseReportBlock(base::BigEndianReader* reader);
  bool ParseApplicationDefined(base::BigEndianReader* reader,
                               const RtcpCommonHeader& header);
  bool ParseCastReceiverLogFrameItem(base::BigEndianReader* reader);
  bool ParseFeedbackCommon(base::BigEndianReader* reader,
                           const RtcpCommonHeader& header);
  bool ParseExtendedReport(base::BigEndianReader* reader,
                           const RtcpCommonHeader& header);
  bool ParseExtendedReportReceiverReferenceTimeReport(
      base::BigEndianReader* reader,
      uint32_t remote_ssrc);
  bool ParseExtendedReportDelaySinceLastReceiverReport(
      base::BigEndianReader* reader);

  const uint32_t local_ssrc_;
  const uint32_t remote_ssrc_;

  bool has_sender_report_;
  RtcpSenderInfo sender_report_;

  uint32_t last_report_;
  uint32_t delay_since_last_report_;
  bool has_last_report_;

  // |receiver_log_| is a vector vector, no need for has_*.
  RtcpReceiverLogMessage receiver_log_;

  bool has_cast_message_;
  RtcpCastMessage cast_message_;

  bool has_receiver_reference_time_report_;
  RtcpReceiverReferenceTimeReport receiver_reference_time_report_;

  // Tracks recently-parsed RTP timestamps so that the truncated values can be
  // re-expanded into full-form.
  RtpTimeTicks last_parsed_sr_rtp_timestamp_;
  RtpTimeTicks last_parsed_frame_log_rtp_timestamp_;

  DISALLOW_COPY_AND_ASSIGN(RtcpParser);
};

// Converts a log event type to an integer value.
// NOTE: We have only allocated 4 bits to represent the type of event over the
// wire. Therefore, this function can only return values from 0 to 15.
uint8_t ConvertEventTypeToWireFormat(CastLoggingEvent event);

// The inverse of |ConvertEventTypeToWireFormat()|.
CastLoggingEvent TranslateToLogEventFromWireFormat(uint8_t event);

// Splits an NTP timestamp having a microsecond timebase into the standard two
// 32-bit integer wire format.
void ConvertTimeToFractions(int64_t ntp_time_us,
                            uint32_t* seconds,
                            uint32_t* fractions);

// Maps a base::TimeTicks value to an NTP timestamp comprised of two components.
void ConvertTimeTicksToNtp(const base::TimeTicks& time,
                           uint32_t* ntp_seconds,
                           uint32_t* ntp_fractions);

// Maps an NTP timestamp, comprised of two components, to a base::TimeTicks
// value.
base::TimeTicks ConvertNtpToTimeTicks(uint32_t ntp_seconds,
                                      uint32_t ntp_fractions);

bool IsRtcpPacket(const uint8_t* packet, size_t length);

uint32_t GetSsrcOfSender(const uint8_t* rtcp_buffer, size_t length);

}  // namespace cast
}  // namespace media

#endif  // MEDIA_CAST_NET_RTCP_RTCP_UTILITY_H_