rtp_payload_params_unittest.cc (61174B)
1 /* 2 * Copyright (c) 2018 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 "call/rtp_payload_params.h" 12 13 #include <cstdint> 14 #include <map> 15 #include <optional> 16 #include <set> 17 #include <variant> 18 #include <vector> 19 20 #include "absl/container/inlined_vector.h" 21 #include "api/field_trials.h" 22 #include "api/transport/rtp/dependency_descriptor.h" 23 #include "api/video/color_space.h" 24 #include "api/video/encoded_image.h" 25 #include "api/video/video_codec_constants.h" 26 #include "api/video/video_codec_type.h" 27 #include "api/video/video_content_type.h" 28 #include "api/video/video_frame_type.h" 29 #include "api/video/video_rotation.h" 30 #include "call/rtp_config.h" 31 #include "common_video/generic_frame_descriptor/generic_frame_info.h" 32 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h" 33 #include "modules/rtp_rtcp/source/rtp_video_header.h" 34 #include "modules/video_coding/codecs/interface/common_constants.h" 35 #include "modules/video_coding/codecs/vp8/include/vp8_globals.h" 36 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h" 37 #include "modules/video_coding/include/video_codec_interface.h" 38 #include "test/create_test_field_trials.h" 39 #include "test/gmock.h" 40 #include "test/gtest.h" 41 42 namespace webrtc { 43 namespace { 44 45 using ::testing::AllOf; 46 using ::testing::Each; 47 using ::testing::ElementsAre; 48 using ::testing::ElementsAreArray; 49 using ::testing::Eq; 50 using ::testing::Field; 51 using ::testing::IsEmpty; 52 using ::testing::Optional; 53 using ::testing::SizeIs; 54 55 using GenericDescriptorInfo = RTPVideoHeader::GenericDescriptorInfo; 56 57 constexpr uint32_t kSsrc1 = 12345; 58 constexpr uint32_t kSsrc2 = 23456; 59 constexpr int16_t kPictureId = 123; 60 constexpr int16_t kTl0PicIdx = 20; 61 constexpr uint8_t kTemporalIdx = 1; 62 constexpr int16_t kInitialPictureId1 = 222; 63 constexpr int16_t kInitialTl0PicIdx1 = 99; 64 constexpr int64_t kDontCare = 0; 65 66 TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_Vp8) { 67 RtpPayloadState state2; 68 state2.picture_id = kPictureId; 69 state2.tl0_pic_idx = kTl0PicIdx; 70 std::map<uint32_t, RtpPayloadState> states = {{kSsrc2, state2}}; 71 72 RtpPayloadParams params(kSsrc2, &state2, CreateTestFieldTrials()); 73 EncodedImage encoded_image; 74 encoded_image.rotation_ = kVideoRotation_90; 75 encoded_image.content_type_ = VideoContentType::SCREENSHARE; 76 encoded_image.SetSimulcastIndex(1); 77 78 CodecSpecificInfo codec_info; 79 codec_info.codecType = kVideoCodecVP8; 80 codec_info.codecSpecific.VP8.temporalIdx = 0; 81 codec_info.codecSpecific.VP8.keyIdx = kNoKeyIdx; 82 codec_info.codecSpecific.VP8.layerSync = false; 83 codec_info.codecSpecific.VP8.nonReference = true; 84 85 RTPVideoHeader header = 86 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 87 88 codec_info.codecType = kVideoCodecVP8; 89 codec_info.codecSpecific.VP8.temporalIdx = 1; 90 codec_info.codecSpecific.VP8.layerSync = true; 91 92 header = params.GetRtpVideoHeader(encoded_image, &codec_info, 1); 93 94 EXPECT_EQ(kVideoRotation_90, header.rotation); 95 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type); 96 EXPECT_EQ(1, header.simulcastIdx); 97 EXPECT_EQ(kVideoCodecVP8, header.codec); 98 const auto& vp8_header = 99 std::get<RTPVideoHeaderVP8>(header.video_type_header); 100 EXPECT_EQ(kPictureId + 2, vp8_header.pictureId); 101 EXPECT_EQ(kTemporalIdx, vp8_header.temporalIdx); 102 EXPECT_EQ(kTl0PicIdx + 1, vp8_header.tl0PicIdx); 103 EXPECT_EQ(kNoKeyIdx, vp8_header.keyIdx); 104 EXPECT_TRUE(vp8_header.layerSync); 105 EXPECT_TRUE(vp8_header.nonReference); 106 } 107 108 TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_Vp9) { 109 RtpPayloadState state; 110 state.picture_id = kPictureId; 111 state.tl0_pic_idx = kTl0PicIdx; 112 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 113 114 EncodedImage encoded_image; 115 encoded_image.rotation_ = kVideoRotation_90; 116 encoded_image.content_type_ = VideoContentType::SCREENSHARE; 117 encoded_image.SetSpatialIndex(0); 118 CodecSpecificInfo codec_info; 119 codec_info.codecType = kVideoCodecVP9; 120 codec_info.codecSpecific.VP9.num_spatial_layers = 3; 121 codec_info.codecSpecific.VP9.first_frame_in_picture = true; 122 codec_info.codecSpecific.VP9.temporal_idx = 2; 123 codec_info.end_of_picture = false; 124 125 RTPVideoHeader header = 126 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 127 128 EXPECT_EQ(kVideoRotation_90, header.rotation); 129 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type); 130 EXPECT_EQ(kVideoCodecVP9, header.codec); 131 EXPECT_FALSE(header.color_space); 132 const auto& vp9_header = 133 std::get<RTPVideoHeaderVP9>(header.video_type_header); 134 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id); 135 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx); 136 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx); 137 EXPECT_EQ(vp9_header.spatial_idx, encoded_image.SpatialIndex()); 138 EXPECT_EQ(vp9_header.num_spatial_layers, 139 codec_info.codecSpecific.VP9.num_spatial_layers); 140 EXPECT_EQ(vp9_header.end_of_picture, codec_info.end_of_picture); 141 142 // Next spatial layer. 143 codec_info.codecSpecific.VP9.first_frame_in_picture = false; 144 codec_info.end_of_picture = true; 145 146 encoded_image.SetSpatialIndex(1); 147 ColorSpace color_space( 148 ColorSpace::PrimaryID::kSMPTE170M, ColorSpace::TransferID::kSMPTE170M, 149 ColorSpace::MatrixID::kSMPTE170M, ColorSpace::RangeID::kFull); 150 encoded_image.SetColorSpace(color_space); 151 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 152 153 EXPECT_EQ(kVideoRotation_90, header.rotation); 154 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type); 155 EXPECT_EQ(kVideoCodecVP9, header.codec); 156 EXPECT_EQ(std::make_optional(color_space), header.color_space); 157 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id); 158 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx); 159 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx); 160 EXPECT_EQ(vp9_header.spatial_idx, encoded_image.SpatialIndex()); 161 EXPECT_EQ(vp9_header.num_spatial_layers, 162 codec_info.codecSpecific.VP9.num_spatial_layers); 163 EXPECT_EQ(vp9_header.end_of_picture, codec_info.end_of_picture); 164 } 165 166 TEST(RtpPayloadParamsTest, PictureIdIsSetForVp8) { 167 RtpPayloadState state; 168 state.picture_id = kInitialPictureId1; 169 state.tl0_pic_idx = kInitialTl0PicIdx1; 170 171 EncodedImage encoded_image; 172 CodecSpecificInfo codec_info; 173 codec_info.codecType = kVideoCodecVP8; 174 175 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 176 RTPVideoHeader header = 177 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 178 EXPECT_EQ(kVideoCodecVP8, header.codec); 179 EXPECT_EQ(kInitialPictureId1 + 1, 180 std::get<RTPVideoHeaderVP8>(header.video_type_header).pictureId); 181 182 // State should hold latest used picture id and tl0_pic_idx. 183 state = params.state(); 184 EXPECT_EQ(kInitialPictureId1 + 1, state.picture_id); 185 EXPECT_EQ(kInitialTl0PicIdx1 + 1, state.tl0_pic_idx); 186 } 187 188 TEST(RtpPayloadParamsTest, PictureIdWraps) { 189 RtpPayloadState state; 190 state.picture_id = kMaxTwoBytePictureId; 191 state.tl0_pic_idx = kInitialTl0PicIdx1; 192 193 EncodedImage encoded_image; 194 CodecSpecificInfo codec_info; 195 codec_info.codecType = kVideoCodecVP8; 196 codec_info.codecSpecific.VP8.temporalIdx = kNoTemporalIdx; 197 198 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 199 RTPVideoHeader header = 200 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 201 EXPECT_EQ(kVideoCodecVP8, header.codec); 202 EXPECT_EQ(0, std::get<RTPVideoHeaderVP8>(header.video_type_header).pictureId); 203 204 // State should hold latest used picture id and tl0_pic_idx. 205 EXPECT_EQ(0, params.state().picture_id); // Wrapped. 206 EXPECT_EQ(kInitialTl0PicIdx1, params.state().tl0_pic_idx); 207 } 208 209 TEST(RtpPayloadParamsTest, CreatesGenericDescriptorForVp8) { 210 constexpr auto kSwitch = DecodeTargetIndication::kSwitch; 211 constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; 212 213 RtpPayloadState state; 214 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 215 216 EncodedImage key_frame_image; 217 key_frame_image._frameType = VideoFrameType::kVideoFrameKey; 218 CodecSpecificInfo key_frame_info; 219 key_frame_info.codecType = kVideoCodecVP8; 220 key_frame_info.codecSpecific.VP8.temporalIdx = 0; 221 RTPVideoHeader key_frame_header = params.GetRtpVideoHeader( 222 key_frame_image, &key_frame_info, /*shared_frame_id=*/123); 223 224 EncodedImage delta_t1_image; 225 delta_t1_image._frameType = VideoFrameType::kVideoFrameDelta; 226 CodecSpecificInfo delta_t1_info; 227 delta_t1_info.codecType = kVideoCodecVP8; 228 delta_t1_info.codecSpecific.VP8.temporalIdx = 1; 229 RTPVideoHeader delta_t1_header = params.GetRtpVideoHeader( 230 delta_t1_image, &delta_t1_info, /*shared_frame_id=*/124); 231 232 EncodedImage delta_t0_image; 233 delta_t0_image._frameType = VideoFrameType::kVideoFrameDelta; 234 CodecSpecificInfo delta_t0_info; 235 delta_t0_info.codecType = kVideoCodecVP8; 236 delta_t0_info.codecSpecific.VP8.temporalIdx = 0; 237 RTPVideoHeader delta_t0_header = params.GetRtpVideoHeader( 238 delta_t0_image, &delta_t0_info, /*shared_frame_id=*/125); 239 240 EXPECT_THAT( 241 key_frame_header, 242 AllOf(Field(&RTPVideoHeader::codec, kVideoCodecVP8), 243 Field(&RTPVideoHeader::frame_type, VideoFrameType::kVideoFrameKey), 244 Field(&RTPVideoHeader::generic, 245 Optional(AllOf( 246 Field(&GenericDescriptorInfo::frame_id, 123), 247 Field(&GenericDescriptorInfo::spatial_index, 0), 248 Field(&GenericDescriptorInfo::temporal_index, 0), 249 Field(&GenericDescriptorInfo::decode_target_indications, 250 ElementsAre(kSwitch, kSwitch, kSwitch, kSwitch)), 251 Field(&GenericDescriptorInfo::dependencies, IsEmpty()), 252 Field(&GenericDescriptorInfo::chain_diffs, 253 ElementsAre(0))))))); 254 255 EXPECT_THAT( 256 delta_t1_header, 257 AllOf( 258 Field(&RTPVideoHeader::codec, kVideoCodecVP8), 259 Field(&RTPVideoHeader::frame_type, VideoFrameType::kVideoFrameDelta), 260 Field( 261 &RTPVideoHeader::generic, 262 Optional(AllOf( 263 Field(&GenericDescriptorInfo::frame_id, 124), 264 Field(&GenericDescriptorInfo::spatial_index, 0), 265 Field(&GenericDescriptorInfo::temporal_index, 1), 266 Field(&GenericDescriptorInfo::decode_target_indications, 267 ElementsAre(kNotPresent, kSwitch, kSwitch, kSwitch)), 268 Field(&GenericDescriptorInfo::dependencies, ElementsAre(123)), 269 Field(&GenericDescriptorInfo::chain_diffs, 270 ElementsAre(1))))))); 271 272 EXPECT_THAT( 273 delta_t0_header, 274 AllOf( 275 Field(&RTPVideoHeader::codec, kVideoCodecVP8), 276 Field(&RTPVideoHeader::frame_type, VideoFrameType::kVideoFrameDelta), 277 Field( 278 &RTPVideoHeader::generic, 279 Optional(AllOf( 280 Field(&GenericDescriptorInfo::frame_id, 125), 281 Field(&GenericDescriptorInfo::spatial_index, 0), 282 Field(&GenericDescriptorInfo::temporal_index, 0), 283 Field(&GenericDescriptorInfo::decode_target_indications, 284 ElementsAre(kSwitch, kSwitch, kSwitch, kSwitch)), 285 Field(&GenericDescriptorInfo::dependencies, ElementsAre(123)), 286 Field(&GenericDescriptorInfo::chain_diffs, 287 ElementsAre(2))))))); 288 } 289 290 TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp8) { 291 RtpPayloadState state; 292 state.picture_id = kInitialPictureId1; 293 state.tl0_pic_idx = kInitialTl0PicIdx1; 294 295 EncodedImage encoded_image; 296 // Modules are sending for this test. 297 // OnEncodedImage, temporalIdx: 1. 298 CodecSpecificInfo codec_info; 299 codec_info.codecType = kVideoCodecVP8; 300 codec_info.codecSpecific.VP8.temporalIdx = 1; 301 302 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 303 RTPVideoHeader header = 304 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 305 306 EXPECT_EQ(kVideoCodecVP8, header.codec); 307 const auto& vp8_header = 308 std::get<RTPVideoHeaderVP8>(header.video_type_header); 309 EXPECT_EQ(kInitialPictureId1 + 1, vp8_header.pictureId); 310 EXPECT_EQ(kInitialTl0PicIdx1, vp8_header.tl0PicIdx); 311 312 // OnEncodedImage, temporalIdx: 0. 313 codec_info.codecSpecific.VP8.temporalIdx = 0; 314 315 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 316 EXPECT_EQ(kVideoCodecVP8, header.codec); 317 EXPECT_EQ(kInitialPictureId1 + 2, vp8_header.pictureId); 318 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp8_header.tl0PicIdx); 319 320 // State should hold latest used picture id and tl0_pic_idx. 321 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id); 322 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx); 323 } 324 325 TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp9) { 326 RtpPayloadState state; 327 state.picture_id = kInitialPictureId1; 328 state.tl0_pic_idx = kInitialTl0PicIdx1; 329 330 EncodedImage encoded_image; 331 // Modules are sending for this test. 332 // OnEncodedImage, temporalIdx: 1. 333 CodecSpecificInfo codec_info; 334 codec_info.codecType = kVideoCodecVP9; 335 codec_info.codecSpecific.VP9.temporal_idx = 1; 336 codec_info.codecSpecific.VP9.first_frame_in_picture = true; 337 338 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 339 RTPVideoHeader header = 340 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 341 342 EXPECT_EQ(kVideoCodecVP9, header.codec); 343 const auto& vp9_header = 344 std::get<RTPVideoHeaderVP9>(header.video_type_header); 345 EXPECT_EQ(kInitialPictureId1 + 1, vp9_header.picture_id); 346 EXPECT_EQ(kInitialTl0PicIdx1, vp9_header.tl0_pic_idx); 347 348 // OnEncodedImage, temporalIdx: 0. 349 codec_info.codecSpecific.VP9.temporal_idx = 0; 350 351 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 352 353 EXPECT_EQ(kVideoCodecVP9, header.codec); 354 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id); 355 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx); 356 357 // OnEncodedImage, first_frame_in_picture = false 358 codec_info.codecSpecific.VP9.first_frame_in_picture = false; 359 360 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); 361 362 EXPECT_EQ(kVideoCodecVP9, header.codec); 363 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id); 364 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx); 365 366 // State should hold latest used picture id and tl0_pic_idx. 367 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id); 368 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx); 369 } 370 371 TEST(RtpPayloadParamsTest, GenerateFrameIdWhenExternalFrameIdsAreNotProvided) { 372 RtpPayloadState state; 373 state.frame_id = 123; 374 375 EncodedImage encoded_image; 376 encoded_image._frameType = VideoFrameType::kVideoFrameKey; 377 CodecSpecificInfo codec_info; 378 codec_info.codecType = kVideoCodecGeneric; 379 380 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 381 RTPVideoHeader header = 382 params.GetRtpVideoHeader(encoded_image, &codec_info, std::nullopt); 383 384 EXPECT_THAT(header.codec, Eq(kVideoCodecGeneric)); 385 386 ASSERT_TRUE(header.generic); 387 EXPECT_THAT(header.generic->frame_id, Eq(123)); 388 389 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 390 header = params.GetRtpVideoHeader(encoded_image, &codec_info, std::nullopt); 391 ASSERT_TRUE(header.generic); 392 EXPECT_THAT(header.generic->frame_id, Eq(124)); 393 } 394 395 TEST(RtpPayloadParamsTest, PictureIdForOldGenericFormat) { 396 FieldTrials field_trials = 397 CreateTestFieldTrials("WebRTC-GenericPictureId/Enabled/"); 398 RtpPayloadState state{}; 399 400 EncodedImage encoded_image; 401 CodecSpecificInfo codec_info; 402 codec_info.codecType = kVideoCodecGeneric; 403 encoded_image._frameType = VideoFrameType::kVideoFrameKey; 404 405 RtpPayloadParams params(kSsrc1, &state, field_trials); 406 RTPVideoHeader header = 407 params.GetRtpVideoHeader(encoded_image, &codec_info, 10); 408 409 EXPECT_EQ(kVideoCodecGeneric, header.codec); 410 const auto* generic = 411 std::get_if<RTPVideoHeaderLegacyGeneric>(&header.video_type_header); 412 ASSERT_TRUE(generic); 413 EXPECT_EQ(0, generic->picture_id); 414 415 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 416 header = params.GetRtpVideoHeader(encoded_image, &codec_info, 20); 417 generic = std::get_if<RTPVideoHeaderLegacyGeneric>(&header.video_type_header); 418 ASSERT_TRUE(generic); 419 EXPECT_EQ(1, generic->picture_id); 420 } 421 422 TEST(RtpPayloadParamsTest, GenericDescriptorForGenericCodec) { 423 RtpPayloadState state; 424 425 EncodedImage encoded_image; 426 encoded_image._frameType = VideoFrameType::kVideoFrameKey; 427 CodecSpecificInfo codec_info; 428 codec_info.codecType = kVideoCodecGeneric; 429 430 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 431 RTPVideoHeader header = 432 params.GetRtpVideoHeader(encoded_image, &codec_info, 0); 433 434 EXPECT_THAT(header.codec, Eq(kVideoCodecGeneric)); 435 436 ASSERT_TRUE(header.generic); 437 EXPECT_THAT(header.generic->frame_id, Eq(0)); 438 EXPECT_THAT(header.generic->spatial_index, Eq(0)); 439 EXPECT_THAT(header.generic->temporal_index, Eq(0)); 440 EXPECT_THAT(header.generic->decode_target_indications, 441 ElementsAre(DecodeTargetIndication::kSwitch)); 442 EXPECT_THAT(header.generic->dependencies, IsEmpty()); 443 EXPECT_THAT(header.generic->chain_diffs, ElementsAre(0)); 444 445 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 446 header = params.GetRtpVideoHeader(encoded_image, &codec_info, 3); 447 ASSERT_TRUE(header.generic); 448 EXPECT_THAT(header.generic->frame_id, Eq(3)); 449 EXPECT_THAT(header.generic->spatial_index, Eq(0)); 450 EXPECT_THAT(header.generic->temporal_index, Eq(0)); 451 EXPECT_THAT(header.generic->dependencies, ElementsAre(0)); 452 EXPECT_THAT(header.generic->decode_target_indications, 453 ElementsAre(DecodeTargetIndication::kSwitch)); 454 EXPECT_THAT(header.generic->chain_diffs, ElementsAre(3)); 455 } 456 457 TEST(RtpPayloadParamsTest, SetsGenericFromGenericFrameInfo) { 458 RtpPayloadState state; 459 EncodedImage encoded_image; 460 CodecSpecificInfo codec_info; 461 462 RtpPayloadParams params(kSsrc1, &state, CreateTestFieldTrials()); 463 464 encoded_image._frameType = VideoFrameType::kVideoFrameKey; 465 codec_info.generic_frame_info = 466 GenericFrameInfo::Builder().S(1).T(0).Dtis("S").Build(); 467 codec_info.generic_frame_info->encoder_buffers = { 468 {/*id=*/0, /*referenced=*/false, /*updated=*/true}}; 469 codec_info.generic_frame_info->part_of_chain = {true, false}; 470 RTPVideoHeader key_header = 471 params.GetRtpVideoHeader(encoded_image, &codec_info, /*frame_id=*/1); 472 473 ASSERT_TRUE(key_header.generic); 474 EXPECT_EQ(key_header.generic->spatial_index, 1); 475 EXPECT_EQ(key_header.generic->temporal_index, 0); 476 EXPECT_EQ(key_header.generic->frame_id, 1); 477 EXPECT_THAT(key_header.generic->dependencies, IsEmpty()); 478 EXPECT_THAT(key_header.generic->decode_target_indications, 479 ElementsAre(DecodeTargetIndication::kSwitch)); 480 EXPECT_THAT(key_header.generic->chain_diffs, SizeIs(2)); 481 482 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 483 codec_info.generic_frame_info = 484 GenericFrameInfo::Builder().S(2).T(3).Dtis("D").Build(); 485 codec_info.generic_frame_info->encoder_buffers = { 486 {/*id=*/0, /*referenced=*/true, /*updated=*/false}}; 487 codec_info.generic_frame_info->part_of_chain = {false, false}; 488 RTPVideoHeader delta_header = 489 params.GetRtpVideoHeader(encoded_image, &codec_info, /*frame_id=*/3); 490 491 ASSERT_TRUE(delta_header.generic); 492 EXPECT_EQ(delta_header.generic->spatial_index, 2); 493 EXPECT_EQ(delta_header.generic->temporal_index, 3); 494 EXPECT_EQ(delta_header.generic->frame_id, 3); 495 EXPECT_THAT(delta_header.generic->dependencies, ElementsAre(1)); 496 EXPECT_THAT(delta_header.generic->decode_target_indications, 497 ElementsAre(DecodeTargetIndication::kDiscardable)); 498 EXPECT_THAT(delta_header.generic->chain_diffs, SizeIs(2)); 499 } 500 501 class RtpPayloadParamsVp8ToGenericTest : public ::testing::Test { 502 public: 503 enum LayerSync { kNoSync, kSync }; 504 505 RtpPayloadParamsVp8ToGenericTest() 506 : state_(), params_(123, &state_, CreateTestFieldTrials()) {} 507 508 void ConvertAndCheck(int temporal_index, 509 int64_t shared_frame_id, 510 VideoFrameType frame_type, 511 LayerSync layer_sync, 512 const std::set<int64_t>& expected_deps, 513 uint16_t width = 0, 514 uint16_t height = 0) { 515 EncodedImage encoded_image; 516 encoded_image._frameType = frame_type; 517 encoded_image._encodedWidth = width; 518 encoded_image._encodedHeight = height; 519 520 CodecSpecificInfo codec_info; 521 codec_info.codecType = kVideoCodecVP8; 522 codec_info.codecSpecific.VP8.temporalIdx = temporal_index; 523 codec_info.codecSpecific.VP8.layerSync = layer_sync == kSync; 524 525 RTPVideoHeader header = 526 params_.GetRtpVideoHeader(encoded_image, &codec_info, shared_frame_id); 527 528 ASSERT_TRUE(header.generic); 529 EXPECT_EQ(header.generic->spatial_index, 0); 530 531 EXPECT_EQ(header.generic->frame_id, shared_frame_id); 532 EXPECT_EQ(header.generic->temporal_index, temporal_index); 533 std::set<int64_t> actual_deps(header.generic->dependencies.begin(), 534 header.generic->dependencies.end()); 535 EXPECT_EQ(expected_deps, actual_deps); 536 537 EXPECT_EQ(header.width, width); 538 EXPECT_EQ(header.height, height); 539 } 540 541 protected: 542 RtpPayloadState state_; 543 RtpPayloadParams params_; 544 }; 545 546 TEST_F(RtpPayloadParamsVp8ToGenericTest, Keyframe) { 547 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 548 ConvertAndCheck(0, 1, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 549 ConvertAndCheck(0, 2, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 550 } 551 552 TEST_F(RtpPayloadParamsVp8ToGenericTest, TooHighTemporalIndex) { 553 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 554 555 EncodedImage encoded_image; 556 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 557 CodecSpecificInfo codec_info; 558 codec_info.codecType = kVideoCodecVP8; 559 codec_info.codecSpecific.VP8.temporalIdx = 560 RtpGenericFrameDescriptor::kMaxTemporalLayers; 561 codec_info.codecSpecific.VP8.layerSync = false; 562 563 RTPVideoHeader header = 564 params_.GetRtpVideoHeader(encoded_image, &codec_info, 1); 565 EXPECT_FALSE(header.generic); 566 } 567 568 TEST_F(RtpPayloadParamsVp8ToGenericTest, LayerSync) { 569 // 02120212 pattern 570 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 571 ConvertAndCheck(2, 1, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 572 ConvertAndCheck(1, 2, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 573 ConvertAndCheck(2, 3, VideoFrameType::kVideoFrameDelta, kNoSync, {0, 1, 2}); 574 575 ConvertAndCheck(0, 4, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 576 ConvertAndCheck(2, 5, VideoFrameType::kVideoFrameDelta, kNoSync, {2, 3, 4}); 577 ConvertAndCheck(1, 6, VideoFrameType::kVideoFrameDelta, kSync, 578 {4}); // layer sync 579 ConvertAndCheck(2, 7, VideoFrameType::kVideoFrameDelta, kNoSync, {4, 5, 6}); 580 } 581 582 TEST_F(RtpPayloadParamsVp8ToGenericTest, FrameIdGaps) { 583 // 0101 pattern 584 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 585 ConvertAndCheck(1, 1, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 586 587 ConvertAndCheck(0, 5, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 588 ConvertAndCheck(1, 10, VideoFrameType::kVideoFrameDelta, kNoSync, {1, 5}); 589 590 ConvertAndCheck(0, 15, VideoFrameType::kVideoFrameDelta, kNoSync, {5}); 591 ConvertAndCheck(1, 20, VideoFrameType::kVideoFrameDelta, kNoSync, {10, 15}); 592 } 593 594 TEST(RtpPayloadParamsVp9ToGenericTest, NoScalability) { 595 RtpPayloadState state; 596 RtpPayloadParams params(/*ssrc=*/123, &state, CreateTestFieldTrials()); 597 598 EncodedImage encoded_image; 599 CodecSpecificInfo codec_info; 600 codec_info.codecType = kVideoCodecVP9; 601 codec_info.codecSpecific.VP9.flexible_mode = true; 602 codec_info.codecSpecific.VP9.num_spatial_layers = 1; 603 codec_info.codecSpecific.VP9.temporal_idx = kNoTemporalIdx; 604 codec_info.codecSpecific.VP9.first_frame_in_picture = true; 605 codec_info.end_of_picture = true; 606 607 // Key frame. 608 encoded_image._frameType = VideoFrameType::kVideoFrameKey; 609 codec_info.codecSpecific.VP9.inter_pic_predicted = false; 610 codec_info.codecSpecific.VP9.num_ref_pics = 0; 611 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info, 612 /*shared_frame_id=*/1); 613 614 ASSERT_TRUE(header.generic); 615 EXPECT_EQ(header.generic->spatial_index, 0); 616 EXPECT_EQ(header.generic->temporal_index, 0); 617 EXPECT_EQ(header.generic->frame_id, 1); 618 ASSERT_THAT(header.generic->decode_target_indications, Not(IsEmpty())); 619 EXPECT_EQ(header.generic->decode_target_indications[0], 620 DecodeTargetIndication::kSwitch); 621 EXPECT_THAT(header.generic->dependencies, IsEmpty()); 622 ASSERT_THAT(header.generic->chain_diffs, Not(IsEmpty())); 623 EXPECT_EQ(header.generic->chain_diffs[0], 0); 624 625 // Delta frame. 626 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 627 codec_info.codecSpecific.VP9.inter_pic_predicted = true; 628 codec_info.codecSpecific.VP9.num_ref_pics = 1; 629 codec_info.codecSpecific.VP9.p_diff[0] = 1; 630 header = params.GetRtpVideoHeader(encoded_image, &codec_info, 631 /*shared_frame_id=*/3); 632 633 ASSERT_TRUE(header.generic); 634 EXPECT_EQ(header.generic->spatial_index, 0); 635 EXPECT_EQ(header.generic->temporal_index, 0); 636 EXPECT_EQ(header.generic->frame_id, 3); 637 ASSERT_THAT(header.generic->decode_target_indications, Not(IsEmpty())); 638 EXPECT_EQ(header.generic->decode_target_indications[0], 639 DecodeTargetIndication::kSwitch); 640 EXPECT_THAT(header.generic->dependencies, ElementsAre(1)); 641 ASSERT_THAT(header.generic->chain_diffs, Not(IsEmpty())); 642 // previous frame in the chain was frame#1, 643 EXPECT_EQ(header.generic->chain_diffs[0], 3 - 1); 644 } 645 646 TEST(RtpPayloadParamsVp9ToGenericTest, NoScalabilityNonFlexibleMode) { 647 RtpPayloadState state; 648 RtpPayloadParams params(/*ssrc=*/123, &state, CreateTestFieldTrials()); 649 650 EncodedImage encoded_image; 651 CodecSpecificInfo codec_info; 652 codec_info.codecType = kVideoCodecVP9; 653 codec_info.codecSpecific.VP9.flexible_mode = false; 654 codec_info.codecSpecific.VP9.num_spatial_layers = 1; 655 codec_info.codecSpecific.VP9.temporal_idx = kNoTemporalIdx; 656 codec_info.codecSpecific.VP9.first_frame_in_picture = true; 657 codec_info.end_of_picture = true; 658 659 // Key frame. 660 encoded_image._frameType = VideoFrameType::kVideoFrameKey; 661 codec_info.codecSpecific.VP9.inter_pic_predicted = false; 662 RTPVideoHeader key_header = 663 params.GetRtpVideoHeader(encoded_image, &codec_info, 664 /*shared_frame_id=*/1); 665 666 ASSERT_TRUE(key_header.generic); 667 EXPECT_EQ(key_header.generic->spatial_index, 0); 668 EXPECT_EQ(key_header.generic->temporal_index, 0); 669 EXPECT_EQ(key_header.generic->frame_id, 1); 670 ASSERT_THAT(key_header.generic->decode_target_indications, Not(IsEmpty())); 671 EXPECT_EQ(key_header.generic->decode_target_indications[0], 672 DecodeTargetIndication::kSwitch); 673 EXPECT_THAT(key_header.generic->dependencies, IsEmpty()); 674 ASSERT_THAT(key_header.generic->chain_diffs, Not(IsEmpty())); 675 EXPECT_EQ(key_header.generic->chain_diffs[0], 0); 676 677 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 678 codec_info.codecSpecific.VP9.inter_pic_predicted = true; 679 RTPVideoHeader delta_header = 680 params.GetRtpVideoHeader(encoded_image, &codec_info, 681 /*shared_frame_id=*/3); 682 683 ASSERT_TRUE(delta_header.generic); 684 EXPECT_EQ(delta_header.generic->spatial_index, 0); 685 EXPECT_EQ(delta_header.generic->temporal_index, 0); 686 EXPECT_EQ(delta_header.generic->frame_id, 3); 687 ASSERT_THAT(delta_header.generic->decode_target_indications, Not(IsEmpty())); 688 EXPECT_EQ(delta_header.generic->decode_target_indications[0], 689 DecodeTargetIndication::kSwitch); 690 EXPECT_THAT(delta_header.generic->dependencies, ElementsAre(1)); 691 ASSERT_THAT(delta_header.generic->chain_diffs, Not(IsEmpty())); 692 EXPECT_EQ(delta_header.generic->chain_diffs[0], 3 - 1); 693 } 694 695 TEST(RtpPayloadParamsVp9ToGenericTest, TemporalScalabilityWith2Layers) { 696 // Test with 2 temporal layers structure that is not used by webrtc: 697 // 1---3 5 698 // / / / ... 699 // 0---2---4--- 700 RtpPayloadState state; 701 RtpPayloadParams params(/*ssrc=*/123, &state, CreateTestFieldTrials()); 702 703 EncodedImage image; 704 CodecSpecificInfo info; 705 info.codecType = kVideoCodecVP9; 706 info.codecSpecific.VP9.flexible_mode = true; 707 info.codecSpecific.VP9.num_spatial_layers = 1; 708 info.codecSpecific.VP9.first_frame_in_picture = true; 709 info.end_of_picture = true; 710 711 RTPVideoHeader headers[6]; 712 // Key frame. 713 image._frameType = VideoFrameType::kVideoFrameKey; 714 info.codecSpecific.VP9.inter_pic_predicted = false; 715 info.codecSpecific.VP9.num_ref_pics = 0; 716 info.codecSpecific.VP9.temporal_up_switch = true; 717 info.codecSpecific.VP9.temporal_idx = 0; 718 headers[0] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/1); 719 720 // Delta frames. 721 info.codecSpecific.VP9.inter_pic_predicted = true; 722 image._frameType = VideoFrameType::kVideoFrameDelta; 723 724 info.codecSpecific.VP9.temporal_up_switch = true; 725 info.codecSpecific.VP9.temporal_idx = 1; 726 info.codecSpecific.VP9.num_ref_pics = 1; 727 info.codecSpecific.VP9.p_diff[0] = 1; 728 headers[1] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/3); 729 730 info.codecSpecific.VP9.temporal_up_switch = false; 731 info.codecSpecific.VP9.temporal_idx = 0; 732 info.codecSpecific.VP9.num_ref_pics = 1; 733 info.codecSpecific.VP9.p_diff[0] = 2; 734 headers[2] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/5); 735 736 info.codecSpecific.VP9.temporal_up_switch = false; 737 info.codecSpecific.VP9.temporal_idx = 1; 738 info.codecSpecific.VP9.num_ref_pics = 2; 739 info.codecSpecific.VP9.p_diff[0] = 1; 740 info.codecSpecific.VP9.p_diff[1] = 2; 741 headers[3] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/7); 742 743 info.codecSpecific.VP9.temporal_up_switch = true; 744 info.codecSpecific.VP9.temporal_idx = 0; 745 info.codecSpecific.VP9.num_ref_pics = 1; 746 info.codecSpecific.VP9.p_diff[0] = 2; 747 headers[4] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/9); 748 749 info.codecSpecific.VP9.temporal_up_switch = true; 750 info.codecSpecific.VP9.temporal_idx = 1; 751 info.codecSpecific.VP9.num_ref_pics = 1; 752 info.codecSpecific.VP9.p_diff[0] = 1; 753 headers[5] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/11); 754 755 ASSERT_TRUE(headers[0].generic); 756 int num_decode_targets = headers[0].generic->decode_target_indications.size(); 757 int num_chains = headers[0].generic->chain_diffs.size(); 758 ASSERT_GE(num_decode_targets, 2); 759 ASSERT_GE(num_chains, 1); 760 761 for (int frame_idx = 0; frame_idx < 6; ++frame_idx) { 762 const RTPVideoHeader& header = headers[frame_idx]; 763 ASSERT_TRUE(header.generic); 764 EXPECT_EQ(header.generic->spatial_index, 0); 765 EXPECT_EQ(header.generic->temporal_index, frame_idx % 2); 766 EXPECT_EQ(header.generic->frame_id, 1 + 2 * frame_idx); 767 ASSERT_THAT(header.generic->decode_target_indications, 768 SizeIs(num_decode_targets)); 769 ASSERT_THAT(header.generic->chain_diffs, SizeIs(num_chains)); 770 // Expect only T0 frames are needed for the 1st decode target. 771 if (header.generic->temporal_index == 0) { 772 EXPECT_NE(header.generic->decode_target_indications[0], 773 DecodeTargetIndication::kNotPresent); 774 } else { 775 EXPECT_EQ(header.generic->decode_target_indications[0], 776 DecodeTargetIndication::kNotPresent); 777 } 778 // Expect all frames are needed for the 2nd decode target. 779 EXPECT_NE(header.generic->decode_target_indications[1], 780 DecodeTargetIndication::kNotPresent); 781 } 782 783 // Expect switch at every beginning of the pattern. 784 EXPECT_THAT(headers[0].generic->decode_target_indications[0], 785 DecodeTargetIndication::kSwitch); 786 EXPECT_THAT(headers[0].generic->decode_target_indications[1], 787 DecodeTargetIndication::kSwitch); 788 EXPECT_THAT(headers[4].generic->decode_target_indications[0], 789 DecodeTargetIndication::kSwitch); 790 EXPECT_THAT(headers[4].generic->decode_target_indications[1], 791 DecodeTargetIndication::kSwitch); 792 793 EXPECT_THAT(headers[0].generic->dependencies, IsEmpty()); // T0, 1 794 EXPECT_THAT(headers[1].generic->dependencies, ElementsAre(1)); // T1, 3 795 EXPECT_THAT(headers[2].generic->dependencies, ElementsAre(1)); // T0, 5 796 EXPECT_THAT(headers[3].generic->dependencies, ElementsAre(5, 3)); // T1, 7 797 EXPECT_THAT(headers[4].generic->dependencies, ElementsAre(5)); // T0, 9 798 EXPECT_THAT(headers[5].generic->dependencies, ElementsAre(9)); // T1, 11 799 800 EXPECT_THAT(headers[0].generic->chain_diffs[0], Eq(0)); 801 EXPECT_THAT(headers[1].generic->chain_diffs[0], Eq(2)); 802 EXPECT_THAT(headers[2].generic->chain_diffs[0], Eq(4)); 803 EXPECT_THAT(headers[3].generic->chain_diffs[0], Eq(2)); 804 EXPECT_THAT(headers[4].generic->chain_diffs[0], Eq(4)); 805 EXPECT_THAT(headers[5].generic->chain_diffs[0], Eq(2)); 806 } 807 808 TEST(RtpPayloadParamsVp9ToGenericTest, TemporalScalabilityWith3Layers) { 809 // Test with 3 temporal layers structure that is not used by webrtc, but used 810 // by chromium: https://imgur.com/pURAGvp 811 RtpPayloadState state; 812 RtpPayloadParams params(/*ssrc=*/123, &state, CreateTestFieldTrials()); 813 814 EncodedImage image; 815 CodecSpecificInfo info; 816 info.codecType = kVideoCodecVP9; 817 info.codecSpecific.VP9.flexible_mode = true; 818 info.codecSpecific.VP9.num_spatial_layers = 1; 819 info.codecSpecific.VP9.first_frame_in_picture = true; 820 info.end_of_picture = true; 821 822 RTPVideoHeader headers[9]; 823 // Key frame. 824 image._frameType = VideoFrameType::kVideoFrameKey; 825 info.codecSpecific.VP9.inter_pic_predicted = false; 826 info.codecSpecific.VP9.num_ref_pics = 0; 827 info.codecSpecific.VP9.temporal_up_switch = true; 828 info.codecSpecific.VP9.temporal_idx = 0; 829 headers[0] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/1); 830 831 // Delta frames. 832 info.codecSpecific.VP9.inter_pic_predicted = true; 833 image._frameType = VideoFrameType::kVideoFrameDelta; 834 835 info.codecSpecific.VP9.temporal_up_switch = true; 836 info.codecSpecific.VP9.temporal_idx = 2; 837 info.codecSpecific.VP9.num_ref_pics = 1; 838 info.codecSpecific.VP9.p_diff[0] = 1; 839 headers[1] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/3); 840 841 info.codecSpecific.VP9.temporal_up_switch = true; 842 info.codecSpecific.VP9.temporal_idx = 1; 843 info.codecSpecific.VP9.num_ref_pics = 1; 844 info.codecSpecific.VP9.p_diff[0] = 2; 845 headers[2] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/5); 846 847 info.codecSpecific.VP9.temporal_up_switch = true; 848 info.codecSpecific.VP9.temporal_idx = 2; 849 info.codecSpecific.VP9.num_ref_pics = 1; 850 info.codecSpecific.VP9.p_diff[0] = 1; 851 headers[3] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/7); 852 853 info.codecSpecific.VP9.temporal_up_switch = false; 854 info.codecSpecific.VP9.temporal_idx = 0; 855 info.codecSpecific.VP9.num_ref_pics = 1; 856 info.codecSpecific.VP9.p_diff[0] = 4; 857 headers[4] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/9); 858 859 info.codecSpecific.VP9.temporal_up_switch = true; 860 info.codecSpecific.VP9.temporal_idx = 2; 861 info.codecSpecific.VP9.num_ref_pics = 2; 862 info.codecSpecific.VP9.p_diff[0] = 1; 863 info.codecSpecific.VP9.p_diff[1] = 3; 864 headers[5] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/11); 865 866 info.codecSpecific.VP9.temporal_up_switch = false; 867 info.codecSpecific.VP9.temporal_idx = 1; 868 info.codecSpecific.VP9.num_ref_pics = 2; 869 info.codecSpecific.VP9.p_diff[0] = 2; 870 info.codecSpecific.VP9.p_diff[1] = 4; 871 headers[6] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/13); 872 873 info.codecSpecific.VP9.temporal_up_switch = true; 874 info.codecSpecific.VP9.temporal_idx = 2; 875 info.codecSpecific.VP9.num_ref_pics = 1; 876 info.codecSpecific.VP9.p_diff[0] = 1; 877 headers[7] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/15); 878 879 info.codecSpecific.VP9.temporal_up_switch = true; 880 info.codecSpecific.VP9.temporal_idx = 0; 881 info.codecSpecific.VP9.num_ref_pics = 1; 882 info.codecSpecific.VP9.p_diff[0] = 4; 883 headers[8] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/17); 884 885 ASSERT_TRUE(headers[0].generic); 886 int num_decode_targets = headers[0].generic->decode_target_indications.size(); 887 int num_chains = headers[0].generic->chain_diffs.size(); 888 ASSERT_GE(num_decode_targets, 3); 889 ASSERT_GE(num_chains, 1); 890 891 for (int frame_idx = 0; frame_idx < 9; ++frame_idx) { 892 const RTPVideoHeader& header = headers[frame_idx]; 893 ASSERT_TRUE(header.generic); 894 EXPECT_EQ(header.generic->spatial_index, 0); 895 EXPECT_EQ(header.generic->frame_id, 1 + 2 * frame_idx); 896 ASSERT_THAT(header.generic->decode_target_indications, 897 SizeIs(num_decode_targets)); 898 ASSERT_THAT(header.generic->chain_diffs, SizeIs(num_chains)); 899 // Expect only T0 frames are needed for the 1st decode target. 900 if (header.generic->temporal_index == 0) { 901 EXPECT_NE(header.generic->decode_target_indications[0], 902 DecodeTargetIndication::kNotPresent); 903 } else { 904 EXPECT_EQ(header.generic->decode_target_indications[0], 905 DecodeTargetIndication::kNotPresent); 906 } 907 // Expect only T0 and T1 frames are needed for the 2nd decode target. 908 if (header.generic->temporal_index <= 1) { 909 EXPECT_NE(header.generic->decode_target_indications[1], 910 DecodeTargetIndication::kNotPresent); 911 } else { 912 EXPECT_EQ(header.generic->decode_target_indications[1], 913 DecodeTargetIndication::kNotPresent); 914 } 915 // Expect all frames are needed for the 3rd decode target. 916 EXPECT_NE(header.generic->decode_target_indications[2], 917 DecodeTargetIndication::kNotPresent); 918 } 919 920 EXPECT_EQ(headers[0].generic->temporal_index, 0); 921 EXPECT_EQ(headers[1].generic->temporal_index, 2); 922 EXPECT_EQ(headers[2].generic->temporal_index, 1); 923 EXPECT_EQ(headers[3].generic->temporal_index, 2); 924 EXPECT_EQ(headers[4].generic->temporal_index, 0); 925 EXPECT_EQ(headers[5].generic->temporal_index, 2); 926 EXPECT_EQ(headers[6].generic->temporal_index, 1); 927 EXPECT_EQ(headers[7].generic->temporal_index, 2); 928 EXPECT_EQ(headers[8].generic->temporal_index, 0); 929 930 // Expect switch at every beginning of the pattern. 931 EXPECT_THAT(headers[0].generic->decode_target_indications, 932 Each(DecodeTargetIndication::kSwitch)); 933 EXPECT_THAT(headers[8].generic->decode_target_indications[0], 934 DecodeTargetIndication::kSwitch); 935 EXPECT_THAT(headers[8].generic->decode_target_indications[1], 936 DecodeTargetIndication::kSwitch); 937 EXPECT_THAT(headers[8].generic->decode_target_indications[2], 938 DecodeTargetIndication::kSwitch); 939 940 EXPECT_THAT(headers[0].generic->dependencies, IsEmpty()); // T0, 1 941 EXPECT_THAT(headers[1].generic->dependencies, ElementsAre(1)); // T2, 3 942 EXPECT_THAT(headers[2].generic->dependencies, ElementsAre(1)); // T1, 5 943 EXPECT_THAT(headers[3].generic->dependencies, ElementsAre(5)); // T2, 7 944 EXPECT_THAT(headers[4].generic->dependencies, ElementsAre(1)); // T0, 9 945 EXPECT_THAT(headers[5].generic->dependencies, ElementsAre(9, 5)); // T2, 11 946 EXPECT_THAT(headers[6].generic->dependencies, ElementsAre(9, 5)); // T1, 13 947 EXPECT_THAT(headers[7].generic->dependencies, ElementsAre(13)); // T2, 15 948 EXPECT_THAT(headers[8].generic->dependencies, ElementsAre(9)); // T0, 17 949 950 EXPECT_THAT(headers[0].generic->chain_diffs[0], Eq(0)); 951 EXPECT_THAT(headers[1].generic->chain_diffs[0], Eq(2)); 952 EXPECT_THAT(headers[2].generic->chain_diffs[0], Eq(4)); 953 EXPECT_THAT(headers[3].generic->chain_diffs[0], Eq(6)); 954 EXPECT_THAT(headers[4].generic->chain_diffs[0], Eq(8)); 955 EXPECT_THAT(headers[5].generic->chain_diffs[0], Eq(2)); 956 EXPECT_THAT(headers[6].generic->chain_diffs[0], Eq(4)); 957 EXPECT_THAT(headers[7].generic->chain_diffs[0], Eq(6)); 958 EXPECT_THAT(headers[8].generic->chain_diffs[0], Eq(8)); 959 } 960 961 TEST(RtpPayloadParamsVp9ToGenericTest, SpatialScalabilityKSvc) { 962 // 1---3-- 963 // | ... 964 // 0---2-- 965 RtpPayloadState state; 966 RtpPayloadParams params(/*ssrc=*/123, &state, CreateTestFieldTrials()); 967 968 EncodedImage image; 969 CodecSpecificInfo info; 970 info.codecType = kVideoCodecVP9; 971 info.codecSpecific.VP9.flexible_mode = true; 972 info.codecSpecific.VP9.num_spatial_layers = 2; 973 info.codecSpecific.VP9.first_frame_in_picture = true; 974 975 RTPVideoHeader headers[4]; 976 // Key frame. 977 image._frameType = VideoFrameType::kVideoFrameKey; 978 image.SetSpatialIndex(0); 979 info.codecSpecific.VP9.inter_pic_predicted = false; 980 info.codecSpecific.VP9.inter_layer_predicted = false; 981 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = false; 982 info.codecSpecific.VP9.num_ref_pics = 0; 983 info.codecSpecific.VP9.first_frame_in_picture = true; 984 info.end_of_picture = false; 985 headers[0] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/1); 986 987 image.SetSpatialIndex(1); 988 info.codecSpecific.VP9.inter_layer_predicted = true; 989 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = true; 990 info.codecSpecific.VP9.first_frame_in_picture = false; 991 info.end_of_picture = true; 992 headers[1] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/3); 993 994 // Delta frames. 995 info.codecSpecific.VP9.inter_pic_predicted = true; 996 image._frameType = VideoFrameType::kVideoFrameDelta; 997 info.codecSpecific.VP9.num_ref_pics = 1; 998 info.codecSpecific.VP9.p_diff[0] = 1; 999 1000 image.SetSpatialIndex(0); 1001 info.codecSpecific.VP9.inter_layer_predicted = false; 1002 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = true; 1003 info.codecSpecific.VP9.first_frame_in_picture = true; 1004 info.end_of_picture = false; 1005 headers[2] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/5); 1006 1007 image.SetSpatialIndex(1); 1008 info.codecSpecific.VP9.inter_layer_predicted = false; 1009 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = true; 1010 info.codecSpecific.VP9.first_frame_in_picture = false; 1011 info.end_of_picture = true; 1012 headers[3] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/7); 1013 1014 ASSERT_TRUE(headers[0].generic); 1015 int num_decode_targets = headers[0].generic->decode_target_indications.size(); 1016 // Rely on implementation detail there are always kMaxTemporalStreams temporal 1017 // layers assumed, in particular assume Decode Target#0 matches layer S0T0, 1018 // and Decode Target#kMaxTemporalStreams matches layer S1T0. 1019 ASSERT_GE(num_decode_targets, kMaxTemporalStreams * 2); 1020 int num_chains = headers[0].generic->chain_diffs.size(); 1021 ASSERT_GE(num_chains, 2); 1022 1023 for (int frame_idx = 0; frame_idx < 4; ++frame_idx) { 1024 const RTPVideoHeader& header = headers[frame_idx]; 1025 ASSERT_TRUE(header.generic); 1026 EXPECT_EQ(header.generic->spatial_index, frame_idx % 2); 1027 EXPECT_EQ(header.generic->temporal_index, 0); 1028 EXPECT_EQ(header.generic->frame_id, 1 + 2 * frame_idx); 1029 ASSERT_THAT(header.generic->decode_target_indications, 1030 SizeIs(num_decode_targets)); 1031 ASSERT_THAT(header.generic->chain_diffs, SizeIs(num_chains)); 1032 } 1033 1034 // Expect S0 key frame is switch for both Decode Targets. 1035 EXPECT_EQ(headers[0].generic->decode_target_indications[0], 1036 DecodeTargetIndication::kSwitch); 1037 EXPECT_EQ(headers[0].generic->decode_target_indications[kMaxTemporalStreams], 1038 DecodeTargetIndication::kSwitch); 1039 // S1 key frame is only needed for the 2nd Decode Targets. 1040 EXPECT_EQ(headers[1].generic->decode_target_indications[0], 1041 DecodeTargetIndication::kNotPresent); 1042 EXPECT_NE(headers[1].generic->decode_target_indications[kMaxTemporalStreams], 1043 DecodeTargetIndication::kNotPresent); 1044 // Delta frames are only needed for their own Decode Targets. 1045 EXPECT_NE(headers[2].generic->decode_target_indications[0], 1046 DecodeTargetIndication::kNotPresent); 1047 EXPECT_EQ(headers[2].generic->decode_target_indications[kMaxTemporalStreams], 1048 DecodeTargetIndication::kNotPresent); 1049 EXPECT_EQ(headers[3].generic->decode_target_indications[0], 1050 DecodeTargetIndication::kNotPresent); 1051 EXPECT_NE(headers[3].generic->decode_target_indications[kMaxTemporalStreams], 1052 DecodeTargetIndication::kNotPresent); 1053 1054 EXPECT_THAT(headers[0].generic->dependencies, IsEmpty()); // S0, 1 1055 EXPECT_THAT(headers[1].generic->dependencies, ElementsAre(1)); // S1, 3 1056 EXPECT_THAT(headers[2].generic->dependencies, ElementsAre(1)); // S0, 5 1057 EXPECT_THAT(headers[3].generic->dependencies, ElementsAre(3)); // S1, 7 1058 1059 EXPECT_THAT(headers[0].generic->chain_diffs[0], Eq(0)); 1060 EXPECT_THAT(headers[0].generic->chain_diffs[1], Eq(0)); 1061 EXPECT_THAT(headers[1].generic->chain_diffs[0], Eq(2)); 1062 EXPECT_THAT(headers[1].generic->chain_diffs[1], Eq(2)); 1063 EXPECT_THAT(headers[2].generic->chain_diffs[0], Eq(4)); 1064 EXPECT_THAT(headers[2].generic->chain_diffs[1], Eq(2)); 1065 EXPECT_THAT(headers[3].generic->chain_diffs[0], Eq(2)); 1066 EXPECT_THAT(headers[3].generic->chain_diffs[1], Eq(4)); 1067 } 1068 1069 TEST(RtpPayloadParamsVp9ToGenericTest, 1070 IncreaseNumberOfSpatialLayersOnDeltaFrame) { 1071 // S1 5-- 1072 // | ... 1073 // S0 1---3-- 1074 RtpPayloadState state; 1075 RtpPayloadParams params(/*ssrc=*/123, &state, CreateTestFieldTrials()); 1076 1077 EncodedImage image; 1078 CodecSpecificInfo info; 1079 info.codecType = kVideoCodecVP9; 1080 info.codecSpecific.VP9.flexible_mode = true; 1081 info.codecSpecific.VP9.num_spatial_layers = 1; 1082 info.codecSpecific.VP9.first_frame_in_picture = true; 1083 1084 RTPVideoHeader headers[3]; 1085 // Key frame. 1086 image._frameType = VideoFrameType::kVideoFrameKey; 1087 image.SetSpatialIndex(0); 1088 info.codecSpecific.VP9.inter_pic_predicted = false; 1089 info.codecSpecific.VP9.inter_layer_predicted = false; 1090 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = true; 1091 info.codecSpecific.VP9.num_ref_pics = 0; 1092 info.codecSpecific.VP9.first_frame_in_picture = true; 1093 info.end_of_picture = true; 1094 headers[0] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/1); 1095 1096 // S0 delta frame. 1097 image._frameType = VideoFrameType::kVideoFrameDelta; 1098 info.codecSpecific.VP9.num_spatial_layers = 2; 1099 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = false; 1100 info.codecSpecific.VP9.first_frame_in_picture = true; 1101 info.codecSpecific.VP9.inter_pic_predicted = true; 1102 info.codecSpecific.VP9.num_ref_pics = 1; 1103 info.codecSpecific.VP9.p_diff[0] = 1; 1104 info.end_of_picture = false; 1105 headers[1] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/3); 1106 1107 // S1 delta frame. 1108 image.SetSpatialIndex(1); 1109 info.codecSpecific.VP9.inter_layer_predicted = true; 1110 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = true; 1111 info.codecSpecific.VP9.first_frame_in_picture = false; 1112 info.codecSpecific.VP9.inter_pic_predicted = false; 1113 info.end_of_picture = true; 1114 headers[2] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/5); 1115 1116 ASSERT_TRUE(headers[0].generic); 1117 int num_decode_targets = headers[0].generic->decode_target_indications.size(); 1118 int num_chains = headers[0].generic->chain_diffs.size(); 1119 // Rely on implementation detail there are always kMaxTemporalStreams temporal 1120 // layers. In particular assume Decode Target#0 matches layer S0T0, and 1121 // Decode Target#kMaxTemporalStreams matches layer S1T0. 1122 static constexpr int kS0T0 = 0; 1123 static constexpr int kS1T0 = kMaxTemporalStreams; 1124 ASSERT_GE(num_decode_targets, 2); 1125 ASSERT_GE(num_chains, 2); 1126 1127 for (int frame_idx = 0; frame_idx < 3; ++frame_idx) { 1128 const RTPVideoHeader& header = headers[frame_idx]; 1129 ASSERT_TRUE(header.generic); 1130 EXPECT_EQ(header.generic->temporal_index, 0); 1131 EXPECT_EQ(header.generic->frame_id, 1 + 2 * frame_idx); 1132 ASSERT_THAT(header.generic->decode_target_indications, 1133 SizeIs(num_decode_targets)); 1134 ASSERT_THAT(header.generic->chain_diffs, SizeIs(num_chains)); 1135 } 1136 1137 EXPECT_TRUE(headers[0].generic->active_decode_targets[kS0T0]); 1138 EXPECT_FALSE(headers[0].generic->active_decode_targets[kS1T0]); 1139 1140 EXPECT_TRUE(headers[1].generic->active_decode_targets[kS0T0]); 1141 EXPECT_TRUE(headers[1].generic->active_decode_targets[kS1T0]); 1142 1143 EXPECT_TRUE(headers[2].generic->active_decode_targets[kS0T0]); 1144 EXPECT_TRUE(headers[2].generic->active_decode_targets[kS1T0]); 1145 1146 EXPECT_EQ(headers[0].generic->decode_target_indications[kS0T0], 1147 DecodeTargetIndication::kSwitch); 1148 1149 EXPECT_EQ(headers[1].generic->decode_target_indications[kS0T0], 1150 DecodeTargetIndication::kSwitch); 1151 1152 EXPECT_EQ(headers[2].generic->decode_target_indications[kS0T0], 1153 DecodeTargetIndication::kNotPresent); 1154 EXPECT_EQ(headers[2].generic->decode_target_indications[kS1T0], 1155 DecodeTargetIndication::kSwitch); 1156 1157 EXPECT_THAT(headers[0].generic->dependencies, IsEmpty()); // S0, 1 1158 EXPECT_THAT(headers[1].generic->dependencies, ElementsAre(1)); // S0, 3 1159 EXPECT_THAT(headers[2].generic->dependencies, ElementsAre(3)); // S1, 5 1160 1161 EXPECT_EQ(headers[0].generic->chain_diffs[0], 0); 1162 1163 EXPECT_EQ(headers[1].generic->chain_diffs[0], 2); 1164 EXPECT_EQ(headers[1].generic->chain_diffs[1], 0); 1165 1166 EXPECT_EQ(headers[2].generic->chain_diffs[0], 2); 1167 EXPECT_EQ(headers[2].generic->chain_diffs[1], 2); 1168 } 1169 1170 TEST(RtpPayloadParamsVp9ToGenericTest, ChangeFirstActiveLayer) { 1171 // S2 4---5 1172 // 1173 // S1 1---3 7 1174 // 1175 // S0 0---2 6 1176 RtpPayloadState state; 1177 RtpPayloadParams params(/*ssrc=*/123, &state, CreateTestFieldTrials()); 1178 1179 EncodedImage image; 1180 CodecSpecificInfo info; 1181 info.codecType = kVideoCodecVP9; 1182 info.codecSpecific.VP9.flexible_mode = true; 1183 info.codecSpecific.VP9.first_frame_in_picture = true; 1184 info.codecSpecific.VP9.inter_layer_predicted = false; 1185 info.codecSpecific.VP9.non_ref_for_inter_layer_pred = true; 1186 info.codecSpecific.VP9.first_frame_in_picture = true; 1187 info.end_of_picture = true; 1188 1189 RTPVideoHeader headers[8]; 1190 // S0 key frame. 1191 info.codecSpecific.VP9.num_spatial_layers = 2; 1192 info.codecSpecific.VP9.first_active_layer = 0; 1193 image._frameType = VideoFrameType::kVideoFrameKey; 1194 image.SetSpatialIndex(0); 1195 info.codecSpecific.VP9.inter_pic_predicted = false; 1196 info.codecSpecific.VP9.num_ref_pics = 0; 1197 headers[0] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/0); 1198 1199 // S1 key frame. 1200 image._frameType = VideoFrameType::kVideoFrameKey; 1201 image.SetSpatialIndex(1); 1202 info.codecSpecific.VP9.inter_pic_predicted = false; 1203 info.codecSpecific.VP9.num_ref_pics = 0; 1204 headers[1] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/1); 1205 1206 // S0 delta frame. 1207 image._frameType = VideoFrameType::kVideoFrameDelta; 1208 image.SetSpatialIndex(0); 1209 info.codecSpecific.VP9.inter_pic_predicted = true; 1210 info.codecSpecific.VP9.num_ref_pics = 1; 1211 info.codecSpecific.VP9.p_diff[0] = 1; 1212 headers[2] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/2); 1213 1214 // S1 delta frame. 1215 image._frameType = VideoFrameType::kVideoFrameDelta; 1216 info.codecSpecific.VP9.inter_pic_predicted = true; 1217 info.codecSpecific.VP9.num_ref_pics = 1; 1218 info.codecSpecific.VP9.p_diff[0] = 1; 1219 headers[3] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/3); 1220 1221 // S2 key frame 1222 info.codecSpecific.VP9.num_spatial_layers = 3; 1223 info.codecSpecific.VP9.first_active_layer = 2; 1224 image._frameType = VideoFrameType::kVideoFrameKey; 1225 image.SetSpatialIndex(2); 1226 info.codecSpecific.VP9.inter_pic_predicted = false; 1227 info.codecSpecific.VP9.num_ref_pics = 0; 1228 headers[4] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/4); 1229 1230 // S2 delta frame. 1231 image._frameType = VideoFrameType::kVideoFrameDelta; 1232 info.codecSpecific.VP9.inter_pic_predicted = true; 1233 info.codecSpecific.VP9.num_ref_pics = 1; 1234 info.codecSpecific.VP9.p_diff[0] = 1; 1235 headers[5] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/5); 1236 1237 // S0 key frame after pause. 1238 info.codecSpecific.VP9.num_spatial_layers = 2; 1239 info.codecSpecific.VP9.first_active_layer = 0; 1240 image._frameType = VideoFrameType::kVideoFrameKey; 1241 image.SetSpatialIndex(0); 1242 info.codecSpecific.VP9.inter_pic_predicted = false; 1243 info.codecSpecific.VP9.num_ref_pics = 0; 1244 headers[6] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/6); 1245 1246 // S1 key frame. 1247 image._frameType = VideoFrameType::kVideoFrameKey; 1248 image.SetSpatialIndex(1); 1249 info.codecSpecific.VP9.inter_pic_predicted = false; 1250 info.codecSpecific.VP9.num_ref_pics = 0; 1251 headers[7] = params.GetRtpVideoHeader(image, &info, /*shared_frame_id=*/7); 1252 1253 ASSERT_TRUE(headers[0].generic); 1254 int num_decode_targets = headers[0].generic->decode_target_indications.size(); 1255 int num_chains = headers[0].generic->chain_diffs.size(); 1256 // Rely on implementation detail there are always kMaxTemporalStreams temporal 1257 // layers. In particular assume Decode Target#0 matches layer S0T0, and 1258 // Decode Target#kMaxTemporalStreams matches layer S1T0. 1259 static constexpr int kS0T0 = 0; 1260 static constexpr int kS1T0 = kMaxTemporalStreams; 1261 static constexpr int kS2T0 = 2 * kMaxTemporalStreams; 1262 ASSERT_GE(num_decode_targets, 3); 1263 ASSERT_GE(num_chains, 3); 1264 1265 for (int frame_idx = 0; frame_idx < int{std::size(headers)}; ++frame_idx) { 1266 const RTPVideoHeader& header = headers[frame_idx]; 1267 ASSERT_TRUE(header.generic); 1268 EXPECT_EQ(header.generic->temporal_index, 0); 1269 ASSERT_THAT(header.generic->decode_target_indications, 1270 SizeIs(num_decode_targets)); 1271 ASSERT_THAT(header.generic->chain_diffs, SizeIs(num_chains)); 1272 EXPECT_EQ(header.generic->frame_id, frame_idx); 1273 } 1274 1275 EXPECT_TRUE(headers[0].generic->active_decode_targets[kS0T0]); 1276 EXPECT_TRUE(headers[0].generic->active_decode_targets[kS1T0]); 1277 EXPECT_FALSE(headers[0].generic->active_decode_targets[kS2T0]); 1278 1279 EXPECT_FALSE(headers[4].generic->active_decode_targets[kS0T0]); 1280 EXPECT_FALSE(headers[4].generic->active_decode_targets[kS1T0]); 1281 EXPECT_TRUE(headers[4].generic->active_decode_targets[kS2T0]); 1282 1283 EXPECT_EQ(headers[1].generic->active_decode_targets, 1284 headers[0].generic->active_decode_targets); 1285 1286 EXPECT_EQ(headers[2].generic->active_decode_targets, 1287 headers[0].generic->active_decode_targets); 1288 1289 EXPECT_EQ(headers[3].generic->active_decode_targets, 1290 headers[0].generic->active_decode_targets); 1291 1292 EXPECT_EQ(headers[5].generic->active_decode_targets, 1293 headers[4].generic->active_decode_targets); 1294 1295 EXPECT_EQ(headers[6].generic->active_decode_targets, 1296 headers[0].generic->active_decode_targets); 1297 1298 EXPECT_EQ(headers[7].generic->active_decode_targets, 1299 headers[0].generic->active_decode_targets); 1300 1301 EXPECT_EQ(headers[0].generic->chain_diffs[0], 0); 1302 EXPECT_EQ(headers[0].generic->chain_diffs[1], 0); 1303 EXPECT_EQ(headers[0].generic->chain_diffs[2], 0); 1304 1305 EXPECT_EQ(headers[1].generic->chain_diffs[0], 1); 1306 EXPECT_EQ(headers[1].generic->chain_diffs[1], 0); 1307 EXPECT_EQ(headers[1].generic->chain_diffs[2], 0); 1308 1309 EXPECT_EQ(headers[2].generic->chain_diffs[0], 2); 1310 EXPECT_EQ(headers[2].generic->chain_diffs[1], 1); 1311 EXPECT_EQ(headers[2].generic->chain_diffs[2], 0); 1312 1313 EXPECT_EQ(headers[3].generic->chain_diffs[0], 1); 1314 EXPECT_EQ(headers[3].generic->chain_diffs[1], 2); 1315 EXPECT_EQ(headers[3].generic->chain_diffs[2], 0); 1316 1317 EXPECT_EQ(headers[4].generic->chain_diffs[0], 0); 1318 EXPECT_EQ(headers[4].generic->chain_diffs[1], 0); 1319 EXPECT_EQ(headers[4].generic->chain_diffs[2], 0); 1320 1321 EXPECT_EQ(headers[5].generic->chain_diffs[0], 0); 1322 EXPECT_EQ(headers[5].generic->chain_diffs[1], 0); 1323 EXPECT_EQ(headers[5].generic->chain_diffs[2], 1); 1324 1325 EXPECT_EQ(headers[6].generic->chain_diffs[0], 0); 1326 EXPECT_EQ(headers[6].generic->chain_diffs[1], 0); 1327 EXPECT_EQ(headers[6].generic->chain_diffs[2], 0); 1328 1329 EXPECT_EQ(headers[7].generic->chain_diffs[0], 1); 1330 EXPECT_EQ(headers[7].generic->chain_diffs[1], 0); 1331 EXPECT_EQ(headers[7].generic->chain_diffs[2], 0); 1332 } 1333 1334 class RtpPayloadParamsH264ToGenericTest : public ::testing::Test { 1335 public: 1336 enum LayerSync { kNoSync, kSync }; 1337 1338 RtpPayloadParamsH264ToGenericTest() 1339 : state_(), params_(123, &state_, CreateTestFieldTrials()) {} 1340 1341 void ConvertAndCheck(int temporal_index, 1342 int64_t shared_frame_id, 1343 VideoFrameType frame_type, 1344 LayerSync layer_sync, 1345 const std::set<int64_t>& expected_deps, 1346 uint16_t width = 0, 1347 uint16_t height = 0, 1348 const std::vector<DecodeTargetIndication>& 1349 expected_decode_target_indication = { 1350 DecodeTargetIndication::kSwitch, 1351 DecodeTargetIndication::kSwitch, 1352 DecodeTargetIndication::kSwitch, 1353 DecodeTargetIndication::kSwitch}) { 1354 EncodedImage encoded_image; 1355 encoded_image._frameType = frame_type; 1356 encoded_image._encodedWidth = width; 1357 encoded_image._encodedHeight = height; 1358 1359 CodecSpecificInfo codec_info; 1360 codec_info.codecType = kVideoCodecH264; 1361 codec_info.codecSpecific.H264.temporal_idx = temporal_index; 1362 codec_info.codecSpecific.H264.base_layer_sync = layer_sync == kSync; 1363 1364 RTPVideoHeader header = 1365 params_.GetRtpVideoHeader(encoded_image, &codec_info, shared_frame_id); 1366 1367 ASSERT_TRUE(header.generic); 1368 EXPECT_EQ(header.generic->spatial_index, 0); 1369 1370 EXPECT_EQ(header.generic->frame_id, shared_frame_id); 1371 EXPECT_EQ(header.generic->temporal_index, temporal_index); 1372 std::set<int64_t> actual_deps(header.generic->dependencies.begin(), 1373 header.generic->dependencies.end()); 1374 EXPECT_EQ(expected_deps, actual_deps); 1375 1376 EXPECT_EQ(header.width, width); 1377 EXPECT_EQ(header.height, height); 1378 1379 EXPECT_THAT(header.generic->decode_target_indications, 1380 ElementsAreArray(expected_decode_target_indication)); 1381 } 1382 1383 protected: 1384 RtpPayloadState state_; 1385 RtpPayloadParams params_; 1386 }; 1387 1388 TEST_F(RtpPayloadParamsH264ToGenericTest, Keyframe) { 1389 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 1390 ConvertAndCheck(0, 1, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 1391 ConvertAndCheck(0, 2, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 1392 } 1393 1394 TEST_F(RtpPayloadParamsH264ToGenericTest, TooHighTemporalIndex) { 1395 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 1396 1397 EncodedImage encoded_image; 1398 encoded_image._frameType = VideoFrameType::kVideoFrameDelta; 1399 CodecSpecificInfo codec_info; 1400 codec_info.codecType = kVideoCodecH264; 1401 codec_info.codecSpecific.H264.temporal_idx = 1402 RtpGenericFrameDescriptor::kMaxTemporalLayers; 1403 codec_info.codecSpecific.H264.base_layer_sync = false; 1404 1405 RTPVideoHeader header = 1406 params_.GetRtpVideoHeader(encoded_image, &codec_info, 1); 1407 EXPECT_FALSE(header.generic); 1408 } 1409 1410 TEST_F(RtpPayloadParamsH264ToGenericTest, LayerSync) { 1411 constexpr auto kSwitch = DecodeTargetIndication::kSwitch; 1412 constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; 1413 1414 // 02120212 pattern 1415 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 1416 ConvertAndCheck(2, 1, VideoFrameType::kVideoFrameDelta, kNoSync, {0}, 0, 0, 1417 {kNotPresent, kNotPresent, kSwitch, kSwitch}); 1418 ConvertAndCheck(1, 2, VideoFrameType::kVideoFrameDelta, kNoSync, {0}, 0, 0, 1419 {kNotPresent, kSwitch, kSwitch, kSwitch}); 1420 ConvertAndCheck(2, 3, VideoFrameType::kVideoFrameDelta, kNoSync, {0, 1, 2}, 0, 1421 0, {kNotPresent, kNotPresent, kSwitch, kSwitch}); 1422 ConvertAndCheck(0, 4, VideoFrameType::kVideoFrameDelta, kNoSync, {0}, 0, 0); 1423 ConvertAndCheck(2, 5, VideoFrameType::kVideoFrameDelta, kNoSync, {2, 3, 4}, 0, 1424 0, {kNotPresent, kNotPresent, kSwitch, kSwitch}); 1425 ConvertAndCheck(1, 6, VideoFrameType::kVideoFrameDelta, kSync, {4}, 0, 0, 1426 {kNotPresent, kSwitch, kSwitch, kSwitch}); // layer sync 1427 ConvertAndCheck(2, 7, VideoFrameType::kVideoFrameDelta, kNoSync, {4, 5, 6}, 0, 1428 0, {kNotPresent, kNotPresent, kSwitch, kSwitch}); 1429 } 1430 1431 TEST_F(RtpPayloadParamsH264ToGenericTest, FrameIdGaps) { 1432 constexpr auto kSwitch = DecodeTargetIndication::kSwitch; 1433 constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent; 1434 1435 // 0101 pattern 1436 ConvertAndCheck(0, 0, VideoFrameType::kVideoFrameKey, kNoSync, {}, 480, 360); 1437 ConvertAndCheck(1, 1, VideoFrameType::kVideoFrameDelta, kNoSync, {0}, 0, 0, 1438 {kNotPresent, kSwitch, kSwitch, kSwitch}); 1439 1440 ConvertAndCheck(0, 5, VideoFrameType::kVideoFrameDelta, kNoSync, {0}); 1441 ConvertAndCheck(1, 10, VideoFrameType::kVideoFrameDelta, kNoSync, {1, 5}, 0, 1442 0, {kNotPresent, kSwitch, kSwitch, kSwitch}); 1443 1444 ConvertAndCheck(0, 15, VideoFrameType::kVideoFrameDelta, kNoSync, {5}); 1445 ConvertAndCheck(1, 20, VideoFrameType::kVideoFrameDelta, kNoSync, {10, 15}, 0, 1446 0, {kNotPresent, kSwitch, kSwitch, kSwitch}); 1447 } 1448 1449 } // namespace 1450 } // namespace webrtc