blob: cdfbc70f0d9003ce341236ea4dec7d87ea20f6e8 [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
11#include <memory>
12
13#include "call/payload_router.h"
14#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);
86 EXPECT_EQ(kPictureId + 1, header.vp9().picture_id);
87 EXPECT_EQ(kTl0PicIdx, header.vp9().tl0_pic_idx);
88 EXPECT_EQ(header.vp9().temporal_idx,
89 codec_info.codecSpecific.VP9.temporal_idx);
90 EXPECT_EQ(header.vp9().spatial_idx, codec_info.codecSpecific.VP9.spatial_idx);
91 EXPECT_EQ(header.vp9().num_spatial_layers,
92 codec_info.codecSpecific.VP9.num_spatial_layers);
93 EXPECT_EQ(header.vp9().end_of_picture,
94 codec_info.codecSpecific.VP9.end_of_picture);
95
96 // Next spatial layer.
97 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
98 codec_info.codecSpecific.VP9.spatial_idx += 1;
99 codec_info.codecSpecific.VP9.end_of_picture = true;
100
101 header = params.GetRtpVideoHeader(encoded_image, &codec_info);
102
103 EXPECT_EQ(kVideoRotation_90, header.rotation);
104 EXPECT_EQ(VideoContentType::SCREENSHARE, header.content_type);
105 EXPECT_EQ(kVideoCodecVP9, header.codec);
106 EXPECT_EQ(kPictureId + 1, header.vp9().picture_id);
107 EXPECT_EQ(kTl0PicIdx, header.vp9().tl0_pic_idx);
108 EXPECT_EQ(header.vp9().temporal_idx,
109 codec_info.codecSpecific.VP9.temporal_idx);
110 EXPECT_EQ(header.vp9().spatial_idx, codec_info.codecSpecific.VP9.spatial_idx);
111 EXPECT_EQ(header.vp9().num_spatial_layers,
112 codec_info.codecSpecific.VP9.num_spatial_layers);
113 EXPECT_EQ(header.vp9().end_of_picture,
114 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);
229 EXPECT_EQ(kInitialPictureId1 + 1, header.vp9().picture_id);
230 EXPECT_EQ(kInitialTl0PicIdx1, header.vp9().tl0_pic_idx);
231
232 // OnEncodedImage, temporalIdx: 0.
233 codec_info.codecSpecific.VP9.temporal_idx = 0;
234
235 header = params.GetRtpVideoHeader(encoded_image, &codec_info);
236
237 EXPECT_EQ(kVideoCodecVP9, header.codec);
238 EXPECT_EQ(kInitialPictureId1 + 2, header.vp9().picture_id);
239 EXPECT_EQ(kInitialTl0PicIdx1 + 1, header.vp9().tl0_pic_idx);
240
241 // OnEncodedImage, first_frame_in_picture = false
242 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
243
244 header = params.GetRtpVideoHeader(encoded_image, &codec_info);
245
246 EXPECT_EQ(kVideoCodecVP9, header.codec);
247 EXPECT_EQ(kInitialPictureId1 + 2, header.vp9().picture_id);
248 EXPECT_EQ(kInitialTl0PicIdx1 + 1, header.vp9().tl0_pic_idx);
249
250 // State should hold latest used picture id and tl0_pic_idx.
251 EXPECT_EQ(kInitialPictureId1 + 2, params.state().picture_id);
252 EXPECT_EQ(kInitialTl0PicIdx1 + 1, params.state().tl0_pic_idx);
253}
254} // namespace webrtc