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