tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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