1 /*
2 * Copyright (c) 2014 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 #include "test/rtcp_packet_parser.h"
12
13 #include "modules/rtp_rtcp/source/rtcp_packet/psfb.h"
14 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
15 #include "rtc_base/checks.h"
16 #include "rtc_base/logging.h"
17
18 namespace webrtc {
19 namespace test {
20
21 RtcpPacketParser::RtcpPacketParser() = default;
22 RtcpPacketParser::~RtcpPacketParser() = default;
23
Parse(const void * data,size_t length)24 bool RtcpPacketParser::Parse(const void* data, size_t length) {
25 ++processed_rtcp_packets_;
26
27 const uint8_t* const buffer = static_cast<const uint8_t*>(data);
28 const uint8_t* const buffer_end = buffer + length;
29
30 rtcp::CommonHeader header;
31 for (const uint8_t* next_packet = buffer; next_packet != buffer_end;
32 next_packet = header.NextPacket()) {
33 RTC_DCHECK_GT(buffer_end - next_packet, 0);
34 if (!header.Parse(next_packet, buffer_end - next_packet)) {
35 RTC_LOG(LS_WARNING)
36 << "Invalid rtcp header or unaligned rtcp packet at position "
37 << (next_packet - buffer);
38 return false;
39 }
40 switch (header.type()) {
41 case rtcp::App::kPacketType:
42 app_.Parse(header);
43 break;
44 case rtcp::Bye::kPacketType:
45 bye_.Parse(header, &sender_ssrc_);
46 break;
47 case rtcp::ExtendedReports::kPacketType:
48 xr_.Parse(header, &sender_ssrc_);
49 break;
50 case rtcp::ExtendedJitterReport::kPacketType:
51 ij_.Parse(header);
52 break;
53 case rtcp::Psfb::kPacketType:
54 switch (header.fmt()) {
55 case rtcp::Fir::kFeedbackMessageType:
56 fir_.Parse(header, &sender_ssrc_);
57 break;
58 case rtcp::Pli::kFeedbackMessageType:
59 pli_.Parse(header, &sender_ssrc_);
60 break;
61 case rtcp::Psfb::kAfbMessageType:
62 if (!loss_notification_.Parse(header, &sender_ssrc_) &&
63 !remb_.Parse(header, &sender_ssrc_)) {
64 RTC_LOG(LS_WARNING) << "Unknown application layer FB message.";
65 }
66 break;
67 default:
68 RTC_LOG(LS_WARNING)
69 << "Unknown rtcp payload specific feedback type "
70 << header.fmt();
71 break;
72 }
73 break;
74 case rtcp::ReceiverReport::kPacketType:
75 receiver_report_.Parse(header, &sender_ssrc_);
76 break;
77 case rtcp::Rtpfb::kPacketType:
78 switch (header.fmt()) {
79 case rtcp::Nack::kFeedbackMessageType:
80 nack_.Parse(header, &sender_ssrc_);
81 break;
82 case rtcp::RapidResyncRequest::kFeedbackMessageType:
83 rrr_.Parse(header, &sender_ssrc_);
84 break;
85 case rtcp::Tmmbn::kFeedbackMessageType:
86 tmmbn_.Parse(header, &sender_ssrc_);
87 break;
88 case rtcp::Tmmbr::kFeedbackMessageType:
89 tmmbr_.Parse(header, &sender_ssrc_);
90 break;
91 case rtcp::TransportFeedback::kFeedbackMessageType:
92 transport_feedback_.Parse(header, &sender_ssrc_);
93 break;
94 default:
95 RTC_LOG(LS_WARNING)
96 << "Unknown rtcp transport feedback type " << header.fmt();
97 break;
98 }
99 break;
100 case rtcp::Sdes::kPacketType:
101 sdes_.Parse(header);
102 break;
103 case rtcp::SenderReport::kPacketType:
104 sender_report_.Parse(header, &sender_ssrc_);
105 break;
106 default:
107 RTC_LOG(LS_WARNING) << "Unknown rtcp packet type " << header.type();
108 break;
109 }
110 }
111 return true;
112 }
113
114 } // namespace test
115 } // namespace webrtc
116