rtp_vp8_ref_finder_unittest.cc (13938B)
1 /* 2 * Copyright (c) 2020 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 "modules/video_coding/rtp_vp8_ref_finder.h" 12 13 #include <cstdint> 14 #include <memory> 15 #include <optional> 16 #include <utility> 17 #include <vector> 18 19 #include "api/array_view.h" 20 #include "api/rtp_packet_infos.h" 21 #include "api/video/encoded_frame.h" 22 #include "api/video/encoded_image.h" 23 #include "api/video/video_codec_type.h" 24 #include "api/video/video_content_type.h" 25 #include "api/video/video_frame_type.h" 26 #include "api/video/video_rotation.h" 27 #include "api/video/video_timing.h" 28 #include "modules/rtp_rtcp/source/frame_object.h" 29 #include "modules/rtp_rtcp/source/rtp_video_header.h" 30 #include "modules/video_coding/codecs/vp8/include/vp8_globals.h" 31 #include "test/gmock.h" 32 #include "test/gtest.h" 33 34 using ::testing::Contains; 35 using ::testing::Eq; 36 using ::testing::Matcher; 37 using ::testing::Matches; 38 using ::testing::SizeIs; 39 using ::testing::UnorderedElementsAreArray; 40 41 namespace webrtc { 42 namespace { 43 44 MATCHER_P2(HasIdAndRefs, id, refs, "") { 45 return Matches(Eq(id))(arg->Id()) && 46 Matches(UnorderedElementsAreArray(refs))( 47 ArrayView<int64_t>(arg->references, arg->num_references)); 48 } 49 50 Matcher<const std::vector<std::unique_ptr<EncodedFrame>>&> 51 HasFrameWithIdAndRefs(int64_t frame_id, const std::vector<int64_t>& refs) { 52 return Contains(HasIdAndRefs(frame_id, refs)); 53 } 54 55 class Frame { 56 public: 57 Frame& AsKeyFrame(bool is_keyframe = true) { 58 is_keyframe_ = is_keyframe; 59 return *this; 60 } 61 62 Frame& Pid(int pid) { 63 picture_id_ = pid; 64 return *this; 65 } 66 67 Frame& Tid(int tid) { 68 temporal_id_ = tid; 69 return *this; 70 } 71 72 Frame& Tl0(int tl0) { 73 tl0_idx_ = tl0; 74 return *this; 75 } 76 77 Frame& AsSync(bool is_sync = true) { 78 sync = is_sync; 79 return *this; 80 } 81 82 operator std::unique_ptr<RtpFrameObject>() { 83 RTPVideoHeaderVP8 vp8_header{}; 84 vp8_header.pictureId = *picture_id_; 85 vp8_header.temporalIdx = *temporal_id_; 86 vp8_header.tl0PicIdx = *tl0_idx_; 87 vp8_header.layerSync = sync; 88 89 RTPVideoHeader video_header; 90 video_header.frame_type = is_keyframe_ ? VideoFrameType::kVideoFrameKey 91 : VideoFrameType::kVideoFrameDelta; 92 video_header.video_type_header = vp8_header; 93 // clang-format off 94 return std::make_unique<RtpFrameObject>( 95 /*seq_num_start=*/0, 96 /*seq_num_end=*/0, 97 /*markerBit=*/true, 98 /*times_nacked=*/0, 99 /*first_packet_received_time=*/0, 100 /*last_packet_received_time=*/0, 101 /*rtp_timestamp=*/0, 102 /*ntp_time_ms=*/0, 103 VideoSendTiming(), 104 /*payload_type=*/0, 105 kVideoCodecVP8, 106 kVideoRotation_0, 107 VideoContentType::UNSPECIFIED, 108 video_header, 109 /*color_space=*/std::nullopt, 110 /*frame_instrumentation_data=*/std::nullopt, 111 RtpPacketInfos(), 112 EncodedImageBuffer::Create(/*size=*/0)); 113 // clang-format on 114 } 115 116 private: 117 bool is_keyframe_ = false; 118 std::optional<int> picture_id_; 119 std::optional<int> temporal_id_; 120 std::optional<int> tl0_idx_; 121 bool sync = false; 122 }; 123 124 } // namespace 125 126 class RtpVp8RefFinderTest : public ::testing::Test { 127 protected: 128 RtpVp8RefFinderTest() : ref_finder_(std::make_unique<RtpVp8RefFinder>()) {} 129 130 void Insert(std::unique_ptr<RtpFrameObject> frame) { 131 for (auto& f : ref_finder_->ManageFrame(std::move(frame))) { 132 frames_.push_back(std::move(f)); 133 } 134 } 135 136 std::unique_ptr<RtpVp8RefFinder> ref_finder_; 137 std::vector<std::unique_ptr<EncodedFrame>> frames_; 138 }; 139 140 TEST_F(RtpVp8RefFinderTest, Vp8RepeatedFrame_0) { 141 Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame()); 142 Insert(Frame().Pid(1).Tid(0).Tl0(2)); 143 Insert(Frame().Pid(1).Tid(0).Tl0(2)); 144 145 EXPECT_THAT(frames_, SizeIs(2)); 146 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 147 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 148 } 149 150 TEST_F(RtpVp8RefFinderTest, Vp8RepeatedFrameLayerSync_01) { 151 Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame()); 152 Insert(Frame().Pid(1).Tid(1).Tl0(1).AsSync()); 153 Insert(Frame().Pid(1).Tid(1).Tl0(1).AsSync()); 154 155 EXPECT_THAT(frames_, SizeIs(2)); 156 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 157 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 158 } 159 160 TEST_F(RtpVp8RefFinderTest, Vp8RepeatedFrame_01) { 161 Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame()); 162 Insert(Frame().Pid(1).Tid(0).Tl0(2).AsSync()); 163 Insert(Frame().Pid(2).Tid(0).Tl0(3)); 164 Insert(Frame().Pid(3).Tid(0).Tl0(4)); 165 Insert(Frame().Pid(3).Tid(0).Tl0(4)); 166 167 EXPECT_THAT(frames_, SizeIs(4)); 168 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 169 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 170 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {1})); 171 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {2})); 172 } 173 174 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayers_0) { 175 Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame()); 176 Insert(Frame().Pid(1).Tid(0).Tl0(2)); 177 178 EXPECT_THAT(frames_, SizeIs(2)); 179 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 180 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 181 } 182 183 TEST_F(RtpVp8RefFinderTest, Vp8DuplicateTl1Frames) { 184 Insert(Frame().Pid(0).Tid(0).Tl0(0).AsKeyFrame()); 185 Insert(Frame().Pid(1).Tid(1).Tl0(0).AsSync()); 186 Insert(Frame().Pid(2).Tid(0).Tl0(1)); 187 Insert(Frame().Pid(3).Tid(1).Tl0(1)); 188 Insert(Frame().Pid(3).Tid(1).Tl0(1)); 189 Insert(Frame().Pid(4).Tid(0).Tl0(2)); 190 Insert(Frame().Pid(5).Tid(1).Tl0(2)); 191 192 EXPECT_THAT(frames_, SizeIs(6)); 193 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 194 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 195 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0})); 196 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1, 2})); 197 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {2})); 198 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {3, 4})); 199 } 200 201 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersReordering_0) { 202 Insert(Frame().Pid(1).Tid(0).Tl0(2)); 203 Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame()); 204 Insert(Frame().Pid(3).Tid(0).Tl0(4)); 205 Insert(Frame().Pid(2).Tid(0).Tl0(3)); 206 Insert(Frame().Pid(5).Tid(0).Tl0(6)); 207 Insert(Frame().Pid(6).Tid(0).Tl0(7)); 208 Insert(Frame().Pid(4).Tid(0).Tl0(5)); 209 210 EXPECT_THAT(frames_, SizeIs(7)); 211 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 212 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 213 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {1})); 214 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {2})); 215 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {3})); 216 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {4})); 217 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {5})); 218 } 219 220 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayers_01) { 221 Insert(Frame().Pid(0).Tid(0).Tl0(255).AsKeyFrame()); 222 Insert(Frame().Pid(1).Tid(1).Tl0(255).AsSync()); 223 Insert(Frame().Pid(2).Tid(0).Tl0(0)); 224 Insert(Frame().Pid(3).Tid(1).Tl0(0)); 225 226 EXPECT_THAT(frames_, SizeIs(4)); 227 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 228 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 229 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0})); 230 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1, 2})); 231 } 232 233 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersReordering_01) { 234 Insert(Frame().Pid(1).Tid(1).Tl0(255).AsSync()); 235 Insert(Frame().Pid(0).Tid(0).Tl0(255).AsKeyFrame()); 236 Insert(Frame().Pid(3).Tid(1).Tl0(0)); 237 Insert(Frame().Pid(5).Tid(1).Tl0(1)); 238 Insert(Frame().Pid(2).Tid(0).Tl0(0)); 239 Insert(Frame().Pid(4).Tid(0).Tl0(1)); 240 Insert(Frame().Pid(6).Tid(0).Tl0(2)); 241 Insert(Frame().Pid(7).Tid(1).Tl0(2)); 242 243 EXPECT_THAT(frames_, SizeIs(8)); 244 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 245 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 246 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0})); 247 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1, 2})); 248 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {2})); 249 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {3, 4})); 250 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {4})); 251 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {5, 6})); 252 } 253 254 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayers_0212) { 255 Insert(Frame().Pid(0).Tid(0).Tl0(55).AsKeyFrame()); 256 Insert(Frame().Pid(1).Tid(2).Tl0(55).AsSync()); 257 Insert(Frame().Pid(2).Tid(1).Tl0(55).AsSync()); 258 Insert(Frame().Pid(3).Tid(2).Tl0(55)); 259 Insert(Frame().Pid(4).Tid(0).Tl0(56)); 260 Insert(Frame().Pid(5).Tid(2).Tl0(56)); 261 Insert(Frame().Pid(6).Tid(1).Tl0(56)); 262 Insert(Frame().Pid(7).Tid(2).Tl0(56)); 263 Insert(Frame().Pid(8).Tid(0).Tl0(57)); 264 Insert(Frame().Pid(9).Tid(2).Tl0(57).AsSync()); 265 Insert(Frame().Pid(10).Tid(1).Tl0(57).AsSync()); 266 Insert(Frame().Pid(11).Tid(2).Tl0(57)); 267 268 EXPECT_THAT(frames_, SizeIs(12)); 269 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 270 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 271 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0})); 272 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {0, 1, 2})); 273 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {0})); 274 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {2, 3, 4})); 275 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {2, 4})); 276 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {4, 5, 6})); 277 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(8, {4})); 278 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(9, {8})); 279 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {8})); 280 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(11, {8, 9, 10})); 281 } 282 283 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersMissingFrame_0212) { 284 Insert(Frame().Pid(0).Tid(0).Tl0(55).AsKeyFrame()); 285 Insert(Frame().Pid(2).Tid(1).Tl0(55).AsSync()); 286 Insert(Frame().Pid(3).Tid(2).Tl0(55)); 287 288 EXPECT_THAT(frames_, SizeIs(2)); 289 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 290 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0})); 291 } 292 293 // Test with 3 temporal layers in a 0212 pattern. 294 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersReordering_0212) { 295 Insert(Frame().Pid(127).Tid(2).Tl0(55).AsSync()); 296 Insert(Frame().Pid(126).Tid(0).Tl0(55).AsKeyFrame()); 297 Insert(Frame().Pid(128).Tid(1).Tl0(55).AsSync()); 298 Insert(Frame().Pid(130).Tid(0).Tl0(56)); 299 Insert(Frame().Pid(131).Tid(2).Tl0(56)); 300 Insert(Frame().Pid(129).Tid(2).Tl0(55)); 301 Insert(Frame().Pid(133).Tid(2).Tl0(56)); 302 Insert(Frame().Pid(135).Tid(2).Tl0(57).AsSync()); 303 Insert(Frame().Pid(132).Tid(1).Tl0(56)); 304 Insert(Frame().Pid(134).Tid(0).Tl0(57)); 305 Insert(Frame().Pid(137).Tid(2).Tl0(57)); 306 Insert(Frame().Pid(136).Tid(1).Tl0(57).AsSync()); 307 308 EXPECT_THAT(frames_, SizeIs(12)); 309 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(126, {})); 310 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(127, {126})); 311 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(128, {126})); 312 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(129, {126, 127, 128})); 313 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(130, {126})); 314 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(131, {128, 129, 130})); 315 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(132, {128, 130})); 316 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(133, {130, 131, 132})); 317 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(134, {130})); 318 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(135, {134})); 319 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(136, {134})); 320 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(137, {134, 135, 136})); 321 } 322 323 TEST_F(RtpVp8RefFinderTest, Vp8LayerSync) { 324 Insert(Frame().Pid(0).Tid(0).Tl0(0).AsKeyFrame()); 325 Insert(Frame().Pid(1).Tid(1).Tl0(0).AsSync()); 326 Insert(Frame().Pid(2).Tid(0).Tl0(1)); 327 Insert(Frame().Pid(4).Tid(0).Tl0(2)); 328 Insert(Frame().Pid(5).Tid(1).Tl0(2).AsSync()); 329 Insert(Frame().Pid(6).Tid(0).Tl0(3)); 330 Insert(Frame().Pid(7).Tid(1).Tl0(3)); 331 332 EXPECT_THAT(frames_, SizeIs(7)); 333 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {})); 334 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0})); 335 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0})); 336 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {2})); 337 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {4})); 338 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {4})); 339 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {5, 6})); 340 } 341 342 TEST_F(RtpVp8RefFinderTest, Vp8Tl1SyncFrameAfterTl1Frame) { 343 Insert(Frame().Pid(1).Tid(0).Tl0(247).AsKeyFrame().AsSync()); 344 Insert(Frame().Pid(3).Tid(0).Tl0(248)); 345 Insert(Frame().Pid(4).Tid(1).Tl0(248)); 346 Insert(Frame().Pid(5).Tid(1).Tl0(248).AsSync()); 347 348 EXPECT_THAT(frames_, SizeIs(3)); 349 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {})); 350 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1})); 351 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {3})); 352 } 353 354 TEST_F(RtpVp8RefFinderTest, Vp8DetectMissingFrame_0212) { 355 Insert(Frame().Pid(1).Tid(0).Tl0(1).AsKeyFrame()); 356 Insert(Frame().Pid(2).Tid(2).Tl0(1).AsSync()); 357 Insert(Frame().Pid(3).Tid(1).Tl0(1).AsSync()); 358 Insert(Frame().Pid(4).Tid(2).Tl0(1)); 359 Insert(Frame().Pid(6).Tid(2).Tl0(2)); 360 Insert(Frame().Pid(7).Tid(1).Tl0(2)); 361 Insert(Frame().Pid(8).Tid(2).Tl0(2)); 362 Insert(Frame().Pid(5).Tid(0).Tl0(2)); 363 364 EXPECT_THAT(frames_, SizeIs(8)); 365 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {})); 366 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {1})); 367 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1})); 368 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {1, 2, 3})); 369 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {1})); 370 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {3, 4, 5})); 371 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {3, 5})); 372 EXPECT_THAT(frames_, HasFrameWithIdAndRefs(8, {5, 6, 7})); 373 } 374 375 TEST_F(RtpVp8RefFinderTest, StashedFramesDoNotWrapTl0Backwards) { 376 Insert(Frame().Pid(0).Tid(0).Tl0(0)); 377 EXPECT_THAT(frames_, SizeIs(0)); 378 379 Insert(Frame().Pid(128).Tid(0).Tl0(128).AsKeyFrame()); 380 EXPECT_THAT(frames_, SizeIs(1)); 381 Insert(Frame().Pid(129).Tid(0).Tl0(129)); 382 EXPECT_THAT(frames_, SizeIs(2)); 383 } 384 385 } // namespace webrtc