blob: 79dc2f1b613b4364f8a0164327ac9166c0a473b7 [file] [log] [blame]
nisseeed52bf2017-05-19 06:15:19 -07001/*
2 * Copyright (c) 2017 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "call/rtx_receive_stream.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "call/test/mock_rtp_packet_sink_interface.h"
14#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
15#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
16#include "modules/rtp_rtcp/source/rtp_packet_received.h"
17#include "test/gmock.h"
18#include "test/gtest.h"
nisseeed52bf2017-05-19 06:15:19 -070019
20namespace webrtc {
21
22namespace {
23
24using ::testing::_;
25using ::testing::StrictMock;
26
nisseeed52bf2017-05-19 06:15:19 -070027constexpr int kMediaPayloadType = 100;
28constexpr int kRtxPayloadType = 98;
nisse38644992017-08-30 04:16:40 -070029constexpr int kUnknownPayloadType = 90;
nisseeed52bf2017-05-19 06:15:19 -070030constexpr uint32_t kMediaSSRC = 0x3333333;
31constexpr uint16_t kMediaSeqno = 0x5657;
32
33constexpr uint8_t kRtxPacket[] = {
Jonas Olssona4d87372019-07-05 19:08:33 +020034 0x80, // Version 2.
35 98, // Payload type.
36 0x12,
37 0x34, // Seqno.
38 0x11,
39 0x11,
40 0x11,
41 0x11, // Timestamp.
42 0x22,
43 0x22,
44 0x22,
45 0x22, // SSRC.
nisseeed52bf2017-05-19 06:15:19 -070046 // RTX header.
Jonas Olssona4d87372019-07-05 19:08:33 +020047 0x56,
48 0x57, // Orig seqno.
nisseeed52bf2017-05-19 06:15:19 -070049 // Payload.
50 0xee,
51};
52
53constexpr uint8_t kRtxPacketWithCVO[] = {
Jonas Olssona4d87372019-07-05 19:08:33 +020054 0x90, // Version 2, X set.
55 98, // Payload type.
56 0x12,
57 0x34, // Seqno.
58 0x11,
59 0x11,
60 0x11,
61 0x11, // Timestamp.
62 0x22,
63 0x22,
64 0x22,
65 0x22, // SSRC.
66 0xbe,
67 0xde,
68 0x00,
69 0x01, // Extension header.
70 0x30,
71 0x01,
72 0x00,
73 0x00, // 90 degree rotation.
nisseeed52bf2017-05-19 06:15:19 -070074 // RTX header.
Jonas Olssona4d87372019-07-05 19:08:33 +020075 0x56,
76 0x57, // Orig seqno.
nisseeed52bf2017-05-19 06:15:19 -070077 // Payload.
78 0xee,
79};
80
81std::map<int, int> PayloadTypeMapping() {
nisse38644992017-08-30 04:16:40 -070082 const std::map<int, int> m = {{kRtxPayloadType, kMediaPayloadType}};
nisseeed52bf2017-05-19 06:15:19 -070083 return m;
84}
85
86template <typename T>
87rtc::ArrayView<T> Truncate(rtc::ArrayView<T> a, size_t drop) {
88 return a.subview(0, a.size() - drop);
89}
90
91} // namespace
92
93TEST(RtxReceiveStreamTest, RestoresPacketPayload) {
94 StrictMock<MockRtpPacketSink> media_sink;
95 RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
96 RtpPacketReceived rtx_packet;
97 EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacket)));
98
Yves Gerey665174f2018-06-19 15:03:05 +020099 EXPECT_CALL(media_sink, OnRtpPacket(_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200100 .WillOnce(::testing::Invoke([](const RtpPacketReceived& packet) {
nisseeed52bf2017-05-19 06:15:19 -0700101 EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
102 EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
103 EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200104 EXPECT_THAT(packet.payload(), ::testing::ElementsAre(0xee));
nisseeed52bf2017-05-19 06:15:19 -0700105 }));
106
107 rtx_sink.OnRtpPacket(rtx_packet);
108}
109
nisse38644992017-08-30 04:16:40 -0700110TEST(RtxReceiveStreamTest, SetsRecoveredFlag) {
111 StrictMock<MockRtpPacketSink> media_sink;
112 RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
113 RtpPacketReceived rtx_packet;
114 EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacket)));
115 EXPECT_FALSE(rtx_packet.recovered());
116 EXPECT_CALL(media_sink, OnRtpPacket(_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200117 .WillOnce(::testing::Invoke([](const RtpPacketReceived& packet) {
nisse38644992017-08-30 04:16:40 -0700118 EXPECT_TRUE(packet.recovered());
119 }));
120
121 rtx_sink.OnRtpPacket(rtx_packet);
122}
123
nisseeed52bf2017-05-19 06:15:19 -0700124TEST(RtxReceiveStreamTest, IgnoresUnknownPayloadType) {
125 StrictMock<MockRtpPacketSink> media_sink;
nisse38644992017-08-30 04:16:40 -0700126 const std::map<int, int> payload_type_mapping = {
127 {kUnknownPayloadType, kMediaPayloadType}};
128
129 RtxReceiveStream rtx_sink(&media_sink, payload_type_mapping, kMediaSSRC);
nisseeed52bf2017-05-19 06:15:19 -0700130 RtpPacketReceived rtx_packet;
131 EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacket)));
132 rtx_sink.OnRtpPacket(rtx_packet);
133}
134
135TEST(RtxReceiveStreamTest, IgnoresTruncatedPacket) {
136 StrictMock<MockRtpPacketSink> media_sink;
137 RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
138 RtpPacketReceived rtx_packet;
139 EXPECT_TRUE(
140 rtx_packet.Parse(Truncate(rtc::ArrayView<const uint8_t>(kRtxPacket), 2)));
141 rtx_sink.OnRtpPacket(rtx_packet);
142}
143
144TEST(RtxReceiveStreamTest, CopiesRtpHeaderExtensions) {
145 StrictMock<MockRtpPacketSink> media_sink;
146 RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
147 RtpHeaderExtensionMap extension_map;
148 extension_map.RegisterByType(3, kRtpExtensionVideoRotation);
149 RtpPacketReceived rtx_packet(&extension_map);
Yves Gerey665174f2018-06-19 15:03:05 +0200150 EXPECT_TRUE(
151 rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacketWithCVO)));
nisseeed52bf2017-05-19 06:15:19 -0700152
153 VideoRotation rotation = kVideoRotation_0;
154 EXPECT_TRUE(rtx_packet.GetExtension<VideoOrientation>(&rotation));
155 EXPECT_EQ(kVideoRotation_90, rotation);
156
Yves Gerey665174f2018-06-19 15:03:05 +0200157 EXPECT_CALL(media_sink, OnRtpPacket(_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200158 .WillOnce(::testing::Invoke([](const RtpPacketReceived& packet) {
nisseeed52bf2017-05-19 06:15:19 -0700159 EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
160 EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
161 EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200162 EXPECT_THAT(packet.payload(), ::testing::ElementsAre(0xee));
nisseeed52bf2017-05-19 06:15:19 -0700163 VideoRotation rotation = kVideoRotation_0;
164 EXPECT_TRUE(packet.GetExtension<VideoOrientation>(&rotation));
165 EXPECT_EQ(rotation, kVideoRotation_90);
166 }));
167
168 rtx_sink.OnRtpPacket(rtx_packet);
169}
170
171} // namespace webrtc