OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h" |
12 | 12 |
13 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 #include "webrtc/test/rtcp_packet_parser.h" |
| 16 |
| 17 namespace webrtc { |
| 18 namespace { |
15 | 19 |
16 using ::testing::_; | 20 using ::testing::_; |
17 using ::testing::ElementsAreArray; | 21 using ::testing::ElementsAreArray; |
18 using ::testing::Invoke; | 22 using ::testing::Invoke; |
| 23 using ::testing::make_tuple; |
19 using ::testing::UnorderedElementsAreArray; | 24 using ::testing::UnorderedElementsAreArray; |
| 25 using ::webrtc::rtcp::Nack; |
20 | 26 |
21 using webrtc::rtcp::Nack; | 27 constexpr uint32_t kSenderSsrc = 0x12345678; |
22 using webrtc::RTCPUtility::RtcpCommonHeader; | 28 constexpr uint32_t kRemoteSsrc = 0x23456789; |
23 using webrtc::RTCPUtility::RtcpParseCommonHeader; | |
24 | 29 |
25 namespace webrtc { | 30 constexpr uint16_t kList[] = {0, 1, 3, 8, 16}; |
26 namespace { | 31 constexpr size_t kListLength = sizeof(kList) / sizeof(kList[0]); |
| 32 constexpr uint8_t kVersionBits = 2 << 6; |
| 33 // clang-format off |
| 34 constexpr uint8_t kPacket[] = { |
| 35 kVersionBits | Nack::kFeedbackMessageType, Nack::kPacketType, 0, 3, |
| 36 0x12, 0x34, 0x56, 0x78, |
| 37 0x23, 0x45, 0x67, 0x89, |
| 38 0x00, 0x00, 0x80, 0x85}; |
27 | 39 |
28 const uint32_t kSenderSsrc = 0x12345678; | 40 constexpr uint16_t kWrapList[] = {0xffdc, 0xffec, 0xfffe, 0xffff, 0x0000, |
29 const uint32_t kRemoteSsrc = 0x23456789; | 41 0x0001, 0x0003, 0x0014, 0x0064}; |
30 | 42 constexpr size_t kWrapListLength = sizeof(kWrapList) / sizeof(kWrapList[0]); |
31 const uint16_t kList[] = {0, 1, 3, 8, 16}; | 43 constexpr uint8_t kWrapPacket[] = { |
32 const size_t kListLength = sizeof(kList) / sizeof(kList[0]); | 44 kVersionBits | Nack::kFeedbackMessageType, Nack::kPacketType, 0, 6, |
33 const uint8_t kPacket[] = {0x81, 205, 0x00, 0x03, 0x12, 0x34, 0x56, 0x78, | 45 0x12, 0x34, 0x56, 0x78, |
34 0x23, 0x45, 0x67, 0x89, 0x00, 0x00, 0x80, 0x85}; | 46 0x23, 0x45, 0x67, 0x89, |
35 const size_t kPacketLength = sizeof(kPacket); | 47 0xff, 0xdc, 0x80, 0x00, |
36 | 48 0xff, 0xfe, 0x00, 0x17, |
37 const uint16_t kWrapList[] = {0xffdc, 0xffec, 0xfffe, 0xffff, 0x0000, | 49 0x00, 0x14, 0x00, 0x00, |
38 0x0001, 0x0003, 0x0014, 0x0064}; | 50 0x00, 0x64, 0x00, 0x00}; |
39 const size_t kWrapListLength = sizeof(kWrapList) / sizeof(kWrapList[0]); | 51 constexpr uint8_t kTooSmallPacket[] = { |
40 const uint8_t kWrapPacket[] = {0x81, 205, 0x00, 0x06, 0x12, 0x34, 0x56, 0x78, | 52 kVersionBits | Nack::kFeedbackMessageType, Nack::kPacketType, 0, 2, |
41 0x23, 0x45, 0x67, 0x89, 0xff, 0xdc, 0x80, 0x00, | 53 0x12, 0x34, 0x56, 0x78, |
42 0xff, 0xfe, 0x00, 0x17, 0x00, 0x14, 0x00, 0x00, | 54 0x23, 0x45, 0x67, 0x89}; |
43 0x00, 0x64, 0x00, 0x00}; | 55 // clang-format on |
44 const size_t kWrapPacketLength = sizeof(kWrapPacket); | 56 } // namespace |
45 | 57 |
46 TEST(RtcpPacketNackTest, Create) { | 58 TEST(RtcpPacketNackTest, Create) { |
47 Nack nack; | 59 Nack nack; |
48 nack.From(kSenderSsrc); | 60 nack.From(kSenderSsrc); |
49 nack.To(kRemoteSsrc); | 61 nack.To(kRemoteSsrc); |
50 nack.WithList(kList, kListLength); | 62 nack.WithList(kList, kListLength); |
51 | 63 |
52 rtc::Buffer packet = nack.Build(); | 64 rtc::Buffer packet = nack.Build(); |
53 | 65 |
54 EXPECT_EQ(kPacketLength, packet.size()); | 66 EXPECT_THAT(make_tuple(packet.data(), packet.size()), |
55 EXPECT_EQ(0, memcmp(kPacket, packet.data(), kPacketLength)); | 67 ElementsAreArray(kPacket)); |
56 } | 68 } |
57 | 69 |
58 TEST(RtcpPacketNackTest, Parse) { | 70 TEST(RtcpPacketNackTest, Parse) { |
59 RtcpCommonHeader header; | |
60 EXPECT_TRUE(RtcpParseCommonHeader(kPacket, kPacketLength, &header)); | |
61 EXPECT_EQ(kPacketLength, header.BlockSize()); | |
62 Nack parsed; | 71 Nack parsed; |
63 | 72 EXPECT_TRUE(test::ParseSinglePacket(kPacket, &parsed)); |
64 EXPECT_TRUE( | |
65 parsed.Parse(header, kPacket + RtcpCommonHeader::kHeaderSizeBytes)); | |
66 const Nack& const_parsed = parsed; | 73 const Nack& const_parsed = parsed; |
67 | 74 |
68 EXPECT_EQ(kSenderSsrc, const_parsed.sender_ssrc()); | 75 EXPECT_EQ(kSenderSsrc, const_parsed.sender_ssrc()); |
69 EXPECT_EQ(kRemoteSsrc, const_parsed.media_ssrc()); | 76 EXPECT_EQ(kRemoteSsrc, const_parsed.media_ssrc()); |
70 EXPECT_THAT(const_parsed.packet_ids(), ElementsAreArray(kList)); | 77 EXPECT_THAT(const_parsed.packet_ids(), ElementsAreArray(kList)); |
71 } | 78 } |
72 | 79 |
73 TEST(RtcpPacketNackTest, CreateWrap) { | 80 TEST(RtcpPacketNackTest, CreateWrap) { |
74 Nack nack; | 81 Nack nack; |
75 nack.From(kSenderSsrc); | 82 nack.From(kSenderSsrc); |
76 nack.To(kRemoteSsrc); | 83 nack.To(kRemoteSsrc); |
77 nack.WithList(kWrapList, kWrapListLength); | 84 nack.WithList(kWrapList, kWrapListLength); |
78 | 85 |
79 rtc::Buffer packet = nack.Build(); | 86 rtc::Buffer packet = nack.Build(); |
80 | 87 |
81 EXPECT_EQ(kWrapPacketLength, packet.size()); | 88 EXPECT_THAT(make_tuple(packet.data(), packet.size()), |
82 EXPECT_EQ(0, memcmp(kWrapPacket, packet.data(), kWrapPacketLength)); | 89 ElementsAreArray(kWrapPacket)); |
83 } | 90 } |
84 | 91 |
85 TEST(RtcpPacketNackTest, ParseWrap) { | 92 TEST(RtcpPacketNackTest, ParseWrap) { |
86 RtcpCommonHeader header; | |
87 EXPECT_TRUE(RtcpParseCommonHeader(kWrapPacket, kWrapPacketLength, &header)); | |
88 EXPECT_EQ(kWrapPacketLength, header.BlockSize()); | |
89 | |
90 Nack parsed; | 93 Nack parsed; |
91 EXPECT_TRUE( | 94 EXPECT_TRUE(test::ParseSinglePacket(kWrapPacket, &parsed)); |
92 parsed.Parse(header, kWrapPacket + RtcpCommonHeader::kHeaderSizeBytes)); | |
93 | 95 |
94 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); | 96 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); |
95 EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc()); | 97 EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc()); |
96 EXPECT_THAT(parsed.packet_ids(), ElementsAreArray(kWrapList)); | 98 EXPECT_THAT(parsed.packet_ids(), ElementsAreArray(kWrapList)); |
97 } | 99 } |
98 | 100 |
99 TEST(RtcpPacketNackTest, BadOrder) { | 101 TEST(RtcpPacketNackTest, BadOrder) { |
100 // Does not guarantee optimal packing, but should guarantee correctness. | 102 // Does not guarantee optimal packing, but should guarantee correctness. |
101 const uint16_t kUnorderedList[] = {1, 25, 13, 12, 9, 27, 29}; | 103 const uint16_t kUnorderedList[] = {1, 25, 13, 12, 9, 27, 29}; |
102 const size_t kUnorderedListLength = | 104 const size_t kUnorderedListLength = |
103 sizeof(kUnorderedList) / sizeof(kUnorderedList[0]); | 105 sizeof(kUnorderedList) / sizeof(kUnorderedList[0]); |
104 Nack nack; | 106 Nack nack; |
105 nack.From(kSenderSsrc); | 107 nack.From(kSenderSsrc); |
106 nack.To(kRemoteSsrc); | 108 nack.To(kRemoteSsrc); |
107 nack.WithList(kUnorderedList, kUnorderedListLength); | 109 nack.WithList(kUnorderedList, kUnorderedListLength); |
108 | 110 |
109 rtc::Buffer packet = nack.Build(); | 111 rtc::Buffer packet = nack.Build(); |
110 | 112 |
111 Nack parsed; | 113 Nack parsed; |
112 RtcpCommonHeader header; | 114 EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed)); |
113 EXPECT_TRUE(RtcpParseCommonHeader(packet.data(), packet.size(), &header)); | |
114 EXPECT_TRUE(parsed.Parse( | |
115 header, packet.data() + RtcpCommonHeader::kHeaderSizeBytes)); | |
116 | 115 |
117 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); | 116 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); |
118 EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc()); | 117 EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc()); |
119 EXPECT_THAT(parsed.packet_ids(), UnorderedElementsAreArray(kUnorderedList)); | 118 EXPECT_THAT(parsed.packet_ids(), UnorderedElementsAreArray(kUnorderedList)); |
120 } | 119 } |
121 | 120 |
122 TEST(RtcpPacketNackTest, CreateFragmented) { | 121 TEST(RtcpPacketNackTest, CreateFragmented) { |
123 Nack nack; | 122 Nack nack; |
124 const uint16_t kList[] = {1, 100, 200, 300, 400}; | 123 const uint16_t kList[] = {1, 100, 200, 300, 400}; |
125 const uint16_t kListLength = sizeof(kList) / sizeof(kList[0]); | 124 const uint16_t kListLength = sizeof(kList) / sizeof(kList[0]); |
126 nack.From(kSenderSsrc); | 125 nack.From(kSenderSsrc); |
127 nack.To(kRemoteSsrc); | 126 nack.To(kRemoteSsrc); |
128 nack.WithList(kList, kListLength); | 127 nack.WithList(kList, kListLength); |
129 | 128 |
130 class MockPacketReadyCallback : public rtcp::RtcpPacket::PacketReadyCallback { | 129 class MockPacketReadyCallback : public rtcp::RtcpPacket::PacketReadyCallback { |
131 public: | 130 public: |
132 MOCK_METHOD2(OnPacketReady, void(uint8_t*, size_t)); | 131 MOCK_METHOD2(OnPacketReady, void(uint8_t*, size_t)); |
133 } verifier; | 132 } verifier; |
134 | 133 |
135 class NackVerifier { | 134 class NackVerifier { |
136 public: | 135 public: |
137 explicit NackVerifier(std::vector<uint16_t> ids) : ids_(ids) {} | 136 explicit NackVerifier(std::vector<uint16_t> ids) : ids_(ids) {} |
138 void operator()(uint8_t* data, size_t length) { | 137 void operator()(uint8_t* data, size_t length) { |
139 RtcpCommonHeader header; | |
140 EXPECT_TRUE(RtcpParseCommonHeader(data, length, &header)); | |
141 EXPECT_EQ(length, header.BlockSize()); | |
142 Nack nack; | 138 Nack nack; |
143 EXPECT_TRUE( | 139 EXPECT_TRUE(test::ParseSinglePacket(data, length, &nack)); |
144 nack.Parse(header, data + RtcpCommonHeader::kHeaderSizeBytes)); | |
145 EXPECT_EQ(kSenderSsrc, nack.sender_ssrc()); | 140 EXPECT_EQ(kSenderSsrc, nack.sender_ssrc()); |
146 EXPECT_EQ(kRemoteSsrc, nack.media_ssrc()); | 141 EXPECT_EQ(kRemoteSsrc, nack.media_ssrc()); |
147 EXPECT_THAT(nack.packet_ids(), ElementsAreArray(ids_)); | 142 EXPECT_THAT(nack.packet_ids(), ElementsAreArray(ids_)); |
148 } | 143 } |
149 std::vector<uint16_t> ids_; | 144 std::vector<uint16_t> ids_; |
150 } packet1({1, 100, 200}), packet2({300, 400}); | 145 } packet1({1, 100, 200}), packet2({300, 400}); |
151 | 146 |
152 EXPECT_CALL(verifier, OnPacketReady(_, _)) | 147 EXPECT_CALL(verifier, OnPacketReady(_, _)) |
153 .WillOnce(Invoke(packet1)) | 148 .WillOnce(Invoke(packet1)) |
154 .WillOnce(Invoke(packet2)); | 149 .WillOnce(Invoke(packet2)); |
(...skipping 14 matching lines...) Expand all Loading... |
169 void OnPacketReady(uint8_t* data, size_t length) override { | 164 void OnPacketReady(uint8_t* data, size_t length) override { |
170 ADD_FAILURE() << "Buffer should be too small."; | 165 ADD_FAILURE() << "Buffer should be too small."; |
171 } | 166 } |
172 } verifier; | 167 } verifier; |
173 uint8_t buffer[kMinNackBlockSize - 1]; | 168 uint8_t buffer[kMinNackBlockSize - 1]; |
174 EXPECT_FALSE( | 169 EXPECT_FALSE( |
175 nack.BuildExternalBuffer(buffer, kMinNackBlockSize - 1, &verifier)); | 170 nack.BuildExternalBuffer(buffer, kMinNackBlockSize - 1, &verifier)); |
176 } | 171 } |
177 | 172 |
178 TEST(RtcpPacketNackTest, ParseFailsWithTooSmallBuffer) { | 173 TEST(RtcpPacketNackTest, ParseFailsWithTooSmallBuffer) { |
179 RtcpCommonHeader header; | |
180 EXPECT_TRUE(RtcpParseCommonHeader(kPacket, kPacketLength, &header)); | |
181 header.payload_size_bytes--; // Damage the packet | |
182 Nack parsed; | 174 Nack parsed; |
183 EXPECT_FALSE( | 175 EXPECT_FALSE(test::ParseSinglePacket(kTooSmallPacket, &parsed)); |
184 parsed.Parse(header, kPacket + RtcpCommonHeader::kHeaderSizeBytes)); | |
185 } | 176 } |
186 | 177 |
187 } // namespace | |
188 } // namespace webrtc | 178 } // namespace webrtc |
OLD | NEW |