| 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 |