OLD | NEW |
(Empty) | |
| 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 <cstring> |
| 12 #include <limits> |
| 13 |
| 14 #include "webrtc/modules/video_coding/frame_object.h" |
| 15 #include "webrtc/modules/video_coding/packet_buffer.h" |
| 16 |
| 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "webrtc/base/random.h" |
| 19 |
| 20 namespace webrtc { |
| 21 namespace video_coding { |
| 22 |
| 23 class TestPacketBuffer : public ::testing::Test, |
| 24 public OnCompleteFrameCallback { |
| 25 protected: |
| 26 TestPacketBuffer() |
| 27 : rand_(0x8739211), packet_buffer_(kStartSize, kMaxSize, this) {} |
| 28 |
| 29 uint16_t Rand() { return rand_.Rand(std::numeric_limits<uint16_t>::max()); } |
| 30 |
| 31 void OnCompleteFrame(std::unique_ptr<FrameObject> frame) override { |
| 32 frames_from_callback_.emplace_back(std::move(frame)); |
| 33 } |
| 34 |
| 35 void TearDown() override { |
| 36 // All FrameObjects must be destroyed before the PacketBuffer since |
| 37 // a FrameObject will try to remove itself from the packet buffer |
| 38 // upon destruction. |
| 39 frames_from_callback_.clear(); |
| 40 } |
| 41 |
| 42 const int kStartSize = 16; |
| 43 const int kMaxSize = 64; |
| 44 |
| 45 Random rand_; |
| 46 PacketBuffer packet_buffer_; |
| 47 std::vector<std::unique_ptr<FrameObject>> frames_from_callback_; |
| 48 }; |
| 49 |
| 50 TEST_F(TestPacketBuffer, InsertOnePacket) { |
| 51 VCMPacket packet; |
| 52 packet.seqNum = Rand(); |
| 53 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 54 } |
| 55 |
| 56 TEST_F(TestPacketBuffer, InsertMultiplePackets) { |
| 57 VCMPacket packet; |
| 58 packet.seqNum = Rand(); |
| 59 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 60 ++packet.seqNum; |
| 61 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 62 ++packet.seqNum; |
| 63 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 64 } |
| 65 |
| 66 TEST_F(TestPacketBuffer, InsertDuplicatePacket) { |
| 67 VCMPacket packet; |
| 68 packet.seqNum = Rand(); |
| 69 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 70 ++packet.seqNum; |
| 71 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 72 EXPECT_FALSE(packet_buffer_.InsertPacket(packet)); |
| 73 ++packet.seqNum; |
| 74 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 75 } |
| 76 |
| 77 TEST_F(TestPacketBuffer, ExpandBuffer) { |
| 78 VCMPacket packet; |
| 79 packet.seqNum = Rand(); |
| 80 |
| 81 for (int i = 0; i < kStartSize + 1; ++i) { |
| 82 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 83 ++packet.seqNum; |
| 84 } |
| 85 } |
| 86 |
| 87 TEST_F(TestPacketBuffer, ExpandBufferOverflow) { |
| 88 VCMPacket packet; |
| 89 packet.seqNum = Rand(); |
| 90 |
| 91 for (int i = 0; i < kMaxSize; ++i) { |
| 92 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 93 ++packet.seqNum; |
| 94 } |
| 95 |
| 96 EXPECT_FALSE(packet_buffer_.InsertPacket(packet)); |
| 97 } |
| 98 |
| 99 TEST_F(TestPacketBuffer, OnePacketOneFrame) { |
| 100 VCMPacket packet; |
| 101 packet.isFirstPacket = true; |
| 102 packet.markerBit = true; |
| 103 packet.seqNum = Rand(); |
| 104 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 105 EXPECT_EQ(1UL, frames_from_callback_.size()); |
| 106 } |
| 107 |
| 108 TEST_F(TestPacketBuffer, TwoPacketsTwoFrames) { |
| 109 VCMPacket packet; |
| 110 packet.isFirstPacket = true; |
| 111 packet.markerBit = true; |
| 112 packet.seqNum = Rand(); |
| 113 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 114 ++packet.seqNum; |
| 115 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 116 EXPECT_EQ(2UL, frames_from_callback_.size()); |
| 117 } |
| 118 |
| 119 TEST_F(TestPacketBuffer, TwoPacketsOneFrames) { |
| 120 VCMPacket packet; |
| 121 packet.isFirstPacket = true; |
| 122 packet.seqNum = Rand(); |
| 123 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 124 packet.markerBit = true; |
| 125 ++packet.seqNum; |
| 126 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 127 EXPECT_EQ(1UL, frames_from_callback_.size()); |
| 128 } |
| 129 |
| 130 TEST_F(TestPacketBuffer, ThreePacketReorderingOneFrame) { |
| 131 VCMPacket packet; |
| 132 packet.isFirstPacket = true; |
| 133 packet.seqNum = Rand(); |
| 134 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 135 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 136 packet.isFirstPacket = false; |
| 137 packet.markerBit = true; |
| 138 packet.seqNum += 2; |
| 139 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 140 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 141 packet.markerBit = false; |
| 142 packet.seqNum -= 1; |
| 143 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 144 EXPECT_EQ(1UL, frames_from_callback_.size()); |
| 145 } |
| 146 |
| 147 TEST_F(TestPacketBuffer, IndexWrapOneFrame) { |
| 148 VCMPacket packet; |
| 149 packet.isFirstPacket = true; |
| 150 packet.seqNum = kStartSize - 1; |
| 151 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 152 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 153 packet.isFirstPacket = false; |
| 154 ++packet.seqNum; |
| 155 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 156 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 157 ++packet.seqNum; |
| 158 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 159 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 160 packet.markerBit = true; |
| 161 ++packet.seqNum; |
| 162 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 163 EXPECT_EQ(1UL, frames_from_callback_.size()); |
| 164 } |
| 165 |
| 166 TEST_F(TestPacketBuffer, DiscardOldPacket) { |
| 167 const uint16_t kSeqNumOffset = Rand(); |
| 168 VCMPacket packet; |
| 169 packet.seqNum = Rand(); |
| 170 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 171 packet.seqNum += 2; |
| 172 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 173 |
| 174 for (int i = 3; i < kMaxSize; ++i) { |
| 175 ++packet.seqNum; |
| 176 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 177 } |
| 178 |
| 179 ++packet.seqNum; |
| 180 EXPECT_FALSE(packet_buffer_.InsertPacket(packet)); |
| 181 packet_buffer_.ClearUpTo(kSeqNumOffset + 1); |
| 182 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 183 } |
| 184 |
| 185 TEST_F(TestPacketBuffer, DiscardMultipleOldPackets) { |
| 186 const uint16_t kSeqNumOffset = Rand(); |
| 187 VCMPacket packet; |
| 188 packet.seqNum = kSeqNumOffset; |
| 189 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 190 packet.seqNum += 2; |
| 191 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 192 |
| 193 for (int i = 3; i < kMaxSize; ++i) { |
| 194 ++packet.seqNum; |
| 195 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 196 } |
| 197 |
| 198 packet_buffer_.ClearUpTo(kSeqNumOffset + 15); |
| 199 for (int i = 0; i < 15; ++i) { |
| 200 ++packet.seqNum; |
| 201 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 202 } |
| 203 for (int i = 15; i < kMaxSize; ++i) { |
| 204 ++packet.seqNum; |
| 205 EXPECT_FALSE(packet_buffer_.InsertPacket(packet)); |
| 206 } |
| 207 } |
| 208 |
| 209 TEST_F(TestPacketBuffer, GetBitstreamFromFrame) { |
| 210 // "many bitstream, such data" with null termination. |
| 211 uint8_t many[] = {0x6d, 0x61, 0x6e, 0x79, 0x20}; |
| 212 uint8_t bitstream[] = {0x62, 0x69, 0x74, 0x73, 0x74, 0x72, |
| 213 0x65, 0x61, 0x6d, 0x2c, 0x20}; |
| 214 uint8_t such[] = {0x73, 0x75, 0x63, 0x68, 0x20}; |
| 215 uint8_t data[] = {0x64, 0x61, 0x74, 0x61, 0x0}; |
| 216 uint8_t |
| 217 result[sizeof(many) + sizeof(bitstream) + sizeof(such) + sizeof(data)]; |
| 218 |
| 219 VCMPacket packet; |
| 220 packet.isFirstPacket = true; |
| 221 packet.seqNum = 0xfffe; |
| 222 packet.dataPtr = many; |
| 223 packet.sizeBytes = sizeof(many); |
| 224 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 225 packet.isFirstPacket = false; |
| 226 ++packet.seqNum; |
| 227 packet.dataPtr = bitstream; |
| 228 packet.sizeBytes = sizeof(bitstream); |
| 229 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 230 ++packet.seqNum; |
| 231 packet.dataPtr = such; |
| 232 packet.sizeBytes = sizeof(such); |
| 233 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 234 packet.markerBit = true; |
| 235 ++packet.seqNum; |
| 236 packet.dataPtr = data; |
| 237 packet.sizeBytes = sizeof(data); |
| 238 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 239 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 240 ASSERT_EQ(1UL, frames_from_callback_.size()); |
| 241 |
| 242 EXPECT_TRUE(frames_from_callback_[0]->GetBitstream(result)); |
| 243 EXPECT_EQ( |
| 244 std::strcmp("many bitstream, such data", reinterpret_cast<char*>(result)), |
| 245 0); |
| 246 } |
| 247 |
| 248 TEST_F(TestPacketBuffer, FreeSlotsOnFrameDestruction) { |
| 249 VCMPacket packet; |
| 250 packet.isFirstPacket = true; |
| 251 packet.seqNum = Rand(); |
| 252 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 253 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 254 packet.isFirstPacket = false; |
| 255 ++packet.seqNum; |
| 256 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 257 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 258 ++packet.seqNum; |
| 259 packet.markerBit = true; |
| 260 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 261 EXPECT_EQ(1UL, frames_from_callback_.size()); |
| 262 |
| 263 frames_from_callback_.clear(); |
| 264 |
| 265 packet.isFirstPacket = true; |
| 266 packet.markerBit = false; |
| 267 packet.seqNum = Rand(); |
| 268 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 269 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 270 packet.isFirstPacket = false; |
| 271 ++packet.seqNum; |
| 272 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 273 EXPECT_EQ(0UL, frames_from_callback_.size()); |
| 274 ++packet.seqNum; |
| 275 packet.markerBit = true; |
| 276 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 277 EXPECT_EQ(1UL, frames_from_callback_.size()); |
| 278 } |
| 279 |
| 280 TEST_F(TestPacketBuffer, Flush) { |
| 281 VCMPacket packet; |
| 282 packet.isFirstPacket = true; |
| 283 packet.markerBit = true; |
| 284 packet.seqNum = Rand(); |
| 285 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 286 EXPECT_FALSE(packet_buffer_.InsertPacket(packet)); |
| 287 packet_buffer_.Flush(); |
| 288 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 289 EXPECT_EQ(2UL, frames_from_callback_.size()); |
| 290 } |
| 291 |
| 292 TEST_F(TestPacketBuffer, InvalidateFrameByFlushing) { |
| 293 VCMPacket packet; |
| 294 packet.isFirstPacket = true; |
| 295 packet.markerBit = true; |
| 296 packet.seqNum = Rand(); |
| 297 EXPECT_TRUE(packet_buffer_.InsertPacket(packet)); |
| 298 ASSERT_EQ(1UL, frames_from_callback_.size()); |
| 299 |
| 300 packet_buffer_.Flush(); |
| 301 EXPECT_FALSE(frames_from_callback_[0]->GetBitstream(nullptr)); |
| 302 } |
| 303 |
| 304 } // namespace video_coding |
| 305 } // namespace webrtc |
OLD | NEW |