xref: /aosp_15_r20/external/webrtc/call/flexfec_receive_stream_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "call/flexfec_receive_stream.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <vector>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include "api/array_view.h"
18*d9f75844SAndroid Build Coastguard Worker #include "api/call/transport.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_headers.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_parameters.h"
21*d9f75844SAndroid Build Coastguard Worker #include "call/flexfec_receive_stream_impl.h"
22*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_stream_receiver_controller.h"
23*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
24*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/mocks/mock_recovered_packet_receiver.h"
25*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h"
26*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/byte_io.h"
27*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
28*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_packet_received.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
30*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
31*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
32*d9f75844SAndroid Build Coastguard Worker #include "test/mock_transport.h"
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker namespace {
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
39*d9f75844SAndroid Build Coastguard Worker 
40*d9f75844SAndroid Build Coastguard Worker constexpr uint8_t kFlexfecPlType = 118;
41*d9f75844SAndroid Build Coastguard Worker constexpr uint8_t kFlexfecSsrc[] = {0x00, 0x00, 0x00, 0x01};
42*d9f75844SAndroid Build Coastguard Worker constexpr uint8_t kMediaSsrc[] = {0x00, 0x00, 0x00, 0x02};
43*d9f75844SAndroid Build Coastguard Worker 
CreateDefaultConfig(Transport * rtcp_send_transport)44*d9f75844SAndroid Build Coastguard Worker FlexfecReceiveStream::Config CreateDefaultConfig(
45*d9f75844SAndroid Build Coastguard Worker     Transport* rtcp_send_transport) {
46*d9f75844SAndroid Build Coastguard Worker   FlexfecReceiveStream::Config config(rtcp_send_transport);
47*d9f75844SAndroid Build Coastguard Worker   config.payload_type = kFlexfecPlType;
48*d9f75844SAndroid Build Coastguard Worker   config.rtp.remote_ssrc = ByteReader<uint32_t>::ReadBigEndian(kFlexfecSsrc);
49*d9f75844SAndroid Build Coastguard Worker   config.protected_media_ssrcs = {
50*d9f75844SAndroid Build Coastguard Worker       ByteReader<uint32_t>::ReadBigEndian(kMediaSsrc)};
51*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(config.IsCompleteAndEnabled());
52*d9f75844SAndroid Build Coastguard Worker   return config;
53*d9f75844SAndroid Build Coastguard Worker }
54*d9f75844SAndroid Build Coastguard Worker 
ParsePacket(rtc::ArrayView<const uint8_t> packet)55*d9f75844SAndroid Build Coastguard Worker RtpPacketReceived ParsePacket(rtc::ArrayView<const uint8_t> packet) {
56*d9f75844SAndroid Build Coastguard Worker   RtpPacketReceived parsed_packet(nullptr);
57*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(parsed_packet.Parse(packet));
58*d9f75844SAndroid Build Coastguard Worker   return parsed_packet;
59*d9f75844SAndroid Build Coastguard Worker }
60*d9f75844SAndroid Build Coastguard Worker 
61*d9f75844SAndroid Build Coastguard Worker }  // namespace
62*d9f75844SAndroid Build Coastguard Worker 
TEST(FlexfecReceiveStreamConfigTest,IsCompleteAndEnabled)63*d9f75844SAndroid Build Coastguard Worker TEST(FlexfecReceiveStreamConfigTest, IsCompleteAndEnabled) {
64*d9f75844SAndroid Build Coastguard Worker   MockTransport rtcp_send_transport;
65*d9f75844SAndroid Build Coastguard Worker   FlexfecReceiveStream::Config config(&rtcp_send_transport);
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker   config.rtp.local_ssrc = 18374743;
68*d9f75844SAndroid Build Coastguard Worker   config.rtcp_mode = RtcpMode::kCompound;
69*d9f75844SAndroid Build Coastguard Worker   config.rtp.transport_cc = true;
70*d9f75844SAndroid Build Coastguard Worker   config.rtp.extensions.emplace_back(TransportSequenceNumber::Uri(), 7);
71*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(config.IsCompleteAndEnabled());
72*d9f75844SAndroid Build Coastguard Worker 
73*d9f75844SAndroid Build Coastguard Worker   config.payload_type = 123;
74*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(config.IsCompleteAndEnabled());
75*d9f75844SAndroid Build Coastguard Worker 
76*d9f75844SAndroid Build Coastguard Worker   config.rtp.remote_ssrc = 238423838;
77*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(config.IsCompleteAndEnabled());
78*d9f75844SAndroid Build Coastguard Worker 
79*d9f75844SAndroid Build Coastguard Worker   config.protected_media_ssrcs.push_back(138989393);
80*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(config.IsCompleteAndEnabled());
81*d9f75844SAndroid Build Coastguard Worker 
82*d9f75844SAndroid Build Coastguard Worker   config.protected_media_ssrcs.push_back(33423423);
83*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(config.IsCompleteAndEnabled());
84*d9f75844SAndroid Build Coastguard Worker }
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker class FlexfecReceiveStreamTest : public ::testing::Test {
87*d9f75844SAndroid Build Coastguard Worker  protected:
FlexfecReceiveStreamTest()88*d9f75844SAndroid Build Coastguard Worker   FlexfecReceiveStreamTest()
89*d9f75844SAndroid Build Coastguard Worker       : config_(CreateDefaultConfig(&rtcp_send_transport_)) {
90*d9f75844SAndroid Build Coastguard Worker     receive_stream_ = std::make_unique<FlexfecReceiveStreamImpl>(
91*d9f75844SAndroid Build Coastguard Worker         Clock::GetRealTimeClock(), config_, &recovered_packet_receiver_,
92*d9f75844SAndroid Build Coastguard Worker         &rtt_stats_);
93*d9f75844SAndroid Build Coastguard Worker     receive_stream_->RegisterWithTransport(&rtp_stream_receiver_controller_);
94*d9f75844SAndroid Build Coastguard Worker   }
95*d9f75844SAndroid Build Coastguard Worker 
~FlexfecReceiveStreamTest()96*d9f75844SAndroid Build Coastguard Worker   ~FlexfecReceiveStreamTest() {
97*d9f75844SAndroid Build Coastguard Worker     receive_stream_->UnregisterFromTransport();
98*d9f75844SAndroid Build Coastguard Worker   }
99*d9f75844SAndroid Build Coastguard Worker 
100*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread_;
101*d9f75844SAndroid Build Coastguard Worker   MockTransport rtcp_send_transport_;
102*d9f75844SAndroid Build Coastguard Worker   FlexfecReceiveStream::Config config_;
103*d9f75844SAndroid Build Coastguard Worker   MockRecoveredPacketReceiver recovered_packet_receiver_;
104*d9f75844SAndroid Build Coastguard Worker   MockRtcpRttStats rtt_stats_;
105*d9f75844SAndroid Build Coastguard Worker   RtpStreamReceiverController rtp_stream_receiver_controller_;
106*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<FlexfecReceiveStreamImpl> receive_stream_;
107*d9f75844SAndroid Build Coastguard Worker };
108*d9f75844SAndroid Build Coastguard Worker 
TEST_F(FlexfecReceiveStreamTest,ConstructDestruct)109*d9f75844SAndroid Build Coastguard Worker TEST_F(FlexfecReceiveStreamTest, ConstructDestruct) {}
110*d9f75844SAndroid Build Coastguard Worker 
111*d9f75844SAndroid Build Coastguard Worker // Create a FlexFEC packet that protects a single media packet and ensure
112*d9f75844SAndroid Build Coastguard Worker // that the callback is called. Correctness of recovery is checked in the
113*d9f75844SAndroid Build Coastguard Worker // FlexfecReceiver unit tests.
TEST_F(FlexfecReceiveStreamTest,RecoversPacket)114*d9f75844SAndroid Build Coastguard Worker TEST_F(FlexfecReceiveStreamTest, RecoversPacket) {
115*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kFlexfecSeqNum[] = {0x00, 0x01};
116*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kFlexfecTs[] = {0x00, 0x11, 0x22, 0x33};
117*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kMediaPlType = 107;
118*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kMediaSeqNum[] = {0x00, 0x02};
119*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kMediaTs[] = {0xaa, 0xbb, 0xcc, 0xdd};
120*d9f75844SAndroid Build Coastguard Worker 
121*d9f75844SAndroid Build Coastguard Worker   // This packet mask protects a single media packet, i.e., the FlexFEC payload
122*d9f75844SAndroid Build Coastguard Worker   // is a copy of that media packet. When inserted in the FlexFEC pipeline,
123*d9f75844SAndroid Build Coastguard Worker   // it will thus trivially recover the lost media packet.
124*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kKBit0 = 1 << 7;
125*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kFlexfecPktMask[] = {kKBit0 | 0x00, 0x01};
126*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kPayloadLength[] = {0x00, 0x04};
127*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kSsrcCount = 1;
128*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kReservedBits = 0x00;
129*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kPayloadBits = 0x00;
130*d9f75844SAndroid Build Coastguard Worker   // clang-format off
131*d9f75844SAndroid Build Coastguard Worker   constexpr uint8_t kFlexfecPacket[] = {
132*d9f75844SAndroid Build Coastguard Worker       // RTP header.
133*d9f75844SAndroid Build Coastguard Worker       0x80,            kFlexfecPlType,  kFlexfecSeqNum[0],  kFlexfecSeqNum[1],
134*d9f75844SAndroid Build Coastguard Worker       kFlexfecTs[0],   kFlexfecTs[1],   kFlexfecTs[2],      kFlexfecTs[3],
135*d9f75844SAndroid Build Coastguard Worker       kFlexfecSsrc[0], kFlexfecSsrc[1], kFlexfecSsrc[2],    kFlexfecSsrc[3],
136*d9f75844SAndroid Build Coastguard Worker       // FlexFEC header.
137*d9f75844SAndroid Build Coastguard Worker       0x00,            kMediaPlType,    kPayloadLength[0],  kPayloadLength[1],
138*d9f75844SAndroid Build Coastguard Worker       kMediaTs[0],     kMediaTs[1],     kMediaTs[2],        kMediaTs[3],
139*d9f75844SAndroid Build Coastguard Worker       kSsrcCount,      kReservedBits,   kReservedBits,      kReservedBits,
140*d9f75844SAndroid Build Coastguard Worker       kMediaSsrc[0],   kMediaSsrc[1],   kMediaSsrc[2],      kMediaSsrc[3],
141*d9f75844SAndroid Build Coastguard Worker       kMediaSeqNum[0], kMediaSeqNum[1], kFlexfecPktMask[0], kFlexfecPktMask[1],
142*d9f75844SAndroid Build Coastguard Worker       // FEC payload.
143*d9f75844SAndroid Build Coastguard Worker       kPayloadBits,    kPayloadBits,    kPayloadBits,       kPayloadBits};
144*d9f75844SAndroid Build Coastguard Worker   // clang-format on
145*d9f75844SAndroid Build Coastguard Worker 
146*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(recovered_packet_receiver_,
147*d9f75844SAndroid Build Coastguard Worker               OnRecoveredPacket(_, kRtpHeaderSize + kPayloadLength[1]));
148*d9f75844SAndroid Build Coastguard Worker 
149*d9f75844SAndroid Build Coastguard Worker   receive_stream_->OnRtpPacket(ParsePacket(kFlexfecPacket));
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   // Tear-down
152*d9f75844SAndroid Build Coastguard Worker   receive_stream_->UnregisterFromTransport();
153*d9f75844SAndroid Build Coastguard Worker }
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
156