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