Remove UlpfecReceiver virtual interface.
There's only one implementation. Bug: none Change-Id: I204c23e7f87102909fcf6ee8632ceeed84e901a1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/271026 Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Cr-Commit-Position: refs/heads/main@{#37725}
This commit is contained in:
parent
46dc5958d9
commit
e488a87753
@ -145,7 +145,6 @@ rtc_library("rtp_rtcp") {
|
|||||||
"include/flexfec_sender.h",
|
"include/flexfec_sender.h",
|
||||||
"include/receive_statistics.h",
|
"include/receive_statistics.h",
|
||||||
"include/remote_ntp_time_estimator.h",
|
"include/remote_ntp_time_estimator.h",
|
||||||
"include/ulpfec_receiver.h",
|
|
||||||
"source/absolute_capture_time_interpolator.cc",
|
"source/absolute_capture_time_interpolator.cc",
|
||||||
"source/absolute_capture_time_interpolator.h",
|
"source/absolute_capture_time_interpolator.h",
|
||||||
"source/absolute_capture_time_sender.cc",
|
"source/absolute_capture_time_sender.cc",
|
||||||
@ -227,8 +226,8 @@ rtc_library("rtp_rtcp") {
|
|||||||
"source/ulpfec_generator.h",
|
"source/ulpfec_generator.h",
|
||||||
"source/ulpfec_header_reader_writer.cc",
|
"source/ulpfec_header_reader_writer.cc",
|
||||||
"source/ulpfec_header_reader_writer.h",
|
"source/ulpfec_header_reader_writer.h",
|
||||||
"source/ulpfec_receiver_impl.cc",
|
"source/ulpfec_receiver.cc",
|
||||||
"source/ulpfec_receiver_impl.h",
|
"source/ulpfec_receiver.h",
|
||||||
"source/video_fec_generator.h",
|
"source/video_fec_generator.h",
|
||||||
"source/video_rtp_depacketizer.cc",
|
"source/video_rtp_depacketizer.cc",
|
||||||
"source/video_rtp_depacketizer.h",
|
"source/video_rtp_depacketizer.h",
|
||||||
|
|||||||
@ -17,9 +17,9 @@
|
|||||||
|
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
#include "modules/rtp_rtcp/include/ulpfec_receiver.h"
|
|
||||||
#include "modules/rtp_rtcp/source/forward_error_correction.h"
|
#include "modules/rtp_rtcp/source/forward_error_correction.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||||
|
#include "modules/rtp_rtcp/source/ulpfec_receiver.h"
|
||||||
#include "rtc_base/system/no_unique_address.h"
|
#include "rtc_base/system/no_unique_address.h"
|
||||||
#include "rtc_base/thread_annotations.h"
|
#include "rtc_base/thread_annotations.h"
|
||||||
|
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MODULES_RTP_RTCP_INCLUDE_ULPFEC_RECEIVER_H_
|
|
||||||
#define MODULES_RTP_RTCP_INCLUDE_ULPFEC_RECEIVER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "api/array_view.h"
|
|
||||||
#include "api/rtp_parameters.h"
|
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
|
||||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
struct FecPacketCounter {
|
|
||||||
FecPacketCounter() = default;
|
|
||||||
size_t num_packets = 0; // Number of received packets.
|
|
||||||
size_t num_bytes = 0;
|
|
||||||
size_t num_fec_packets = 0; // Number of received FEC packets.
|
|
||||||
size_t num_recovered_packets =
|
|
||||||
0; // Number of recovered media packets using FEC.
|
|
||||||
int64_t first_packet_time_ms = -1; // Time when first packet is received.
|
|
||||||
};
|
|
||||||
|
|
||||||
class UlpfecReceiver {
|
|
||||||
public:
|
|
||||||
static std::unique_ptr<UlpfecReceiver> Create(
|
|
||||||
uint32_t ssrc,
|
|
||||||
RecoveredPacketReceiver* callback,
|
|
||||||
rtc::ArrayView<const RtpExtension> extensions);
|
|
||||||
|
|
||||||
virtual ~UlpfecReceiver() {}
|
|
||||||
|
|
||||||
// Takes a RED packet, strips the RED header, and adds the resulting
|
|
||||||
// "virtual" RTP packet(s) into the internal buffer.
|
|
||||||
//
|
|
||||||
// TODO(brandtr): Set `ulpfec_payload_type` during constructor call,
|
|
||||||
// rather than as a parameter here.
|
|
||||||
virtual bool AddReceivedRedPacket(const RtpPacketReceived& rtp_packet,
|
|
||||||
uint8_t ulpfec_payload_type) = 0;
|
|
||||||
|
|
||||||
// Sends the received packets to the FEC and returns all packets
|
|
||||||
// (both original media and recovered) through the callback.
|
|
||||||
virtual void ProcessReceivedFec() = 0;
|
|
||||||
|
|
||||||
// Returns a counter describing the added and recovered packets.
|
|
||||||
virtual FecPacketCounter GetPacketCounter() const = 0;
|
|
||||||
|
|
||||||
virtual void SetRtpExtensions(
|
|
||||||
rtc::ArrayView<const RtpExtension> extensions) = 0;
|
|
||||||
};
|
|
||||||
} // namespace webrtc
|
|
||||||
#endif // MODULES_RTP_RTCP_INCLUDE_ULPFEC_RECEIVER_H_
|
|
||||||
@ -8,7 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "modules/rtp_rtcp/source/ulpfec_receiver_impl.h"
|
#include "modules/rtp_rtcp/source/ulpfec_receiver.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -20,15 +20,7 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
std::unique_ptr<UlpfecReceiver> UlpfecReceiver::Create(
|
UlpfecReceiver::UlpfecReceiver(uint32_t ssrc,
|
||||||
uint32_t ssrc,
|
|
||||||
RecoveredPacketReceiver* callback,
|
|
||||||
rtc::ArrayView<const RtpExtension> extensions) {
|
|
||||||
return std::make_unique<UlpfecReceiverImpl>(ssrc, callback, extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
UlpfecReceiverImpl::UlpfecReceiverImpl(
|
|
||||||
uint32_t ssrc,
|
|
||||||
RecoveredPacketReceiver* callback,
|
RecoveredPacketReceiver* callback,
|
||||||
rtc::ArrayView<const RtpExtension> extensions)
|
rtc::ArrayView<const RtpExtension> extensions)
|
||||||
: ssrc_(ssrc),
|
: ssrc_(ssrc),
|
||||||
@ -36,18 +28,18 @@ UlpfecReceiverImpl::UlpfecReceiverImpl(
|
|||||||
recovered_packet_callback_(callback),
|
recovered_packet_callback_(callback),
|
||||||
fec_(ForwardErrorCorrection::CreateUlpfec(ssrc_)) {}
|
fec_(ForwardErrorCorrection::CreateUlpfec(ssrc_)) {}
|
||||||
|
|
||||||
UlpfecReceiverImpl::~UlpfecReceiverImpl() {
|
UlpfecReceiver::~UlpfecReceiver() {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
received_packets_.clear();
|
received_packets_.clear();
|
||||||
fec_->ResetState(&recovered_packets_);
|
fec_->ResetState(&recovered_packets_);
|
||||||
}
|
}
|
||||||
|
|
||||||
FecPacketCounter UlpfecReceiverImpl::GetPacketCounter() const {
|
FecPacketCounter UlpfecReceiver::GetPacketCounter() const {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
return packet_counter_;
|
return packet_counter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlpfecReceiverImpl::SetRtpExtensions(
|
void UlpfecReceiver::SetRtpExtensions(
|
||||||
rtc::ArrayView<const RtpExtension> extensions) {
|
rtc::ArrayView<const RtpExtension> extensions) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
extensions_.Reset(extensions);
|
extensions_.Reset(extensions);
|
||||||
@ -81,8 +73,7 @@ void UlpfecReceiverImpl::SetRtpExtensions(
|
|||||||
// block length: 10 bits Length in bytes of the corresponding data
|
// block length: 10 bits Length in bytes of the corresponding data
|
||||||
// block excluding header.
|
// block excluding header.
|
||||||
|
|
||||||
bool UlpfecReceiverImpl::AddReceivedRedPacket(
|
bool UlpfecReceiver::AddReceivedRedPacket(const RtpPacketReceived& rtp_packet,
|
||||||
const RtpPacketReceived& rtp_packet,
|
|
||||||
uint8_t ulpfec_payload_type) {
|
uint8_t ulpfec_payload_type) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
// TODO(bugs.webrtc.org/11993): We get here via Call::DeliverRtp, so should be
|
// TODO(bugs.webrtc.org/11993): We get here via Call::DeliverRtp, so should be
|
||||||
@ -159,7 +150,7 @@ bool UlpfecReceiverImpl::AddReceivedRedPacket(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlpfecReceiverImpl::ProcessReceivedFec() {
|
void UlpfecReceiver::ProcessReceivedFec() {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
|
||||||
// If we iterate over `received_packets_` and it contains a packet that cause
|
// If we iterate over `received_packets_` and it contains a packet that cause
|
||||||
@ -8,8 +8,8 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_IMPL_H_
|
#ifndef MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_H_
|
||||||
#define MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_IMPL_H_
|
#define MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -20,28 +20,37 @@
|
|||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
#include "modules/rtp_rtcp/include/ulpfec_receiver.h"
|
|
||||||
#include "modules/rtp_rtcp/source/forward_error_correction.h"
|
#include "modules/rtp_rtcp/source/forward_error_correction.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||||
#include "rtc_base/system/no_unique_address.h"
|
#include "rtc_base/system/no_unique_address.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
class UlpfecReceiverImpl : public UlpfecReceiver {
|
struct FecPacketCounter {
|
||||||
|
FecPacketCounter() = default;
|
||||||
|
size_t num_packets = 0; // Number of received packets.
|
||||||
|
size_t num_bytes = 0;
|
||||||
|
size_t num_fec_packets = 0; // Number of received FEC packets.
|
||||||
|
size_t num_recovered_packets =
|
||||||
|
0; // Number of recovered media packets using FEC.
|
||||||
|
int64_t first_packet_time_ms = -1; // Time when first packet is received.
|
||||||
|
};
|
||||||
|
|
||||||
|
class UlpfecReceiver {
|
||||||
public:
|
public:
|
||||||
explicit UlpfecReceiverImpl(uint32_t ssrc,
|
UlpfecReceiver(uint32_t ssrc,
|
||||||
RecoveredPacketReceiver* callback,
|
RecoveredPacketReceiver* callback,
|
||||||
rtc::ArrayView<const RtpExtension> extensions);
|
rtc::ArrayView<const RtpExtension> extensions);
|
||||||
~UlpfecReceiverImpl() override;
|
~UlpfecReceiver();
|
||||||
|
|
||||||
bool AddReceivedRedPacket(const RtpPacketReceived& rtp_packet,
|
bool AddReceivedRedPacket(const RtpPacketReceived& rtp_packet,
|
||||||
uint8_t ulpfec_payload_type) override;
|
uint8_t ulpfec_payload_type);
|
||||||
|
|
||||||
void ProcessReceivedFec() override;
|
void ProcessReceivedFec();
|
||||||
|
|
||||||
FecPacketCounter GetPacketCounter() const override;
|
FecPacketCounter GetPacketCounter() const;
|
||||||
|
|
||||||
void SetRtpExtensions(rtc::ArrayView<const RtpExtension> extensions) override;
|
void SetRtpExtensions(rtc::ArrayView<const RtpExtension> extensions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint32_t ssrc_;
|
const uint32_t ssrc_;
|
||||||
@ -63,4 +72,4 @@ class UlpfecReceiverImpl : public UlpfecReceiver {
|
|||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_IMPL_H_
|
#endif // MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_H_
|
||||||
@ -8,12 +8,13 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "modules/rtp_rtcp/include/ulpfec_receiver.h"
|
#include "modules/rtp_rtcp/source/ulpfec_receiver.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "modules/rtp_rtcp/mocks/mock_recovered_packet_receiver.h"
|
#include "modules/rtp_rtcp/mocks/mock_recovered_packet_receiver.h"
|
||||||
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
|
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
|
||||||
@ -49,9 +50,7 @@ class UlpfecReceiverTest : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
UlpfecReceiverTest()
|
UlpfecReceiverTest()
|
||||||
: fec_(ForwardErrorCorrection::CreateUlpfec(kMediaSsrc)),
|
: fec_(ForwardErrorCorrection::CreateUlpfec(kMediaSsrc)),
|
||||||
receiver_fec_(UlpfecReceiver::Create(kMediaSsrc,
|
receiver_fec_(kMediaSsrc, &recovered_packet_receiver_, {}),
|
||||||
&recovered_packet_receiver_,
|
|
||||||
{})),
|
|
||||||
packet_generator_(kMediaSsrc) {}
|
packet_generator_(kMediaSsrc) {}
|
||||||
|
|
||||||
// Generates `num_fec_packets` FEC packets, given `media_packets`.
|
// Generates `num_fec_packets` FEC packets, given `media_packets`.
|
||||||
@ -87,7 +86,7 @@ class UlpfecReceiverTest : public ::testing::Test {
|
|||||||
|
|
||||||
MockRecoveredPacketReceiver recovered_packet_receiver_;
|
MockRecoveredPacketReceiver recovered_packet_receiver_;
|
||||||
std::unique_ptr<ForwardErrorCorrection> fec_;
|
std::unique_ptr<ForwardErrorCorrection> fec_;
|
||||||
std::unique_ptr<UlpfecReceiver> receiver_fec_;
|
UlpfecReceiver receiver_fec_;
|
||||||
UlpfecPacketGenerator packet_generator_;
|
UlpfecPacketGenerator packet_generator_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,13 +125,13 @@ void UlpfecReceiverTest::BuildAndAddRedMediaPacket(AugmentedPacket* packet,
|
|||||||
bool is_recovered) {
|
bool is_recovered) {
|
||||||
RtpPacketReceived red_packet =
|
RtpPacketReceived red_packet =
|
||||||
packet_generator_.BuildMediaRedPacket(*packet, is_recovered);
|
packet_generator_.BuildMediaRedPacket(*packet, is_recovered);
|
||||||
EXPECT_TRUE(receiver_fec_->AddReceivedRedPacket(red_packet, kFecPayloadType));
|
EXPECT_TRUE(receiver_fec_.AddReceivedRedPacket(red_packet, kFecPayloadType));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlpfecReceiverTest::BuildAndAddRedFecPacket(Packet* packet) {
|
void UlpfecReceiverTest::BuildAndAddRedFecPacket(Packet* packet) {
|
||||||
RtpPacketReceived red_packet =
|
RtpPacketReceived red_packet =
|
||||||
packet_generator_.BuildUlpfecRedPacket(*packet);
|
packet_generator_.BuildUlpfecRedPacket(*packet);
|
||||||
EXPECT_TRUE(receiver_fec_->AddReceivedRedPacket(red_packet, kFecPayloadType));
|
EXPECT_TRUE(receiver_fec_.AddReceivedRedPacket(red_packet, kFecPayloadType));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlpfecReceiverTest::VerifyReconstructedMediaPacket(
|
void UlpfecReceiverTest::VerifyReconstructedMediaPacket(
|
||||||
@ -164,9 +163,9 @@ void UlpfecReceiverTest::InjectGarbagePacketLength(size_t fec_garbage_offset) {
|
|||||||
// packet to cause a recovery from the FEC packet.
|
// packet to cause a recovery from the FEC packet.
|
||||||
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
||||||
BuildAndAddRedFecPacket(fec_packets.front());
|
BuildAndAddRedFecPacket(fec_packets.front());
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
|
|
||||||
FecPacketCounter counter = receiver_fec_->GetPacketCounter();
|
FecPacketCounter counter = receiver_fec_.GetPacketCounter();
|
||||||
EXPECT_EQ(2U, counter.num_packets);
|
EXPECT_EQ(2U, counter.num_packets);
|
||||||
EXPECT_EQ(1U, counter.num_fec_packets);
|
EXPECT_EQ(1U, counter.num_fec_packets);
|
||||||
EXPECT_EQ(0U, counter.num_recovered_packets);
|
EXPECT_EQ(0U, counter.num_recovered_packets);
|
||||||
@ -176,12 +175,11 @@ void UlpfecReceiverTest::SurvivesMaliciousPacket(const uint8_t* data,
|
|||||||
size_t length,
|
size_t length,
|
||||||
uint8_t ulpfec_payload_type) {
|
uint8_t ulpfec_payload_type) {
|
||||||
NullRecoveredPacketReceiver null_callback;
|
NullRecoveredPacketReceiver null_callback;
|
||||||
std::unique_ptr<UlpfecReceiver> receiver_fec(
|
UlpfecReceiver receiver_fec(kMediaSsrc, &null_callback, {});
|
||||||
UlpfecReceiver::Create(kMediaSsrc, &null_callback, {}));
|
|
||||||
|
|
||||||
RtpPacketReceived rtp_packet;
|
RtpPacketReceived rtp_packet;
|
||||||
ASSERT_TRUE(rtp_packet.Parse(data, length));
|
ASSERT_TRUE(rtp_packet.Parse(data, length));
|
||||||
receiver_fec->AddReceivedRedPacket(rtp_packet, ulpfec_payload_type);
|
receiver_fec.AddReceivedRedPacket(rtp_packet, ulpfec_payload_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, TwoMediaOneFec) {
|
TEST_F(UlpfecReceiverTest, TwoMediaOneFec) {
|
||||||
@ -192,7 +190,7 @@ TEST_F(UlpfecReceiverTest, TwoMediaOneFec) {
|
|||||||
std::list<ForwardErrorCorrection::Packet*> fec_packets;
|
std::list<ForwardErrorCorrection::Packet*> fec_packets;
|
||||||
EncodeFec(media_packets, kNumFecPackets, &fec_packets);
|
EncodeFec(media_packets, kNumFecPackets, &fec_packets);
|
||||||
|
|
||||||
FecPacketCounter counter = receiver_fec_->GetPacketCounter();
|
FecPacketCounter counter = receiver_fec_.GetPacketCounter();
|
||||||
EXPECT_EQ(0u, counter.num_packets);
|
EXPECT_EQ(0u, counter.num_packets);
|
||||||
EXPECT_EQ(-1, counter.first_packet_time_ms);
|
EXPECT_EQ(-1, counter.first_packet_time_ms);
|
||||||
|
|
||||||
@ -200,8 +198,8 @@ TEST_F(UlpfecReceiverTest, TwoMediaOneFec) {
|
|||||||
auto it = augmented_media_packets.begin();
|
auto it = augmented_media_packets.begin();
|
||||||
BuildAndAddRedMediaPacket(*it);
|
BuildAndAddRedMediaPacket(*it);
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
counter = receiver_fec_->GetPacketCounter();
|
counter = receiver_fec_.GetPacketCounter();
|
||||||
EXPECT_EQ(1u, counter.num_packets);
|
EXPECT_EQ(1u, counter.num_packets);
|
||||||
EXPECT_EQ(0u, counter.num_fec_packets);
|
EXPECT_EQ(0u, counter.num_fec_packets);
|
||||||
EXPECT_EQ(0u, counter.num_recovered_packets);
|
EXPECT_EQ(0u, counter.num_recovered_packets);
|
||||||
@ -213,9 +211,9 @@ TEST_F(UlpfecReceiverTest, TwoMediaOneFec) {
|
|||||||
BuildAndAddRedFecPacket(*fec_it);
|
BuildAndAddRedFecPacket(*fec_it);
|
||||||
++it;
|
++it;
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
|
|
||||||
counter = receiver_fec_->GetPacketCounter();
|
counter = receiver_fec_.GetPacketCounter();
|
||||||
EXPECT_EQ(2u, counter.num_packets);
|
EXPECT_EQ(2u, counter.num_packets);
|
||||||
EXPECT_EQ(1u, counter.num_fec_packets);
|
EXPECT_EQ(1u, counter.num_fec_packets);
|
||||||
EXPECT_EQ(1u, counter.num_recovered_packets);
|
EXPECT_EQ(1u, counter.num_recovered_packets);
|
||||||
@ -230,7 +228,7 @@ TEST_F(UlpfecReceiverTest, TwoMediaOneFecNotUsesRecoveredPackets) {
|
|||||||
std::list<ForwardErrorCorrection::Packet*> fec_packets;
|
std::list<ForwardErrorCorrection::Packet*> fec_packets;
|
||||||
EncodeFec(media_packets, kNumFecPackets, &fec_packets);
|
EncodeFec(media_packets, kNumFecPackets, &fec_packets);
|
||||||
|
|
||||||
FecPacketCounter counter = receiver_fec_->GetPacketCounter();
|
FecPacketCounter counter = receiver_fec_.GetPacketCounter();
|
||||||
EXPECT_EQ(0u, counter.num_packets);
|
EXPECT_EQ(0u, counter.num_packets);
|
||||||
EXPECT_EQ(-1, counter.first_packet_time_ms);
|
EXPECT_EQ(-1, counter.first_packet_time_ms);
|
||||||
|
|
||||||
@ -238,8 +236,8 @@ TEST_F(UlpfecReceiverTest, TwoMediaOneFecNotUsesRecoveredPackets) {
|
|||||||
auto it = augmented_media_packets.begin();
|
auto it = augmented_media_packets.begin();
|
||||||
BuildAndAddRedMediaPacket(*it, /*is_recovered=*/true);
|
BuildAndAddRedMediaPacket(*it, /*is_recovered=*/true);
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
counter = receiver_fec_->GetPacketCounter();
|
counter = receiver_fec_.GetPacketCounter();
|
||||||
EXPECT_EQ(1u, counter.num_packets);
|
EXPECT_EQ(1u, counter.num_packets);
|
||||||
EXPECT_EQ(0u, counter.num_fec_packets);
|
EXPECT_EQ(0u, counter.num_fec_packets);
|
||||||
EXPECT_EQ(0u, counter.num_recovered_packets);
|
EXPECT_EQ(0u, counter.num_recovered_packets);
|
||||||
@ -250,9 +248,9 @@ TEST_F(UlpfecReceiverTest, TwoMediaOneFecNotUsesRecoveredPackets) {
|
|||||||
auto fec_it = fec_packets.begin();
|
auto fec_it = fec_packets.begin();
|
||||||
BuildAndAddRedFecPacket(*fec_it);
|
BuildAndAddRedFecPacket(*fec_it);
|
||||||
++it;
|
++it;
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
|
|
||||||
counter = receiver_fec_->GetPacketCounter();
|
counter = receiver_fec_.GetPacketCounter();
|
||||||
EXPECT_EQ(2u, counter.num_packets);
|
EXPECT_EQ(2u, counter.num_packets);
|
||||||
EXPECT_EQ(1u, counter.num_fec_packets);
|
EXPECT_EQ(1u, counter.num_fec_packets);
|
||||||
EXPECT_EQ(0u, counter.num_recovered_packets);
|
EXPECT_EQ(0u, counter.num_recovered_packets);
|
||||||
@ -284,12 +282,12 @@ TEST_F(UlpfecReceiverTest, TwoMediaTwoFec) {
|
|||||||
auto fec_it = fec_packets.begin();
|
auto fec_it = fec_packets.begin();
|
||||||
BuildAndAddRedFecPacket(*fec_it);
|
BuildAndAddRedFecPacket(*fec_it);
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
++fec_it;
|
++fec_it;
|
||||||
BuildAndAddRedFecPacket(*fec_it);
|
BuildAndAddRedFecPacket(*fec_it);
|
||||||
++it;
|
++it;
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, TwoFramesOneFec) {
|
TEST_F(UlpfecReceiverTest, TwoFramesOneFec) {
|
||||||
@ -305,12 +303,12 @@ TEST_F(UlpfecReceiverTest, TwoFramesOneFec) {
|
|||||||
auto it = augmented_media_packets.begin();
|
auto it = augmented_media_packets.begin();
|
||||||
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
// Drop one media packet.
|
// Drop one media packet.
|
||||||
BuildAndAddRedFecPacket(fec_packets.front());
|
BuildAndAddRedFecPacket(fec_packets.front());
|
||||||
++it;
|
++it;
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, OneCompleteOneUnrecoverableFrame) {
|
TEST_F(UlpfecReceiverTest, OneCompleteOneUnrecoverableFrame) {
|
||||||
@ -327,11 +325,11 @@ TEST_F(UlpfecReceiverTest, OneCompleteOneUnrecoverableFrame) {
|
|||||||
auto it = augmented_media_packets.begin();
|
auto it = augmented_media_packets.begin();
|
||||||
BuildAndAddRedMediaPacket(*it); // First frame: one packet.
|
BuildAndAddRedMediaPacket(*it); // First frame: one packet.
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
++it;
|
++it;
|
||||||
BuildAndAddRedMediaPacket(*it); // First packet of second frame.
|
BuildAndAddRedMediaPacket(*it); // First packet of second frame.
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, MaxFramesOneFec) {
|
TEST_F(UlpfecReceiverTest, MaxFramesOneFec) {
|
||||||
@ -351,12 +349,12 @@ TEST_F(UlpfecReceiverTest, MaxFramesOneFec) {
|
|||||||
for (; it != augmented_media_packets.end(); ++it) {
|
for (; it != augmented_media_packets.end(); ++it) {
|
||||||
BuildAndAddRedMediaPacket(*it);
|
BuildAndAddRedMediaPacket(*it);
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
BuildAndAddRedFecPacket(fec_packets.front());
|
BuildAndAddRedFecPacket(fec_packets.front());
|
||||||
it = augmented_media_packets.begin();
|
it = augmented_media_packets.begin();
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, TooManyFrames) {
|
TEST_F(UlpfecReceiverTest, TooManyFrames) {
|
||||||
@ -388,7 +386,7 @@ TEST_F(UlpfecReceiverTest, PacketNotDroppedTooEarly) {
|
|||||||
|
|
||||||
BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front());
|
BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front());
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
delayed_fec = fec_packets.front();
|
delayed_fec = fec_packets.front();
|
||||||
|
|
||||||
// Fill the FEC decoder. No packets should be dropped.
|
// Fill the FEC decoder. No packets should be dropped.
|
||||||
@ -403,13 +401,13 @@ TEST_F(UlpfecReceiverTest, PacketNotDroppedTooEarly) {
|
|||||||
it != augmented_media_packets_batch2.end(); ++it) {
|
it != augmented_media_packets_batch2.end(); ++it) {
|
||||||
BuildAndAddRedMediaPacket(*it);
|
BuildAndAddRedMediaPacket(*it);
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the delayed FEC packet. One packet should be reconstructed.
|
// Add the delayed FEC packet. One packet should be reconstructed.
|
||||||
BuildAndAddRedFecPacket(delayed_fec);
|
BuildAndAddRedFecPacket(delayed_fec);
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, PacketDroppedWhenTooOld) {
|
TEST_F(UlpfecReceiverTest, PacketDroppedWhenTooOld) {
|
||||||
@ -427,7 +425,7 @@ TEST_F(UlpfecReceiverTest, PacketDroppedWhenTooOld) {
|
|||||||
|
|
||||||
BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front());
|
BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front());
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
delayed_fec = fec_packets.front();
|
delayed_fec = fec_packets.front();
|
||||||
|
|
||||||
// Fill the FEC decoder and force the last packet to be dropped.
|
// Fill the FEC decoder and force the last packet to be dropped.
|
||||||
@ -442,14 +440,14 @@ TEST_F(UlpfecReceiverTest, PacketDroppedWhenTooOld) {
|
|||||||
it != augmented_media_packets_batch2.end(); ++it) {
|
it != augmented_media_packets_batch2.end(); ++it) {
|
||||||
BuildAndAddRedMediaPacket(*it);
|
BuildAndAddRedMediaPacket(*it);
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the delayed FEC packet. No packet should be reconstructed since the
|
// Add the delayed FEC packet. No packet should be reconstructed since the
|
||||||
// first media packet of that frame has been dropped due to being too old.
|
// first media packet of that frame has been dropped due to being too old.
|
||||||
BuildAndAddRedFecPacket(delayed_fec);
|
BuildAndAddRedFecPacket(delayed_fec);
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(0);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(0);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, OldFecPacketDropped) {
|
TEST_F(UlpfecReceiverTest, OldFecPacketDropped) {
|
||||||
@ -468,7 +466,7 @@ TEST_F(UlpfecReceiverTest, OldFecPacketDropped) {
|
|||||||
// Only FEC packets inserted. No packets recoverable at this time.
|
// Only FEC packets inserted. No packets recoverable at this time.
|
||||||
BuildAndAddRedFecPacket(*it);
|
BuildAndAddRedFecPacket(*it);
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(0);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(0);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
// Move unique_ptr's to media_packets for lifetime management.
|
// Move unique_ptr's to media_packets for lifetime management.
|
||||||
media_packets.insert(media_packets.end(),
|
media_packets.insert(media_packets.end(),
|
||||||
@ -483,7 +481,7 @@ TEST_F(UlpfecReceiverTest, OldFecPacketDropped) {
|
|||||||
// returned.
|
// returned.
|
||||||
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
||||||
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, _)).Times(1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UlpfecReceiverTest, TruncatedPacketWithFBitSet) {
|
TEST_F(UlpfecReceiverTest, TruncatedPacketWithFBitSet) {
|
||||||
@ -531,12 +529,12 @@ TEST_F(UlpfecReceiverTest, MediaWithPadding) {
|
|||||||
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
BuildAndAddRedMediaPacket(augmented_media_packets.front());
|
||||||
|
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
|
|
||||||
BuildAndAddRedFecPacket(fec_packets.front());
|
BuildAndAddRedFecPacket(fec_packets.front());
|
||||||
++it;
|
++it;
|
||||||
VerifyReconstructedMediaPacket(**it, 1);
|
VerifyReconstructedMediaPacket(**it, 1);
|
||||||
receiver_fec_->ProcessReceivedFec();
|
receiver_fec_.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -11,9 +11,9 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
#include "modules/rtp_rtcp/include/ulpfec_receiver.h"
|
|
||||||
#include "modules/rtp_rtcp/source/byte_io.h"
|
#include "modules/rtp_rtcp/source/byte_io.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||||
|
#include "modules/rtp_rtcp/source/ulpfec_receiver.h"
|
||||||
#include "test/fuzzers/fuzz_data_helper.h"
|
#include "test/fuzzers/fuzz_data_helper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -36,8 +36,7 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
|||||||
uint16_t media_seq_num = ByteReader<uint16_t>::ReadLittleEndian(data + 10);
|
uint16_t media_seq_num = ByteReader<uint16_t>::ReadLittleEndian(data + 10);
|
||||||
|
|
||||||
DummyCallback callback;
|
DummyCallback callback;
|
||||||
std::unique_ptr<UlpfecReceiver> receiver(
|
UlpfecReceiver receiver(ulpfec_ssrc, &callback, {});
|
||||||
UlpfecReceiver::Create(ulpfec_ssrc, &callback, {}));
|
|
||||||
|
|
||||||
test::FuzzDataHelper fuzz_data(rtc::MakeArrayView(data, size));
|
test::FuzzDataHelper fuzz_data(rtc::MakeArrayView(data, size));
|
||||||
while (fuzz_data.CanReadBytes(kMinDataNeeded)) {
|
while (fuzz_data.CanReadBytes(kMinDataNeeded)) {
|
||||||
@ -63,10 +62,10 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
|||||||
parsed_packet.SetSsrc(media_ssrc);
|
parsed_packet.SetSsrc(media_ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
receiver->AddReceivedRedPacket(parsed_packet, 0);
|
receiver.AddReceivedRedPacket(parsed_packet, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
receiver->ProcessReceivedFec();
|
receiver.ProcessReceivedFec();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||||
#include "modules/rtp_rtcp/include/receive_statistics.h"
|
#include "modules/rtp_rtcp/include/receive_statistics.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_cvo.h"
|
#include "modules/rtp_rtcp/include/rtp_cvo.h"
|
||||||
#include "modules/rtp_rtcp/include/ulpfec_receiver.h"
|
|
||||||
#include "modules/rtp_rtcp/source/create_video_rtp_depacketizer.h"
|
#include "modules/rtp_rtcp/source/create_video_rtp_depacketizer.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
|
#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_format.h"
|
#include "modules/rtp_rtcp/source/rtp_format.h"
|
||||||
@ -34,6 +33,7 @@
|
|||||||
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
|
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
|
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
|
||||||
|
#include "modules/rtp_rtcp/source/ulpfec_receiver.h"
|
||||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
|
#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
|
||||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h"
|
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h"
|
||||||
#include "modules/video_coding/frame_object.h"
|
#include "modules/video_coding/frame_object.h"
|
||||||
@ -234,7 +234,8 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2(
|
|||||||
forced_playout_delay_max_ms_("max_ms", absl::nullopt),
|
forced_playout_delay_max_ms_("max_ms", absl::nullopt),
|
||||||
forced_playout_delay_min_ms_("min_ms", absl::nullopt),
|
forced_playout_delay_min_ms_("min_ms", absl::nullopt),
|
||||||
rtp_receive_statistics_(rtp_receive_statistics),
|
rtp_receive_statistics_(rtp_receive_statistics),
|
||||||
ulpfec_receiver_(UlpfecReceiver::Create(config->rtp.remote_ssrc,
|
ulpfec_receiver_(
|
||||||
|
std::make_unique<UlpfecReceiver>(config->rtp.remote_ssrc,
|
||||||
this,
|
this,
|
||||||
config->rtp.extensions)),
|
config->rtp.extensions)),
|
||||||
packet_sink_(config->rtp.packet_sink_),
|
packet_sink_(config->rtp.packet_sink_),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user