blob: 149bd729f5205ad413dab4fc220cab6c1e623864 [file] [log] [blame]
Stefan Holmerf7044682018-07-17 10:16:41 +02001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <string.h>
12#include <map>
philipelbf2b6202018-08-27 14:33:18 +020013#include <set>
Stefan Holmerf7044682018-07-17 10:16:41 +020014
Yves Gerey3e707812018-11-28 16:47:49 +010015#include "absl/container/inlined_vector.h"
16#include "absl/types/optional.h"
17#include "absl/types/variant.h"
18#include "api/video/video_content_type.h"
19#include "api/video/video_rotation.h"
Stefan Holmer9416ef82018-07-19 10:34:38 +020020#include "call/rtp_payload_params.h"
Yves Gerey3e707812018-11-28 16:47:49 +010021#include "common_types.h" // NOLINT(build/include)
22#include "modules/video_coding/codecs/h264/include/h264_globals.h"
23#include "modules/video_coding/codecs/interface/common_constants.h"
24#include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
25#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
Stefan Holmerf7044682018-07-17 10:16:41 +020026#include "modules/video_coding/include/video_codec_interface.h"
philipelbf2b6202018-08-27 14:33:18 +020027#include "test/field_trial.h"
Stefan Holmerf7044682018-07-17 10:16:41 +020028#include "test/gtest.h"
29
30namespace webrtc {
31namespace {
32const uint32_t kSsrc1 = 12345;
33const uint32_t kSsrc2 = 23456;
34const int16_t kPictureId = 123;
35const int16_t kTl0PicIdx = 20;
36const uint8_t kTemporalIdx = 1;
37const int16_t kInitialPictureId1 = 222;
38const int16_t kInitialTl0PicIdx1 = 99;
philipelbf2b6202018-08-27 14:33:18 +020039const int64_t kDontCare = 0;
Stefan Holmerf7044682018-07-17 10:16:41 +020040} // namespace
41
42TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_Vp8) {
43 RtpPayloadState state2;
44 state2.picture_id = kPictureId;
45 state2.tl0_pic_idx = kTl0PicIdx;
46 std::map<uint32_t, RtpPayloadState> states = {{kSsrc2, state2}};
47
48 RtpPayloadParams params(kSsrc2, &state2);
49 EncodedImage encoded_image;
50 encoded_image.rotation_ = kVideoRotation_90;
51 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
Niels Möllerd3b8c632018-08-27 15:33:42 +020052 encoded_image.SetSpatialIndex(1);
Stefan Holmerf7044682018-07-17 10:16:41 +020053
54 CodecSpecificInfo codec_info;
Stefan Holmerf7044682018-07-17 10:16:41 +020055 codec_info.codecType = kVideoCodecVP8;
philipelbf2b6202018-08-27 14:33:18 +020056 codec_info.codecSpecific.VP8.temporalIdx = 0;
Stefan Holmerf7044682018-07-17 10:16:41 +020057 codec_info.codecSpecific.VP8.keyIdx = kNoKeyIdx;
philipelbf2b6202018-08-27 14:33:18 +020058 codec_info.codecSpecific.VP8.layerSync = false;
Stefan Holmerf7044682018-07-17 10:16:41 +020059 codec_info.codecSpecific.VP8.nonReference = true;
60
philipelbf2b6202018-08-27 14:33:18 +020061 RTPVideoHeader header =
62 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
63
64 codec_info.codecType = kVideoCodecVP8;
philipelbf2b6202018-08-27 14:33:18 +020065 codec_info.codecSpecific.VP8.temporalIdx = 1;
66 codec_info.codecSpecific.VP8.layerSync = true;
67
68 header = params.GetRtpVideoHeader(encoded_image, &codec_info, 1);
Stefan Holmerf7044682018-07-17 10:16:41 +020069
70 EXPECT_EQ(kVideoRotation_90, header.rotation);
71 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
72 EXPECT_EQ(1, header.simulcastIdx);
73 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +000074 const auto& vp8_header =
75 absl::get<RTPVideoHeaderVP8>(header.video_type_header);
76 EXPECT_EQ(kPictureId + 2, vp8_header.pictureId);
77 EXPECT_EQ(kTemporalIdx, vp8_header.temporalIdx);
78 EXPECT_EQ(kTl0PicIdx + 1, vp8_header.tl0PicIdx);
79 EXPECT_EQ(kNoKeyIdx, vp8_header.keyIdx);
80 EXPECT_TRUE(vp8_header.layerSync);
81 EXPECT_TRUE(vp8_header.nonReference);
Stefan Holmerf7044682018-07-17 10:16:41 +020082}
83
84TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_Vp9) {
85 RtpPayloadState state;
86 state.picture_id = kPictureId;
87 state.tl0_pic_idx = kTl0PicIdx;
88 RtpPayloadParams params(kSsrc1, &state);
89
90 EncodedImage encoded_image;
91 encoded_image.rotation_ = kVideoRotation_90;
92 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
Niels Möllerd3b8c632018-08-27 15:33:42 +020093 encoded_image.SetSpatialIndex(0);
Stefan Holmerf7044682018-07-17 10:16:41 +020094 CodecSpecificInfo codec_info;
Stefan Holmerf7044682018-07-17 10:16:41 +020095 codec_info.codecType = kVideoCodecVP9;
96 codec_info.codecSpecific.VP9.num_spatial_layers = 3;
97 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
Stefan Holmerf7044682018-07-17 10:16:41 +020098 codec_info.codecSpecific.VP9.temporal_idx = 2;
99 codec_info.codecSpecific.VP9.end_of_picture = false;
100
philipelbf2b6202018-08-27 14:33:18 +0200101 RTPVideoHeader header =
102 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200103
104 EXPECT_EQ(kVideoRotation_90, header.rotation);
105 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
106 EXPECT_EQ(kVideoCodecVP9, header.codec);
Johannes Krond0b69a82018-12-03 14:18:53 +0100107 EXPECT_FALSE(header.color_space);
philipel29d88462018-08-08 14:26:00 +0200108 const auto& vp9_header =
109 absl::get<RTPVideoHeaderVP9>(header.video_type_header);
110 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id);
111 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx);
112 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx);
Niels Möllerd3b8c632018-08-27 15:33:42 +0200113 EXPECT_EQ(vp9_header.spatial_idx, encoded_image.SpatialIndex());
philipel29d88462018-08-08 14:26:00 +0200114 EXPECT_EQ(vp9_header.num_spatial_layers,
Stefan Holmerf7044682018-07-17 10:16:41 +0200115 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel29d88462018-08-08 14:26:00 +0200116 EXPECT_EQ(vp9_header.end_of_picture,
Stefan Holmerf7044682018-07-17 10:16:41 +0200117 codec_info.codecSpecific.VP9.end_of_picture);
118
119 // Next spatial layer.
120 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
Stefan Holmerf7044682018-07-17 10:16:41 +0200121 codec_info.codecSpecific.VP9.end_of_picture = true;
122
Niels Möllerd3b8c632018-08-27 15:33:42 +0200123 encoded_image.SetSpatialIndex(1);
Johannes Krond0b69a82018-12-03 14:18:53 +0100124 ColorSpace color_space(
125 ColorSpace::PrimaryID::kSMPTE170M, ColorSpace::TransferID::kSMPTE170M,
126 ColorSpace::MatrixID::kSMPTE170M, ColorSpace::RangeID::kFull);
Danil Chapovalovb7698942019-02-05 11:32:19 +0100127 encoded_image.SetColorSpace(color_space);
philipelbf2b6202018-08-27 14:33:18 +0200128 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200129
130 EXPECT_EQ(kVideoRotation_90, header.rotation);
131 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
132 EXPECT_EQ(kVideoCodecVP9, header.codec);
Johannes Krond0b69a82018-12-03 14:18:53 +0100133 EXPECT_EQ(absl::make_optional(color_space), header.color_space);
philipel29d88462018-08-08 14:26:00 +0200134 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id);
135 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx);
136 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx);
Niels Möllerd3b8c632018-08-27 15:33:42 +0200137 EXPECT_EQ(vp9_header.spatial_idx, encoded_image.SpatialIndex());
philipel29d88462018-08-08 14:26:00 +0200138 EXPECT_EQ(vp9_header.num_spatial_layers,
Stefan Holmerf7044682018-07-17 10:16:41 +0200139 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel29d88462018-08-08 14:26:00 +0200140 EXPECT_EQ(vp9_header.end_of_picture,
Stefan Holmerf7044682018-07-17 10:16:41 +0200141 codec_info.codecSpecific.VP9.end_of_picture);
142}
143
144TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_H264) {
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500145 RtpPayloadState state;
146 state.picture_id = kPictureId;
147 state.tl0_pic_idx = kInitialTl0PicIdx1;
148 RtpPayloadParams params(kSsrc1, &state);
Stefan Holmerf7044682018-07-17 10:16:41 +0200149
150 EncodedImage encoded_image;
151 CodecSpecificInfo codec_info;
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500152 CodecSpecificInfoH264 *h264info = &codec_info.codecSpecific.H264;
Stefan Holmerf7044682018-07-17 10:16:41 +0200153 codec_info.codecType = kVideoCodecH264;
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500154 h264info->packetization_mode = H264PacketizationMode::SingleNalUnit;
155 h264info->temporal_idx = kNoTemporalIdx;
Stefan Holmerf7044682018-07-17 10:16:41 +0200156
philipelbf2b6202018-08-27 14:33:18 +0200157 RTPVideoHeader header =
158 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200159
160 EXPECT_EQ(0, header.simulcastIdx);
161 EXPECT_EQ(kVideoCodecH264, header.codec);
162 const auto& h264 = absl::get<RTPVideoHeaderH264>(header.video_type_header);
163 EXPECT_EQ(H264PacketizationMode::SingleNalUnit, h264.packetization_mode);
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500164
165 // test temporal param 1
166 h264info->temporal_idx = 1;
167 h264info->base_layer_sync = true;
168 h264info->idr_frame = false;
169
170 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
171
172 EXPECT_EQ(kVideoCodecH264, header.codec);
173 EXPECT_EQ(header.frame_marking.tl0_pic_idx, kInitialTl0PicIdx1);
174 EXPECT_EQ(header.frame_marking.temporal_id, h264info->temporal_idx);
175 EXPECT_EQ(header.frame_marking.base_layer_sync, h264info->base_layer_sync);
176 EXPECT_EQ(header.frame_marking.independent_frame, h264info->idr_frame);
177
178 // test temporal param 2
179 h264info->temporal_idx = 0;
180 h264info->base_layer_sync = false;
181 h264info->idr_frame = true;
182
183 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
184
185 EXPECT_EQ(kVideoCodecH264, header.codec);
186 EXPECT_EQ(header.frame_marking.tl0_pic_idx, kInitialTl0PicIdx1 + 1);
187 EXPECT_EQ(header.frame_marking.temporal_id, h264info->temporal_idx);
188 EXPECT_EQ(header.frame_marking.base_layer_sync, h264info->base_layer_sync);
189 EXPECT_EQ(header.frame_marking.independent_frame, h264info->idr_frame);
Stefan Holmerf7044682018-07-17 10:16:41 +0200190}
191
192TEST(RtpPayloadParamsTest, PictureIdIsSetForVp8) {
193 RtpPayloadState state;
194 state.picture_id = kInitialPictureId1;
195 state.tl0_pic_idx = kInitialTl0PicIdx1;
196
197 EncodedImage encoded_image;
198 CodecSpecificInfo codec_info;
Stefan Holmerf7044682018-07-17 10:16:41 +0200199 codec_info.codecType = kVideoCodecVP8;
Stefan Holmerf7044682018-07-17 10:16:41 +0200200
201 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200202 RTPVideoHeader header =
203 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200204 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000205 EXPECT_EQ(kInitialPictureId1 + 1,
206 absl::get<RTPVideoHeaderVP8>(header.video_type_header).pictureId);
Stefan Holmerf7044682018-07-17 10:16:41 +0200207
208 // State should hold latest used picture id and tl0_pic_idx.
209 state = params.state();
210 EXPECT_EQ(kInitialPictureId1 + 1, state.picture_id);
211 EXPECT_EQ(kInitialTl0PicIdx1 + 1, state.tl0_pic_idx);
212}
213
214TEST(RtpPayloadParamsTest, PictureIdWraps) {
215 RtpPayloadState state;
216 state.picture_id = kMaxTwoBytePictureId;
217 state.tl0_pic_idx = kInitialTl0PicIdx1;
218
219 EncodedImage encoded_image;
220 CodecSpecificInfo codec_info;
Stefan Holmerf7044682018-07-17 10:16:41 +0200221 codec_info.codecType = kVideoCodecVP8;
222 codec_info.codecSpecific.VP8.temporalIdx = kNoTemporalIdx;
223
224 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200225 RTPVideoHeader header =
226 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200227 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000228 EXPECT_EQ(0,
229 absl::get<RTPVideoHeaderVP8>(header.video_type_header).pictureId);
Stefan Holmerf7044682018-07-17 10:16:41 +0200230
231 // State should hold latest used picture id and tl0_pic_idx.
232 EXPECT_EQ(0, params.state().picture_id); // Wrapped.
233 EXPECT_EQ(kInitialTl0PicIdx1, params.state().tl0_pic_idx);
234}
235
236TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp8) {
237 RtpPayloadState state;
238 state.picture_id = kInitialPictureId1;
239 state.tl0_pic_idx = kInitialTl0PicIdx1;
240
241 EncodedImage encoded_image;
242 // Modules are sending for this test.
243 // OnEncodedImage, temporalIdx: 1.
244 CodecSpecificInfo codec_info;
Stefan Holmerf7044682018-07-17 10:16:41 +0200245 codec_info.codecType = kVideoCodecVP8;
246 codec_info.codecSpecific.VP8.temporalIdx = 1;
247
248 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200249 RTPVideoHeader header =
250 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200251
252 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000253 const auto& vp8_header =
254 absl::get<RTPVideoHeaderVP8>(header.video_type_header);
255 EXPECT_EQ(kInitialPictureId1 + 1, vp8_header.pictureId);
256 EXPECT_EQ(kInitialTl0PicIdx1, vp8_header.tl0PicIdx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200257
258 // OnEncodedImage, temporalIdx: 0.
259 codec_info.codecSpecific.VP8.temporalIdx = 0;
260
philipelbf2b6202018-08-27 14:33:18 +0200261 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200262 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000263 EXPECT_EQ(kInitialPictureId1 + 2, vp8_header.pictureId);
264 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp8_header.tl0PicIdx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200265
266 // State should hold latest used picture id and tl0_pic_idx.
267 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id);
268 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx);
269}
270
271TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp9) {
272 RtpPayloadState state;
273 state.picture_id = kInitialPictureId1;
274 state.tl0_pic_idx = kInitialTl0PicIdx1;
275
276 EncodedImage encoded_image;
277 // Modules are sending for this test.
278 // OnEncodedImage, temporalIdx: 1.
279 CodecSpecificInfo codec_info;
Stefan Holmerf7044682018-07-17 10:16:41 +0200280 codec_info.codecType = kVideoCodecVP9;
281 codec_info.codecSpecific.VP9.temporal_idx = 1;
282 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
283
284 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200285 RTPVideoHeader header =
286 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200287
288 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 14:26:00 +0200289 const auto& vp9_header =
290 absl::get<RTPVideoHeaderVP9>(header.video_type_header);
291 EXPECT_EQ(kInitialPictureId1 + 1, vp9_header.picture_id);
292 EXPECT_EQ(kInitialTl0PicIdx1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200293
294 // OnEncodedImage, temporalIdx: 0.
295 codec_info.codecSpecific.VP9.temporal_idx = 0;
296
philipelbf2b6202018-08-27 14:33:18 +0200297 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200298
299 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 14:26:00 +0200300 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id);
301 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200302
303 // OnEncodedImage, first_frame_in_picture = false
304 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
305
philipelbf2b6202018-08-27 14:33:18 +0200306 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200307
308 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 14:26:00 +0200309 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id);
310 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200311
312 // State should hold latest used picture id and tl0_pic_idx.
313 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id);
314 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx);
315}
philipelbf2b6202018-08-27 14:33:18 +0200316
317TEST(RtpPayloadParamsTest, PictureIdForOldGenericFormat) {
318 test::ScopedFieldTrials generic_picture_id(
319 "WebRTC-GenericPictureId/Enabled/");
320 RtpPayloadState state{};
321
322 EncodedImage encoded_image;
philipeld1d03592019-03-01 13:53:55 +0100323 CodecSpecificInfo codec_info;
philipelbf2b6202018-08-27 14:33:18 +0200324 codec_info.codecType = kVideoCodecGeneric;
325
326 RtpPayloadParams params(kSsrc1, &state);
327 RTPVideoHeader header =
328 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
329
330 EXPECT_EQ(kVideoCodecGeneric, header.codec);
331 ASSERT_TRUE(header.generic);
332 EXPECT_EQ(0, header.generic->frame_id);
333
334 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
335 ASSERT_TRUE(header.generic);
336 EXPECT_EQ(1, header.generic->frame_id);
337}
338
339class RtpPayloadParamsVp8ToGenericTest : public ::testing::Test {
340 public:
341 enum LayerSync { kNoSync, kSync };
342
philipel569397f2018-09-26 12:25:31 +0200343 RtpPayloadParamsVp8ToGenericTest()
344 : generic_descriptor_field_trial_("WebRTC-GenericDescriptor/Enabled/"),
345 state_(),
346 params_(123, &state_) {}
philipelbf2b6202018-08-27 14:33:18 +0200347
348 void ConvertAndCheck(int temporal_index,
349 int64_t shared_frame_id,
350 FrameType frame_type,
351 LayerSync layer_sync,
philipelfab91292018-10-17 14:36:08 +0200352 const std::set<int64_t>& expected_deps,
353 uint16_t width = 0,
354 uint16_t height = 0) {
philipelbf2b6202018-08-27 14:33:18 +0200355 EncodedImage encoded_image;
356 encoded_image._frameType = frame_type;
philipelfab91292018-10-17 14:36:08 +0200357 encoded_image._encodedWidth = width;
358 encoded_image._encodedHeight = height;
philipelbf2b6202018-08-27 14:33:18 +0200359
philipeld1d03592019-03-01 13:53:55 +0100360 CodecSpecificInfo codec_info;
philipelbf2b6202018-08-27 14:33:18 +0200361 codec_info.codecType = kVideoCodecVP8;
362 codec_info.codecSpecific.VP8.temporalIdx = temporal_index;
363 codec_info.codecSpecific.VP8.layerSync = layer_sync == kSync;
364
365 RTPVideoHeader header =
366 params_.GetRtpVideoHeader(encoded_image, &codec_info, shared_frame_id);
367
368 ASSERT_TRUE(header.generic);
369 EXPECT_TRUE(header.generic->higher_spatial_layers.empty());
370 EXPECT_EQ(header.generic->spatial_index, 0);
371
372 EXPECT_EQ(header.generic->frame_id, shared_frame_id);
373 EXPECT_EQ(header.generic->temporal_index, temporal_index);
374 std::set<int64_t> actual_deps(header.generic->dependencies.begin(),
375 header.generic->dependencies.end());
376 EXPECT_EQ(expected_deps, actual_deps);
philipelfab91292018-10-17 14:36:08 +0200377
378 EXPECT_EQ(header.width, width);
379 EXPECT_EQ(header.height, height);
philipelbf2b6202018-08-27 14:33:18 +0200380 }
381
382 protected:
philipel569397f2018-09-26 12:25:31 +0200383 test::ScopedFieldTrials generic_descriptor_field_trial_;
philipelbf2b6202018-08-27 14:33:18 +0200384 RtpPayloadState state_;
385 RtpPayloadParams params_;
386};
387
388TEST_F(RtpPayloadParamsVp8ToGenericTest, Keyframe) {
philipelfab91292018-10-17 14:36:08 +0200389 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200390 ConvertAndCheck(0, 1, kVideoFrameDelta, kNoSync, {0});
philipelfab91292018-10-17 14:36:08 +0200391 ConvertAndCheck(0, 2, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200392}
393
394TEST_F(RtpPayloadParamsVp8ToGenericTest, TooHighTemporalIndex) {
philipelfab91292018-10-17 14:36:08 +0200395 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200396
397 EncodedImage encoded_image;
398 encoded_image._frameType = kVideoFrameDelta;
philipeld1d03592019-03-01 13:53:55 +0100399 CodecSpecificInfo codec_info;
philipelbf2b6202018-08-27 14:33:18 +0200400 codec_info.codecType = kVideoCodecVP8;
401 codec_info.codecSpecific.VP8.temporalIdx =
402 RtpGenericFrameDescriptor::kMaxTemporalLayers;
403 codec_info.codecSpecific.VP8.layerSync = false;
404
405 RTPVideoHeader header =
406 params_.GetRtpVideoHeader(encoded_image, &codec_info, 1);
407 EXPECT_FALSE(header.generic);
408}
409
410TEST_F(RtpPayloadParamsVp8ToGenericTest, LayerSync) {
411 // 02120212 pattern
philipelfab91292018-10-17 14:36:08 +0200412 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200413 ConvertAndCheck(2, 1, kVideoFrameDelta, kNoSync, {0});
414 ConvertAndCheck(1, 2, kVideoFrameDelta, kNoSync, {0});
415 ConvertAndCheck(2, 3, kVideoFrameDelta, kNoSync, {0, 1, 2});
416
417 ConvertAndCheck(0, 4, kVideoFrameDelta, kNoSync, {0});
418 ConvertAndCheck(2, 5, kVideoFrameDelta, kNoSync, {2, 3, 4});
419 ConvertAndCheck(1, 6, kVideoFrameDelta, kSync, {4}); // layer sync
420 ConvertAndCheck(2, 7, kVideoFrameDelta, kNoSync, {4, 5, 6});
421}
422
423TEST_F(RtpPayloadParamsVp8ToGenericTest, FrameIdGaps) {
424 // 0101 pattern
philipelfab91292018-10-17 14:36:08 +0200425 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200426 ConvertAndCheck(1, 1, kVideoFrameDelta, kNoSync, {0});
427
428 ConvertAndCheck(0, 5, kVideoFrameDelta, kNoSync, {0});
429 ConvertAndCheck(1, 10, kVideoFrameDelta, kNoSync, {1, 5});
430
431 ConvertAndCheck(0, 15, kVideoFrameDelta, kNoSync, {5});
432 ConvertAndCheck(1, 20, kVideoFrameDelta, kNoSync, {10, 15});
433}
434
Stefan Holmerf7044682018-07-17 10:16:41 +0200435} // namespace webrtc