1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file.
4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#ifndef MEDIA_CAST_RTCP_RTCP_UTILITY_H_
6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define MEDIA_CAST_RTCP_RTCP_UTILITY_H_
7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "media/cast/cast_config.h"
9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "media/cast/cast_defines.h"
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/cast/logging/logging_defines.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "media/cast/rtcp/rtcp_defines.h"
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace media {
14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace cast {
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static const int kRtcpRpsiDataSize = 30;
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// RFC 3550 page 44, including end null.
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const size_t kRtcpCnameSize = 256;
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static const int kRtcpMaxNumberOfRembFeedbackSsrcs = 255;
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static const uint32 kRemb = ('R' << 24) + ('E' << 16) + ('M' << 8) + 'B';
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static const uint32 kCast = ('C' << 24) + ('A' << 16) + ('S' << 8) + 'T';
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const uint8 kReceiverLogSubtype = 2;
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const size_t kRtcpMaxReceiverLogMessages = 256;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const size_t kRtcpMaxNackFields = 253;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const size_t kRtcpMaxCastLossFields = 100;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldReceiverReport {
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3550.
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 number_of_report_blocks;
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldSenderReport {
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3550.
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 number_of_report_blocks;
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 ntp_most_significant;
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 ntp_least_significant;
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 rtp_timestamp;
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_packet_count;
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_octet_count;
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldReportBlockItem {
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3550.
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 ssrc;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 fraction_lost;
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 cumulative_number_of_packets_lost;
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 extended_highest_sequence_number;
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 jitter;
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 last_sender_report;
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 delay_last_sender_report;
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldSdesCName {
60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3550
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  char name[kRtcpCnameSize];
63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldBye {
66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3550.
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldGenericRtpFeedbackNack {
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 4585.
72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 media_ssrc;
74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldGenericRtpFeedbackNackItem {
77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 4585.
78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint16 packet_id;
79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint16 bitmask;
80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificFir {
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 5104.
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 media_ssrc;  // zero!
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificFirItem {
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 5104.
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 ssrc;
91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 command_sequence_number;
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificPli {
95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 4585.
96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 media_ssrc;
98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificRpsi {
101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 4585.
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 media_ssrc;
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 payload_type;
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint16 number_of_valid_bits;
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 native_bit_string[kRtcpRpsiDataSize];
107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldXr {
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3611.
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldXrRrtr {
115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3611.
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 ntp_most_significant;
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 ntp_least_significant;
118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldXrDlrr {
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3611.
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 receivers_ssrc;
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 last_receiver_report;
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 delay_last_receiver_report;
125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificApplication {
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 sender_ssrc;
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 media_ssrc;
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificRembItem {
133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 bitrate;
134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 number_of_ssrcs;
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 ssrcs[kRtcpMaxNumberOfRembFeedbackSsrcs];
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificCastItem {
139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 last_frame_id;
140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 number_of_lost_fields;
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  uint16 target_delay_ms;
142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpFieldPayloadSpecificCastNackItem {
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 frame_id;
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint16 packet_id;
147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 bitmask;
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct RtcpFieldApplicationSpecificCastReceiverLogItem {
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  uint32 sender_ssrc;
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  uint32 rtp_timestamp;
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  uint32 event_timestamp_base;
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  uint8 event;
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  union {
156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    uint16 packet_id;
157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    int16 delay_delta;
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  } delay_delta_or_packet_id;
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  uint16 event_timestamp_delta;
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)union RtcpField {
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldReceiverReport receiver_report;
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldSenderReport sender_report;
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldReportBlockItem report_block_item;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldSdesCName c_name;
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldBye bye;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldXr extended_report;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldXrRrtr rrtr;
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldXrDlrr dlrr;
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldGenericRtpFeedbackNack nack;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldGenericRtpFeedbackNackItem nack_item;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificPli pli;
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificRpsi rpsi;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificFir fir;
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificFirItem fir_item;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificApplication application_specific;
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificRembItem remb_item;
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificCastItem cast_item;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RtcpFieldPayloadSpecificCastNackItem cast_nack_item;
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RtcpFieldApplicationSpecificCastReceiverLogItem cast_receiver_log;
186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)enum RtcpFieldTypes {
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpNotValidCode,
190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3550.
192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpRrCode,
193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpSrCode,
194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpReportBlockItemCode,
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpSdesCode,
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpSdesChunkCode,
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpByeCode,
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 3611.
200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpXrCode,
201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpXrRrtrCode,
202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpXrDlrrCode,
203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpXrUnknownItemCode,
204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 4585.
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpGenericRtpFeedbackNackCode,
207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpGenericRtpFeedbackNackItemCode,
208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificPliCode,
209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificRpsiCode,
210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificAppCode,
211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Application specific.
213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificRembCode,
214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificRembItemCode,
215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificCastCode,
216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificCastNackItemCode,
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  kRtcpApplicationSpecificCastReceiverLogCode,
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  kRtcpApplicationSpecificCastReceiverLogFrameCode,
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  kRtcpApplicationSpecificCastReceiverLogEventCode,
220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 5104.
222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificFirCode,
223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpPayloadSpecificFirItemCode,
224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RFC 6051.
226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  kRtcpGenericRtpFeedbackSrReqCode,
227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct RtcpCommonHeader {
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 V;   // Version.
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool P;    // Padding.
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 IC;  // Item count / subtype.
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 PT;  // Packet Type.
234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint16 length_in_octets;
235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class RtcpParser {
238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public:
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpParser(const uint8* rtcp_data, size_t rtcp_length);
240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ~RtcpParser();
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpFieldTypes FieldType() const;
243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const RtcpField& Field() const;
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool IsValid() const;
246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpFieldTypes Begin();
248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpFieldTypes Iterate();
249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  enum ParseState {
252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStateTopLevel,     // Top level packet
253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStateReportBlock,  // Sender/Receiver report report blocks.
254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStateSdes,
255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStateBye,
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    kStateApplicationSpecificCastReceiverFrameLog,
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    kStateApplicationSpecificCastReceiverEventLog,
258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStateExtendedReportBlock,
259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStateExtendedReportDelaySinceLastReceiverReport,
260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStateGenericRtpFeedbackNack,
261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStatePayloadSpecificRpsi,
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStatePayloadSpecificFir,
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStatePayloadSpecificApplication,
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStatePayloadSpecificRemb,      // Application specific Remb.
265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStatePayloadSpecificCast,      // Application specific Cast.
266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    kStatePayloadSpecificCastNack,  // Application specific Nack for Cast.
267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  };
268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool RtcpParseCommonHeader(const uint8* begin,
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                             const uint8* end,
271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                             RtcpCommonHeader* parsed_header) const;
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateTopLevel();
274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateReportBlockItem();
275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateSdesItem();
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateByeItem();
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void IterateCastReceiverLogFrame();
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void IterateCastReceiverLogEvent();
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateExtendedReportItem();
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateExtendedReportDelaySinceLastReceiverReportItem();
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateNackItem();
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateRpsiItem();
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IterateFirItem();
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IteratePayloadSpecificAppItem();
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IteratePayloadSpecificRembItem();
286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IteratePayloadSpecificCastItem();
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void IteratePayloadSpecificCastNackItem();
288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void Validate();
290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void EndCurrentBlock();
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseRR();
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseSR();
294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseReportBlockItem();
295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseSdes();
297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseSdesItem();
298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseSdesTypes();
299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseBye();
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseByeItem();
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ParseApplicationDefined(uint8 subtype);
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ParseCastReceiverLogFrameItem();
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ParseCastReceiverLogEventItem();
304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseExtendedReport();
306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseExtendedReportItem();
307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseExtendedReportReceiverReferenceTimeReport();
308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseExtendedReportDelaySinceLastReceiverReport();
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseFeedBackCommon(const RtcpCommonHeader& header);
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseNackItem();
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseRpsiItem();
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParseFirItem();
314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParsePayloadSpecificAppItem();
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParsePayloadSpecificRembItem();
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParsePayloadSpecificCastItem();
317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ParsePayloadSpecificCastNackItem();
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const uint8* const rtcp_data_begin_;
321424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const uint8* const rtcp_data_end_;
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool valid_packet_;
324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const uint8* rtcp_data_;
325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const uint8* rtcp_block_end_;
326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ParseState state_;
328424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint8 number_of_blocks_;
329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpFieldTypes field_type_;
330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpField field_;
331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RtcpParser);
333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Converts a log event type to an integer value.
336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// NOTE: We have only allocated 4 bits to represent the type of event over the
337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// wire. Therefore, this function can only return values from 0 to 15.
338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)uint8 ConvertEventTypeToWireFormat(CastLoggingEvent event);
339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// The inverse of |ConvertEventTypeToWireFormat()|.
341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event);
342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace cast
344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace media
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif  // MEDIA_CAST_RTCP_RTCP_UTILITY_H_
347