blob: b2339cd3b52ac25c99bec3744f973232c1963fd4 [file] [log] [blame]
Stefan Holmerf7044682018-07-17 08:16:411/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <memory>
12
Stefan Holmer9416ef82018-07-19 08:34:3813#include "call/rtp_payload_params.h"
Stefan Holmerf7044682018-07-17 08:16:4114#include "modules/video_coding/include/video_codec_interface.h"
15#include "test/gtest.h"
16
17namespace webrtc {
18namespace {
19const uint32_t kSsrc1 = 12345;
20const uint32_t kSsrc2 = 23456;
21const int16_t kPictureId = 123;
22const int16_t kTl0PicIdx = 20;
23const uint8_t kTemporalIdx = 1;
24const int16_t kInitialPictureId1 = 222;
25const int16_t kInitialTl0PicIdx1 = 99;
26} // namespace
27
28TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_Vp8) {
29 RtpPayloadState state2;
30 state2.picture_id = kPictureId;
31 state2.tl0_pic_idx = kTl0PicIdx;
32 std::map<uint32_t, RtpPayloadState> states = {{kSsrc2, state2}};
33
34 RtpPayloadParams params(kSsrc2, &state2);
35 EncodedImage encoded_image;
36 encoded_image.rotation_ = kVideoRotation_90;
37 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
38
39 CodecSpecificInfo codec_info;
40 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
41 codec_info.codecType = kVideoCodecVP8;
42 codec_info.codecSpecific.VP8.simulcastIdx = 1;
43 codec_info.codecSpecific.VP8.temporalIdx = kTemporalIdx;
44 codec_info.codecSpecific.VP8.keyIdx = kNoKeyIdx;
45 codec_info.codecSpecific.VP8.layerSync = true;
46 codec_info.codecSpecific.VP8.nonReference = true;
47
48 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info);
49
50 EXPECT_EQ(kVideoRotation_90, header.rotation);
51 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
52 EXPECT_EQ(1, header.simulcastIdx);
53 EXPECT_EQ(kVideoCodecVP8, header.codec);
54 EXPECT_EQ(kPictureId + 1, header.vp8().pictureId);
55 EXPECT_EQ(kTemporalIdx, header.vp8().temporalIdx);
56 EXPECT_EQ(kTl0PicIdx, header.vp8().tl0PicIdx);
57 EXPECT_EQ(kNoKeyIdx, header.vp8().keyIdx);
58 EXPECT_TRUE(header.vp8().layerSync);
59 EXPECT_TRUE(header.vp8().nonReference);
60}
61
62TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_Vp9) {
63 RtpPayloadState state;
64 state.picture_id = kPictureId;
65 state.tl0_pic_idx = kTl0PicIdx;
66 RtpPayloadParams params(kSsrc1, &state);
67
68 EncodedImage encoded_image;
69 encoded_image.rotation_ = kVideoRotation_90;
70 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
71
72 CodecSpecificInfo codec_info;
73 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
74 codec_info.codecType = kVideoCodecVP9;
75 codec_info.codecSpecific.VP9.num_spatial_layers = 3;
76 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
77 codec_info.codecSpecific.VP9.spatial_idx = 0;
78 codec_info.codecSpecific.VP9.temporal_idx = 2;
79 codec_info.codecSpecific.VP9.end_of_picture = false;
80
81 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info);
82
83 EXPECT_EQ(kVideoRotation_90, header.rotation);
84 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
85 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 12:26:0086 const auto& vp9_header =
87 absl::get<RTPVideoHeaderVP9>(header.video_type_header);
88 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id);
89 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx);
90 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx);
91 EXPECT_EQ(vp9_header.spatial_idx, codec_info.codecSpecific.VP9.spatial_idx);
92 EXPECT_EQ(vp9_header.num_spatial_layers,
Stefan Holmerf7044682018-07-17 08:16:4193 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel29d88462018-08-08 12:26:0094 EXPECT_EQ(vp9_header.end_of_picture,
Stefan Holmerf7044682018-07-17 08:16:4195 codec_info.codecSpecific.VP9.end_of_picture);
96
97 // Next spatial layer.
98 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
99 codec_info.codecSpecific.VP9.spatial_idx += 1;
100 codec_info.codecSpecific.VP9.end_of_picture = true;
101
102 header = params.GetRtpVideoHeader(encoded_image, &codec_info);
103
104 EXPECT_EQ(kVideoRotation_90, header.rotation);
105 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
106 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 12:26:00107 EXPECT_EQ(kPictureId + 1, vp9_header.picture_id);
108 EXPECT_EQ(kTl0PicIdx, vp9_header.tl0_pic_idx);
109 EXPECT_EQ(vp9_header.temporal_idx, codec_info.codecSpecific.VP9.temporal_idx);
110 EXPECT_EQ(vp9_header.spatial_idx, codec_info.codecSpecific.VP9.spatial_idx);
111 EXPECT_EQ(vp9_header.num_spatial_layers,
Stefan Holmerf7044682018-07-17 08:16:41112 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel29d88462018-08-08 12:26:00113 EXPECT_EQ(vp9_header.end_of_picture,
Stefan Holmerf7044682018-07-17 08:16:41114 codec_info.codecSpecific.VP9.end_of_picture);
115}
116
117TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_H264) {
118 RtpPayloadParams params(kSsrc1, {});
119
120 EncodedImage encoded_image;
121 CodecSpecificInfo codec_info;
122 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
123 codec_info.codecType = kVideoCodecH264;
124 codec_info.codecSpecific.H264.packetization_mode =
125 H264PacketizationMode::SingleNalUnit;
126
127 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info);
128
129 EXPECT_EQ(0, header.simulcastIdx);
130 EXPECT_EQ(kVideoCodecH264, header.codec);
131 const auto& h264 = absl::get<RTPVideoHeaderH264>(header.video_type_header);
132 EXPECT_EQ(H264PacketizationMode::SingleNalUnit, h264.packetization_mode);
133}
134
135TEST(RtpPayloadParamsTest, PictureIdIsSetForVp8) {
136 RtpPayloadState state;
137 state.picture_id = kInitialPictureId1;
138 state.tl0_pic_idx = kInitialTl0PicIdx1;
139
140 EncodedImage encoded_image;
141 CodecSpecificInfo codec_info;
142 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
143 codec_info.codecType = kVideoCodecVP8;
144 codec_info.codecSpecific.VP8.simulcastIdx = 0;
145
146 RtpPayloadParams params(kSsrc1, &state);
147 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info);
148 EXPECT_EQ(kVideoCodecVP8, header.codec);
149 EXPECT_EQ(kInitialPictureId1 + 1, header.vp8().pictureId);
150
151 // State should hold latest used picture id and tl0_pic_idx.
152 state = params.state();
153 EXPECT_EQ(kInitialPictureId1 + 1, state.picture_id);
154 EXPECT_EQ(kInitialTl0PicIdx1 + 1, state.tl0_pic_idx);
155}
156
157TEST(RtpPayloadParamsTest, PictureIdWraps) {
158 RtpPayloadState state;
159 state.picture_id = kMaxTwoBytePictureId;
160 state.tl0_pic_idx = kInitialTl0PicIdx1;
161
162 EncodedImage encoded_image;
163 CodecSpecificInfo codec_info;
164 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
165 codec_info.codecType = kVideoCodecVP8;
166 codec_info.codecSpecific.VP8.temporalIdx = kNoTemporalIdx;
167
168 RtpPayloadParams params(kSsrc1, &state);
169 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info);
170 EXPECT_EQ(kVideoCodecVP8, header.codec);
171 EXPECT_EQ(0, header.vp8().pictureId);
172
173 // State should hold latest used picture id and tl0_pic_idx.
174 EXPECT_EQ(0, params.state().picture_id); // Wrapped.
175 EXPECT_EQ(kInitialTl0PicIdx1, params.state().tl0_pic_idx);
176}
177
178TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp8) {
179 RtpPayloadState state;
180 state.picture_id = kInitialPictureId1;
181 state.tl0_pic_idx = kInitialTl0PicIdx1;
182
183 EncodedImage encoded_image;
184 // Modules are sending for this test.
185 // OnEncodedImage, temporalIdx: 1.
186 CodecSpecificInfo codec_info;
187 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
188 codec_info.codecType = kVideoCodecVP8;
189 codec_info.codecSpecific.VP8.temporalIdx = 1;
190
191 RtpPayloadParams params(kSsrc1, &state);
192 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info);
193
194 EXPECT_EQ(kVideoCodecVP8, header.codec);
195 EXPECT_EQ(kInitialPictureId1 + 1, header.vp8().pictureId);
196 EXPECT_EQ(kInitialTl0PicIdx1, header.vp8().tl0PicIdx);
197
198 // OnEncodedImage, temporalIdx: 0.
199 codec_info.codecSpecific.VP8.temporalIdx = 0;
200
201 header = params.GetRtpVideoHeader(encoded_image, &codec_info);
202 EXPECT_EQ(kVideoCodecVP8, header.codec);
203 EXPECT_EQ(kInitialPictureId1 + 2, header.vp8().pictureId);
204 EXPECT_EQ(kInitialTl0PicIdx1 + 1, header.vp8().tl0PicIdx);
205
206 // State should hold latest used picture id and tl0_pic_idx.
207 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id);
208 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx);
209}
210
211TEST(RtpPayloadParamsTest, Tl0PicIdxUpdatedForVp9) {
212 RtpPayloadState state;
213 state.picture_id = kInitialPictureId1;
214 state.tl0_pic_idx = kInitialTl0PicIdx1;
215
216 EncodedImage encoded_image;
217 // Modules are sending for this test.
218 // OnEncodedImage, temporalIdx: 1.
219 CodecSpecificInfo codec_info;
220 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
221 codec_info.codecType = kVideoCodecVP9;
222 codec_info.codecSpecific.VP9.temporal_idx = 1;
223 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
224
225 RtpPayloadParams params(kSsrc1, &state);
226 RTPVideoHeader header = params.GetRtpVideoHeader(encoded_image, &codec_info);
227
228 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 12:26:00229 const auto& vp9_header =
230 absl::get<RTPVideoHeaderVP9>(header.video_type_header);
231 EXPECT_EQ(kInitialPictureId1 + 1, vp9_header.picture_id);
232 EXPECT_EQ(kInitialTl0PicIdx1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 08:16:41233
234 // OnEncodedImage, temporalIdx: 0.
235 codec_info.codecSpecific.VP9.temporal_idx = 0;
236
237 header = params.GetRtpVideoHeader(encoded_image, &codec_info);
238
239 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 12:26:00240 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id);
241 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 08:16:41242
243 // OnEncodedImage, first_frame_in_picture = false
244 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
245
246 header = params.GetRtpVideoHeader(encoded_image, &codec_info);
247
248 EXPECT_EQ(kVideoCodecVP9, header.codec);
philipel29d88462018-08-08 12:26:00249 EXPECT_EQ(kInitialPictureId1 + 2, vp9_header.picture_id);
250 EXPECT_EQ(kInitialTl0PicIdx1 + 1, vp9_header.tl0_pic_idx);
Stefan Holmerf7044682018-07-17 08:16:41251
252 // State should hold latest used picture id and tl0_pic_idx.
253 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id);
254 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx);
255}
256} // namespace webrtc