| /* | |
| * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #include "test/rtcp_packet_parser.h" | |
| #include "modules/rtp_rtcp/source/rtcp_packet/psfb.h" | |
| #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h" | |
| #include "rtc_base/checks.h" | |
| #include "rtc_base/logging.h" | |
| namespace webrtc { | |
| namespace test { | |
| RtcpPacketParser::RtcpPacketParser() = default; | |
| RtcpPacketParser::~RtcpPacketParser() = default; | |
| bool RtcpPacketParser::Parse(const void* data, size_t length) { | |
| ++processed_rtcp_packets_; | |
| const uint8_t* const buffer = static_cast<const uint8_t*>(data); | |
| const uint8_t* const buffer_end = buffer + length; | |
| rtcp::CommonHeader header; | |
| for (const uint8_t* next_packet = buffer; next_packet != buffer_end; | |
| next_packet = header.NextPacket()) { | |
| RTC_DCHECK_GT(buffer_end - next_packet, 0); | |
| if (!header.Parse(next_packet, buffer_end - next_packet)) { | |
| RTC_LOG(LS_WARNING) | |
| << "Invalid rtcp header or unaligned rtcp packet at position " | |
| << (next_packet - buffer); | |
| return false; | |
| } | |
| switch (header.type()) { | |
| case rtcp::App::kPacketType: | |
| app_.Parse(header); | |
| break; | |
| case rtcp::Bye::kPacketType: | |
| bye_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::ExtendedReports::kPacketType: | |
| xr_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::ExtendedJitterReport::kPacketType: | |
| ij_.Parse(header); | |
| break; | |
| case rtcp::Psfb::kPacketType: | |
| switch (header.fmt()) { | |
| case rtcp::Fir::kFeedbackMessageType: | |
| fir_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::Pli::kFeedbackMessageType: | |
| pli_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::Psfb::kAfbMessageType: | |
| if (!loss_notification_.Parse(header, &sender_ssrc_) && | |
| !remb_.Parse(header, &sender_ssrc_)) { | |
| RTC_LOG(LS_WARNING) << "Unknown application layer FB message."; | |
| } | |
| break; | |
| default: | |
| RTC_LOG(LS_WARNING) | |
| << "Unknown rtcp payload specific feedback type " | |
| << header.fmt(); | |
| break; | |
| } | |
| break; | |
| case rtcp::ReceiverReport::kPacketType: | |
| receiver_report_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::Rtpfb::kPacketType: | |
| switch (header.fmt()) { | |
| case rtcp::Nack::kFeedbackMessageType: | |
| nack_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::RapidResyncRequest::kFeedbackMessageType: | |
| rrr_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::Tmmbn::kFeedbackMessageType: | |
| tmmbn_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::Tmmbr::kFeedbackMessageType: | |
| tmmbr_.Parse(header, &sender_ssrc_); | |
| break; | |
| case rtcp::TransportFeedback::kFeedbackMessageType: | |
| transport_feedback_.Parse(header, &sender_ssrc_); | |
| break; | |
| default: | |
| RTC_LOG(LS_WARNING) | |
| << "Unknown rtcp transport feedback type " << header.fmt(); | |
| break; | |
| } | |
| break; | |
| case rtcp::Sdes::kPacketType: | |
| sdes_.Parse(header); | |
| break; | |
| case rtcp::SenderReport::kPacketType: | |
| sender_report_.Parse(header, &sender_ssrc_); | |
| break; | |
| default: | |
| RTC_LOG(LS_WARNING) << "Unknown rtcp packet type " << header.type(); | |
| break; | |
| } | |
| } | |
| return true; | |
| } | |
| } // namespace test | |
| } // namespace webrtc |