blob: ff3589effbbb981c7d86e9614cccf1daa68d210d [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;
55 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
56 codec_info.codecType = kVideoCodecVP8;
philipelbf2b6202018-08-27 14:33:18 +020057 codec_info.codecSpecific.VP8.temporalIdx = 0;
Stefan Holmerf7044682018-07-17 10:16:41 +020058 codec_info.codecSpecific.VP8.keyIdx = kNoKeyIdx;
philipelbf2b6202018-08-27 14:33:18 +020059 codec_info.codecSpecific.VP8.layerSync = false;
Stefan Holmerf7044682018-07-17 10:16:41 +020060 codec_info.codecSpecific.VP8.nonReference = true;
61
philipelbf2b6202018-08-27 14:33:18 +020062 RTPVideoHeader header =
63 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
64
65 codec_info.codecType = kVideoCodecVP8;
philipelbf2b6202018-08-27 14:33:18 +020066 codec_info.codecSpecific.VP8.temporalIdx = 1;
67 codec_info.codecSpecific.VP8.layerSync = true;
68
69 header = params.GetRtpVideoHeader(encoded_image, &codec_info, 1);
Stefan Holmerf7044682018-07-17 10:16:41 +020070
71 EXPECT_EQ(kVideoRotation_90, header.rotation);
72 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
73 EXPECT_EQ(1, header.simulcastIdx);
74 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +000075 const auto& vp8_header =
76 absl::get<RTPVideoHeaderVP8>(header.video_type_header);
77 EXPECT_EQ(kPictureId + 2, vp8_header.pictureId);
78 EXPECT_EQ(kTemporalIdx, vp8_header.temporalIdx);
79 EXPECT_EQ(kTl0PicIdx + 1, vp8_header.tl0PicIdx);
80 EXPECT_EQ(kNoKeyIdx, vp8_header.keyIdx);
81 EXPECT_TRUE(vp8_header.layerSync);
82 EXPECT_TRUE(vp8_header.nonReference);
Stefan Holmerf7044682018-07-17 10:16:41 +020083}
84
85TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_Vp9) {
86 RtpPayloadState state;
87 state.picture_id = kPictureId;
88 state.tl0_pic_idx = kTl0PicIdx;
89 RtpPayloadParams params(kSsrc1, &state);
90
91 EncodedImage encoded_image;
92 encoded_image.rotation_ = kVideoRotation_90;
93 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
Niels Möllerd3b8c632018-08-27 15:33:42 +020094 encoded_image.SetSpatialIndex(0);
Stefan Holmerf7044682018-07-17 10:16:41 +020095 CodecSpecificInfo codec_info;
96 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
97 codec_info.codecType = kVideoCodecVP9;
98 codec_info.codecSpecific.VP9.num_spatial_layers = 3;
99 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
Stefan Holmerf7044682018-07-17 10:16:41 +0200100 codec_info.codecSpecific.VP9.temporal_idx = 2;
101 codec_info.codecSpecific.VP9.end_of_picture = false;
102
philipelbf2b6202018-08-27 14:33:18 +0200103 RTPVideoHeader header =
104 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200105
106 EXPECT_EQ(kVideoRotation_90, header.rotation);
107 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
108 EXPECT_EQ(kVideoCodecVP9, header.codec);
Johannes Krond0b69a82018-12-03 14:18:53 +0100109 EXPECT_FALSE(header.color_space);
philipel29d88462018-08-08 14:26:00 +0200110 const auto& vp9_header =
111 absl::get<RTPVideoHeaderVP9>(header.video_type_header);
112 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id);
113 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx);
114 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx);
Niels Möllerd3b8c632018-08-27 15:33:42 +0200115 EXPECT_EQ(vp9_header.spatial_idx, encoded_image.SpatialIndex());
philipel29d88462018-08-08 14:26:00 +0200116 EXPECT_EQ(vp9_header.num_spatial_layers,
Stefan Holmerf7044682018-07-17 10:16:41 +0200117 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel29d88462018-08-08 14:26:00 +0200118 EXPECT_EQ(vp9_header.end_of_picture,
Stefan Holmerf7044682018-07-17 10:16:41 +0200119 codec_info.codecSpecific.VP9.end_of_picture);
120
121 // Next spatial layer.
122 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
Stefan Holmerf7044682018-07-17 10:16:41 +0200123 codec_info.codecSpecific.VP9.end_of_picture = true;
124
Niels Möllerd3b8c632018-08-27 15:33:42 +0200125 encoded_image.SetSpatialIndex(1);
Johannes Krond0b69a82018-12-03 14:18:53 +0100126 ColorSpace color_space(
127 ColorSpace::PrimaryID::kSMPTE170M, ColorSpace::TransferID::kSMPTE170M,
128 ColorSpace::MatrixID::kSMPTE170M, ColorSpace::RangeID::kFull);
Danil Chapovalovb7698942019-02-05 11:32:19 +0100129 encoded_image.SetColorSpace(color_space);
philipelbf2b6202018-08-27 14:33:18 +0200130 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200131
132 EXPECT_EQ(kVideoRotation_90, header.rotation);
133 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
134 EXPECT_EQ(kVideoCodecVP9, header.codec);
Johannes Krond0b69a82018-12-03 14:18:53 +0100135 EXPECT_EQ(absl::make_optional(color_space), header.color_space);
philipel29d88462018-08-08 14:26:00 +0200136 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id);
137 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx);
138 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx);
Niels Möllerd3b8c632018-08-27 15:33:42 +0200139 EXPECT_EQ(vp9_header.spatial_idx, encoded_image.SpatialIndex());
philipel29d88462018-08-08 14:26:00 +0200140 EXPECT_EQ(vp9_header.num_spatial_layers,
Stefan Holmerf7044682018-07-17 10:16:41 +0200141 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel29d88462018-08-08 14:26:00 +0200142 EXPECT_EQ(vp9_header.end_of_picture,
Stefan Holmerf7044682018-07-17 10:16:41 +0200143 codec_info.codecSpecific.VP9.end_of_picture);
144}
145
146TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_H264) {
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500147 RtpPayloadState state;
148 state.picture_id = kPictureId;
149 state.tl0_pic_idx = kInitialTl0PicIdx1;
150 RtpPayloadParams params(kSsrc1, &state);
Stefan Holmerf7044682018-07-17 10:16:41 +0200151
152 EncodedImage encoded_image;
153 CodecSpecificInfo codec_info;
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500154 CodecSpecificInfoH264 *h264info = &codec_info.codecSpecific.H264;
Stefan Holmerf7044682018-07-17 10:16:41 +0200155 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
156 codec_info.codecType = kVideoCodecH264;
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500157 h264info->packetization_mode = H264PacketizationMode::SingleNalUnit;
158 h264info->temporal_idx = kNoTemporalIdx;
Stefan Holmerf7044682018-07-17 10:16:41 +0200159
philipelbf2b6202018-08-27 14:33:18 +0200160 RTPVideoHeader header =
161 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200162
163 EXPECT_EQ(0, header.simulcastIdx);
164 EXPECT_EQ(kVideoCodecH264, header.codec);
165 const auto& h264 = absl::get<RTPVideoHeaderH264>(header.video_type_header);
166 EXPECT_EQ(H264PacketizationMode::SingleNalUnit, h264.packetization_mode);
Johnny Lee1a1c52b2019-02-08 14:25:40 -0500167
168 // test temporal param 1
169 h264info->temporal_idx = 1;
170 h264info->base_layer_sync = true;
171 h264info->idr_frame = false;
172
173 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
174
175 EXPECT_EQ(kVideoCodecH264, header.codec);
176 EXPECT_EQ(header.frame_marking.tl0_pic_idx, kInitialTl0PicIdx1);
177 EXPECT_EQ(header.frame_marking.temporal_id, h264info->temporal_idx);
178 EXPECT_EQ(header.frame_marking.base_layer_sync, h264info->base_layer_sync);
179 EXPECT_EQ(header.frame_marking.independent_frame, h264info->idr_frame);
180
181 // test temporal param 2
182 h264info->temporal_idx = 0;
183 h264info->base_layer_sync = false;
184 h264info->idr_frame = true;
185
186 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
187
188 EXPECT_EQ(kVideoCodecH264, header.codec);
189 EXPECT_EQ(header.frame_marking.tl0_pic_idx, kInitialTl0PicIdx1 + 1);
190 EXPECT_EQ(header.frame_marking.temporal_id, h264info->temporal_idx);
191 EXPECT_EQ(header.frame_marking.base_layer_sync, h264info->base_layer_sync);
192 EXPECT_EQ(header.frame_marking.independent_frame, h264info->idr_frame);
Stefan Holmerf7044682018-07-17 10:16:41 +0200193}
194
195TEST(RtpPayloadParamsTest, PictureIdIsSetForVp8) {
196 RtpPayloadState state;
197 state.picture_id = kInitialPictureId1;
198 state.tl0_pic_idx = kInitialTl0PicIdx1;
199
200 EncodedImage encoded_image;
201 CodecSpecificInfo codec_info;
202 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
203 codec_info.codecType = kVideoCodecVP8;
Stefan Holmerf7044682018-07-17 10:16:41 +0200204
205 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200206 RTPVideoHeader header =
207 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200208 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000209 EXPECT_EQ(kInitialPictureId1 + 1,
210 absl::get<RTPVideoHeaderVP8>(header.video_type_header).pictureId);
Stefan Holmerf7044682018-07-17 10:16:41 +0200211
212 // State should hold latest used picture id and tl0_pic_idx.
213 state = params.state();
214 EXPECT_EQ(kInitialPictureId1 + 1, state.picture_id);
215 EXPECT_EQ(kInitialTl0PicIdx1 + 1, state.tl0_pic_idx);
216}
217
218TEST(RtpPayloadParamsTest, PictureIdWraps) {
219 RtpPayloadState state;
220 state.picture_id = kMaxTwoBytePictureId;
221 state.tl0_pic_idx = kInitialTl0PicIdx1;
222
223 EncodedImage encoded_image;
224 CodecSpecificInfo codec_info;
225 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
226 codec_info.codecType = kVideoCodecVP8;
227 codec_info.codecSpecific.VP8.temporalIdx = kNoTemporalIdx;
228
229 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200230 RTPVideoHeader header =
231 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200232 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000233 EXPECT_EQ(0,
234 absl::get<RTPVideoHeaderVP8>(header.video_type_header).pictureId);
Stefan Holmerf7044682018-07-17 10:16:41 +0200235
236 // State should hold latest used picture id and tl0_pic_idx.
237 EXPECT_EQ(0, params.state().picture_id); // Wrapped.
238 EXPECT_EQ(kInitialTl0PicIdx1, params.state().tl0_pic_idx);
239}
240
241TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp8) {
242 RtpPayloadState state;
243 state.picture_id = kInitialPictureId1;
244 state.tl0_pic_idx = kInitialTl0PicIdx1;
245
246 EncodedImage encoded_image;
247 // Modules are sending for this test.
248 // OnEncodedImage, temporalIdx: 1.
249 CodecSpecificInfo codec_info;
250 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
251 codec_info.codecType = kVideoCodecVP8;
252 codec_info.codecSpecific.VP8.temporalIdx = 1;
253
254 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200255 RTPVideoHeader header =
256 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200257
258 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000259 const auto& vp8_header =
260 absl::get<RTPVideoHeaderVP8>(header.video_type_header);
261 EXPECT_EQ(kInitialPictureId1 + 1, vp8_header.pictureId);
262 EXPECT_EQ(kInitialTl0PicIdx1, vp8_header.tl0PicIdx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200263
264 // OnEncodedImage, temporalIdx: 0.
265 codec_info.codecSpecific.VP8.temporalIdx = 0;
266
philipelbf2b6202018-08-27 14:33:18 +0200267 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200268 EXPECT_EQ(kVideoCodecVP8, header.codec);
Philip Eliassond52a1a62018-09-07 13:03:55 +0000269 EXPECT_EQ(kInitialPictureId1 + 2, vp8_header.pictureId);
270 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp8_header.tl0PicIdx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200271
272 // State should hold latest used picture id and tl0_pic_idx.
273 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id);
274 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx);
275}
276
277TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp9) {
278 RtpPayloadState state;
279 state.picture_id = kInitialPictureId1;
280 state.tl0_pic_idx = kInitialTl0PicIdx1;
281
282 EncodedImage encoded_image;
283 // Modules are sending for this test.
284 // OnEncodedImage, temporalIdx: 1.
285 CodecSpecificInfo codec_info;
286 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
287 codec_info.codecType = kVideoCodecVP9;
288 codec_info.codecSpecific.VP9.temporal_idx = 1;
289 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
290
291 RtpPayloadParams params(kSsrc1, &state);
philipelbf2b6202018-08-27 14:33:18 +0200292 RTPVideoHeader header =
293 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200294
295 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 14:26:00 +0200296 const auto& vp9_header =
297 absl::get<RTPVideoHeaderVP9>(header.video_type_header);
298 EXPECT_EQ(kInitialPictureId1 + 1, vp9_header.picture_id);
299 EXPECT_EQ(kInitialTl0PicIdx1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200300
301 // OnEncodedImage, temporalIdx: 0.
302 codec_info.codecSpecific.VP9.temporal_idx = 0;
303
philipelbf2b6202018-08-27 14:33:18 +0200304 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200305
306 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 14:26:00 +0200307 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id);
308 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200309
310 // OnEncodedImage, first_frame_in_picture = false
311 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
312
philipelbf2b6202018-08-27 14:33:18 +0200313 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
Stefan Holmerf7044682018-07-17 10:16:41 +0200314
315 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 14:26:00 +0200316 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id);
317 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 10:16:41 +0200318
319 // State should hold latest used picture id and tl0_pic_idx.
320 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id);
321 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx);
322}
philipelbf2b6202018-08-27 14:33:18 +0200323
324TEST(RtpPayloadParamsTest, PictureIdForOldGenericFormat) {
325 test::ScopedFieldTrials generic_picture_id(
326 "WebRTC-GenericPictureId/Enabled/");
327 RtpPayloadState state{};
328
329 EncodedImage encoded_image;
330 CodecSpecificInfo codec_info{};
331 codec_info.codecType = kVideoCodecGeneric;
332
333 RtpPayloadParams params(kSsrc1, &state);
334 RTPVideoHeader header =
335 params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
336
337 EXPECT_EQ(kVideoCodecGeneric, header.codec);
338 ASSERT_TRUE(header.generic);
339 EXPECT_EQ(0, header.generic->frame_id);
340
341 header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare);
342 ASSERT_TRUE(header.generic);
343 EXPECT_EQ(1, header.generic->frame_id);
344}
345
346class RtpPayloadParamsVp8ToGenericTest : public ::testing::Test {
347 public:
348 enum LayerSync { kNoSync, kSync };
349
philipel569397f2018-09-26 12:25:31 +0200350 RtpPayloadParamsVp8ToGenericTest()
351 : generic_descriptor_field_trial_("WebRTC-GenericDescriptor/Enabled/"),
352 state_(),
353 params_(123, &state_) {}
philipelbf2b6202018-08-27 14:33:18 +0200354
355 void ConvertAndCheck(int temporal_index,
356 int64_t shared_frame_id,
357 FrameType frame_type,
358 LayerSync layer_sync,
philipelfab91292018-10-17 14:36:08 +0200359 const std::set<int64_t>& expected_deps,
360 uint16_t width = 0,
361 uint16_t height = 0) {
philipelbf2b6202018-08-27 14:33:18 +0200362 EncodedImage encoded_image;
363 encoded_image._frameType = frame_type;
philipelfab91292018-10-17 14:36:08 +0200364 encoded_image._encodedWidth = width;
365 encoded_image._encodedHeight = height;
philipelbf2b6202018-08-27 14:33:18 +0200366
367 CodecSpecificInfo codec_info{};
368 codec_info.codecType = kVideoCodecVP8;
369 codec_info.codecSpecific.VP8.temporalIdx = temporal_index;
370 codec_info.codecSpecific.VP8.layerSync = layer_sync == kSync;
371
372 RTPVideoHeader header =
373 params_.GetRtpVideoHeader(encoded_image, &codec_info, shared_frame_id);
374
375 ASSERT_TRUE(header.generic);
376 EXPECT_TRUE(header.generic->higher_spatial_layers.empty());
377 EXPECT_EQ(header.generic->spatial_index, 0);
378
379 EXPECT_EQ(header.generic->frame_id, shared_frame_id);
380 EXPECT_EQ(header.generic->temporal_index, temporal_index);
381 std::set<int64_t> actual_deps(header.generic->dependencies.begin(),
382 header.generic->dependencies.end());
383 EXPECT_EQ(expected_deps, actual_deps);
philipelfab91292018-10-17 14:36:08 +0200384
385 EXPECT_EQ(header.width, width);
386 EXPECT_EQ(header.height, height);
philipelbf2b6202018-08-27 14:33:18 +0200387 }
388
389 protected:
philipel569397f2018-09-26 12:25:31 +0200390 test::ScopedFieldTrials generic_descriptor_field_trial_;
philipelbf2b6202018-08-27 14:33:18 +0200391 RtpPayloadState state_;
392 RtpPayloadParams params_;
393};
394
395TEST_F(RtpPayloadParamsVp8ToGenericTest, Keyframe) {
philipelfab91292018-10-17 14:36:08 +0200396 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200397 ConvertAndCheck(0, 1, kVideoFrameDelta, kNoSync, {0});
philipelfab91292018-10-17 14:36:08 +0200398 ConvertAndCheck(0, 2, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200399}
400
401TEST_F(RtpPayloadParamsVp8ToGenericTest, TooHighTemporalIndex) {
philipelfab91292018-10-17 14:36:08 +0200402 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200403
404 EncodedImage encoded_image;
405 encoded_image._frameType = kVideoFrameDelta;
406 CodecSpecificInfo codec_info{};
407 codec_info.codecType = kVideoCodecVP8;
408 codec_info.codecSpecific.VP8.temporalIdx =
409 RtpGenericFrameDescriptor::kMaxTemporalLayers;
410 codec_info.codecSpecific.VP8.layerSync = false;
411
412 RTPVideoHeader header =
413 params_.GetRtpVideoHeader(encoded_image, &codec_info, 1);
414 EXPECT_FALSE(header.generic);
415}
416
417TEST_F(RtpPayloadParamsVp8ToGenericTest, LayerSync) {
418 // 02120212 pattern
philipelfab91292018-10-17 14:36:08 +0200419 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200420 ConvertAndCheck(2, 1, kVideoFrameDelta, kNoSync, {0});
421 ConvertAndCheck(1, 2, kVideoFrameDelta, kNoSync, {0});
422 ConvertAndCheck(2, 3, kVideoFrameDelta, kNoSync, {0, 1, 2});
423
424 ConvertAndCheck(0, 4, kVideoFrameDelta, kNoSync, {0});
425 ConvertAndCheck(2, 5, kVideoFrameDelta, kNoSync, {2, 3, 4});
426 ConvertAndCheck(1, 6, kVideoFrameDelta, kSync, {4}); // layer sync
427 ConvertAndCheck(2, 7, kVideoFrameDelta, kNoSync, {4, 5, 6});
428}
429
430TEST_F(RtpPayloadParamsVp8ToGenericTest, FrameIdGaps) {
431 // 0101 pattern
philipelfab91292018-10-17 14:36:08 +0200432 ConvertAndCheck(0, 0, kVideoFrameKey, kNoSync, {}, 480, 360);
philipelbf2b6202018-08-27 14:33:18 +0200433 ConvertAndCheck(1, 1, kVideoFrameDelta, kNoSync, {0});
434
435 ConvertAndCheck(0, 5, kVideoFrameDelta, kNoSync, {0});
436 ConvertAndCheck(1, 10, kVideoFrameDelta, kNoSync, {1, 5});
437
438 ConvertAndCheck(0, 15, kVideoFrameDelta, kNoSync, {5});
439 ConvertAndCheck(1, 20, kVideoFrameDelta, kNoSync, {10, 15});
440}
441
Stefan Holmerf7044682018-07-17 10:16:41 +0200442} // namespace webrtc