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