1 /* Gstreamer
2 * Copyright (C) <2018> Collabora Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19 #include <gst/check/gstcheck.h>
20 #include <gst/codecparsers/gsth265parser.h>
21 #include <string.h>
22
23 unsigned char slice_eos_slice_eob[] = {
24 0x00, 0x00, 0x00, 0x01, 0x26, 0x01, 0xaf, 0x06, 0xb8, 0x63, 0xef, 0x3a,
25 0x7f, 0x3e, 0x53, 0xff, 0xff, 0xf2, 0x4a, 0xef, 0xff, 0xfe, 0x6a, 0x5d,
26 0x60, 0xbc, 0xf8, 0x29, 0xeb, 0x9c, 0x4a, 0xb5, 0xcc, 0x76, 0x30, 0xa0,
27 0x7c, 0xd3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x19, 0x30,
28 0x00, 0x00, 0x00, 0x01, 0x48, 0x01,
29 0x00, 0x00, 0x00, 0x01, 0x26, 0x01, 0xaf, 0x06, 0xb8, 0x63, 0xef, 0x3a,
30 0x7f, 0x3e, 0x53, 0xff, 0xff, 0xf2, 0x4a, 0xef, 0xff, 0xfe, 0x6a, 0x5d,
31 0x60, 0xbc, 0xf8, 0x29, 0xeb, 0x9c, 0x4a, 0xb5, 0xcc, 0x76, 0x30, 0xa0,
32 0x7c, 0xd3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x19, 0x30,
33 0x00, 0x00, 0x00, 0x01, 0x4a, 0x01,
34 };
35
36 static const guint8 h265_vps_with_nonzero_max_layer_id[] = {
37 0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01,
38 0xff, 0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00,
39 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
40 0x5d, 0xac, 0x59
41 };
42
43 static const guint8 h265_pps_with_range_extension[] = {
44 0x00, 0x00, 0x00, 0x01, 0x44, 0x01, 0x30, 0x42, 0x13, 0x1c, 0x0c, 0x60,
45 0xe1, 0xd9, 0x38, 0x83, 0xb6, 0x38, 0x2c, 0x19, 0x29, 0x82, 0x42, 0xee,
46 0x61, 0xec, 0x28, 0x11, 0x1a, 0x51, 0xc1, 0x60, 0xc9, 0x4c, 0x12, 0x17,
47 0x73, 0x0f, 0x61, 0x40, 0x88, 0xd1, 0x05, 0x38, 0x20, 0x28, 0x94, 0xc5,
48 0x1c, 0x26, 0x70, 0xb0, 0x44, 0x20, 0x30, 0x69, 0x4a, 0x16, 0x12, 0x2c,
49 0x20, 0x83, 0xe3, 0x06, 0x87, 0x87, 0xc7, 0x30, 0xa9, 0x22, 0xd0, 0xb1,
50 0x01, 0x40, 0x98, 0xa1, 0x02, 0x47, 0x33, 0x85, 0x43, 0xc1, 0x31, 0x01,
51 0x18, 0x68, 0x2e, 0x3a, 0x20, 0x22, 0x20, 0x48, 0xc0, 0xd8, 0xe0, 0xa8,
52 0xa1, 0xc5, 0x04, 0x05, 0x12, 0x98, 0xa3, 0x84, 0xce, 0x16, 0x08, 0x84,
53 0x06, 0x0d, 0x29, 0x42, 0xc2, 0x45, 0x84, 0x10, 0x7c, 0x60, 0xd0, 0xf0,
54 0xf8, 0xe6, 0x15, 0x24, 0x5a, 0x16, 0x20, 0x28, 0x13, 0x14, 0x20, 0x48,
55 0xe6, 0x70, 0xa8, 0x78, 0x26, 0x20, 0x23, 0x0d, 0x05, 0xc7, 0x44, 0x04,
56 0x44, 0x09, 0x18, 0x1b, 0x1c, 0x15, 0x14, 0x3a, 0x08, 0x0a, 0x25, 0x31,
57 0x47, 0x09, 0x9c, 0x2c, 0x11, 0x08, 0x0c, 0x1a, 0x52, 0x85, 0x84, 0x8b,
58 0x08, 0x20, 0xf8, 0xc1, 0xa1, 0xe1, 0xf1, 0xcc, 0x2a, 0x48, 0xb4, 0x2c,
59 0x40, 0x50, 0x26, 0x28, 0x40, 0x91, 0xcc, 0xe1, 0x50, 0xf0, 0x4c, 0x40,
60 0x46, 0x1a, 0x0b, 0x8e, 0x88, 0x08, 0x88, 0x12, 0x30, 0x36, 0x38, 0x2a,
61 0x28, 0x71, 0x41, 0x01, 0x44, 0xa6, 0x28, 0xe1, 0x33, 0x85, 0x82, 0x21,
62 0x01, 0x83, 0x4a, 0x50, 0xb0, 0x91, 0x61, 0x04, 0x1f, 0x18, 0x34, 0x3c,
63 0x3e, 0x39, 0x85, 0x49, 0x16, 0x85, 0x88, 0x0a, 0x04, 0xc5, 0x08, 0x12,
64 0x39, 0x9c, 0x2a, 0x1e, 0x09, 0x88, 0x08, 0xc3, 0x41, 0x71, 0xd1, 0x01,
65 0x11, 0x02, 0x46, 0x06, 0xc7, 0x05, 0x45, 0x0e, 0x82, 0x00, 0x88, 0xc0,
66 0xa9, 0xc3, 0x08, 0xc1, 0xf0, 0xf1, 0x43, 0xe2, 0x04, 0x04, 0x83, 0x28,
67 0x51, 0x03, 0x64, 0x20, 0x70, 0x22, 0x13, 0x08, 0x18, 0x68, 0xd1, 0xc3,
68 0x04, 0x8d, 0x87, 0x85, 0x86, 0x43, 0x81, 0x50, 0xd0, 0xf0, 0x98, 0x70,
69 0xa6, 0x1e, 0x34, 0x31, 0x0d, 0x87, 0x82, 0xe8, 0xf0, 0xc0, 0xd2, 0x94,
70 0xa1, 0x20, 0xcb, 0x31, 0x88, 0xa0, 0x80, 0x22, 0x30, 0x2a, 0x70, 0xc2,
71 0x30, 0x7c, 0x3c, 0x50, 0xf8, 0x81, 0x01, 0x20, 0xca, 0x14, 0x40, 0xd9,
72 0x08, 0x1c, 0x08, 0x84, 0xc2, 0x06, 0x1a, 0x34, 0x70, 0xc1, 0x23, 0x61,
73 0xe1, 0x61, 0x90, 0xe0, 0x54, 0x34, 0x3c, 0x26, 0x1c, 0x29, 0x87, 0x8d,
74 0x0c, 0x43, 0x61, 0xe0, 0xba, 0x3c, 0x30, 0x34, 0xa5, 0x28, 0x48, 0x32,
75 0xcc, 0x68, 0x20, 0x08, 0x8c, 0x0a, 0x9c, 0x30, 0x8c, 0x1f, 0x0f, 0x14,
76 0x3e, 0x20, 0x40, 0x48, 0x32, 0x85, 0x10, 0x36, 0x42, 0x07, 0x02, 0x21,
77 0x30, 0x81, 0x86, 0x8d, 0x1c, 0x30, 0x48, 0xd8, 0x78, 0x58, 0x64, 0x38,
78 0x15, 0x0d, 0x0f, 0x09, 0x87, 0x0a, 0x61, 0xe3, 0x43, 0x10, 0xd8, 0x78,
79 0x2e, 0x8f, 0x0c, 0x0d, 0x29, 0x4a, 0x12, 0x0c, 0xb3, 0x1a, 0x08, 0x02,
80 0x23, 0x02, 0xa7, 0x0c, 0x23, 0x07, 0xc3, 0xc5, 0x0f, 0x88, 0x10, 0x12,
81 0x0c, 0xa1, 0x44, 0x0d, 0x90, 0x81, 0xc0, 0x88, 0x4c, 0x20, 0x61, 0xa3,
82 0x47, 0x0c, 0x12, 0x36, 0x1e, 0x16, 0x19, 0x0e, 0x05, 0x43, 0x43, 0xc2,
83 0x61, 0xc2, 0x98, 0x78, 0xd0, 0xc4, 0x36, 0x1e, 0x0b, 0xa3, 0xc3, 0x03,
84 0x4a, 0x52, 0x84, 0x83, 0x2c, 0xc6, 0x4a, 0x56, 0x01, 0x46, 0x89, 0x0c,
85 0xce, 0x25, 0x04, 0x83, 0x21, 0x96, 0x3b, 0x80,
86 };
87
88 static const guint8 h265_with_scc_extension[] = {
89 0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x09, 0x00, 0x40,
90 0x00, 0x00, 0x0e, 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x3c, 0x9b, 0x02, 0x40,
91 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x09, 0x00, 0x40, 0x00, 0x00, 0x0e,
92 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x3c, 0xa0, 0x0d, 0x08, 0x0f, 0x1f, 0xe5,
93 0x9b, 0x92, 0x46, 0xd8, 0x79, 0x79, 0x24, 0x93, 0xf9, 0xe7, 0xf3, 0xcb, 0xff,
94 0xff, 0xff, 0x3f, 0x9f, 0xcf, 0xcf, 0xe7, 0x6d, 0x90, 0xf3, 0x60, 0x40, 0x02,
95 0x12, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x44, 0x01, 0xc1, 0x94, 0x95, 0x81, 0x14,
96 0x42, 0x40, 0x0a,
97 };
98
99 static guint8 h265_sps[] = {
100 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03,
101 0x00, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x99, 0xa0, 0x01,
102 0xe0, 0x20, 0x02, 0x1c, 0x59, 0x4b, 0x92, 0x42, 0x96, 0x11, 0x80, 0xb5,
103 0x01, 0x01, 0x01, 0x14, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x03,
104 0x00, 0xf3, 0xf2, 0x00, 0x6e, 0x00, 0x17, 0xbd, 0xf8, 0x00, 0x02, 0x94,
105 0xb4, 0x00, 0x06, 0x9b, 0x60, 0x00, 0xd3, 0x6c, 0x00, 0x01, 0x4a, 0x5a,
106 0x40, 0x00, 0x14, 0xa5, 0xa0, 0x00, 0x34, 0xdb, 0x00, 0x06, 0x9b, 0x60,
107 0x00, 0x0a, 0x52, 0xd0, 0x40,
108 };
109
110 static guint8 h265_sei_pic_timing[] = {
111 0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x01, 0x10, 0x04, 0x00, 0x00, 0x03, 0x00,
112 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x08, 0xaf, 0xff, 0xff,
113 0xff, 0xfe, 0x80
114 };
115
116 /* hdr10plus dynamic metadata */
117 static guint8 h265_sei_user_data_registered[] = {
118 0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x04, 0x40, 0xb5, 0x00, 0x3c, 0x00, 0x01,
119 0x04, 0x01, 0x40, 0x00, 0x0c, 0x80, 0x8b, 0x4c, 0x41, 0xff, 0x1b, 0xd6,
120 0x01, 0x03, 0x64, 0x08, 0x00, 0x0c, 0x28, 0xdb, 0x20, 0x50, 0x00, 0xac,
121 0xc8, 0x00, 0xe1, 0x90, 0x03, 0x6e, 0x58, 0x10, 0x32, 0xd0, 0x2a, 0x6a,
122 0xf8, 0x48, 0xf3, 0x18, 0xe1, 0xb4, 0x00, 0x40, 0x44, 0x10, 0x25, 0x09,
123 0xa6, 0xae, 0x5c, 0x83, 0x50, 0xdd, 0xf9, 0x8e, 0xc7, 0xbd, 0x00, 0x80
124 };
125
126 static guint8 h265_sei_time_code[] = {
127 0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x88, 0x06, 0x60, 0x40, 0x00, 0x00, 0x03,
128 0x00, 0x10, 0x80
129 };
130
131 static guint8 h265_sei_mdcv[] = {
132 0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x89, 0x18, 0x33, 0xc2, 0x86, 0xc4, 0x1d,
133 0x4c, 0x0b, 0xb8, 0x84, 0xd0, 0x3e, 0x80, 0x3d, 0x13, 0x40, 0x42, 0x00, 0x98,
134 0x96, 0x80, 0x00, 0x00, 0x03, 0x00, 0x01, 0x80
135 };
136
137 static guint8 h265_sei_cll[] = {
138 0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x90, 0x04, 0x03, 0xe8, 0x01, 0x90, 0x80
139 };
140
GST_START_TEST(test_h265_parse_slice_eos_slice_eob)141 GST_START_TEST (test_h265_parse_slice_eos_slice_eob)
142 {
143 GstH265ParserResult res;
144 GstH265NalUnit nalu;
145 GstH265Parser *parser = gst_h265_parser_new ();
146 const guint8 *buf = slice_eos_slice_eob;
147 guint n, buf_size = sizeof (slice_eos_slice_eob);
148
149 res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
150
151 assert_equals_int (res, GST_H265_PARSER_OK);
152 assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
153 assert_equals_int (nalu.size, buf_size / 2 - 10); /* 2 slices, 1 start code(4) and EOx(6) */
154
155 n = nalu.offset + nalu.size;
156 buf += n;
157 buf_size -= n;
158
159 res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
160
161 assert_equals_int (res, GST_H265_PARSER_OK);
162 assert_equals_int (nalu.type, GST_H265_NAL_EOS);
163 assert_equals_int (nalu.size, 2);
164
165 n = nalu.offset + nalu.size;
166 buf += n;
167 buf_size -= n;
168
169 res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
170
171 assert_equals_int (res, GST_H265_PARSER_OK);
172 assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
173 assert_equals_int (nalu.size, 43);
174
175 n = nalu.offset + nalu.size;
176 buf += n;
177 buf_size -= n;
178
179 res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
180
181 assert_equals_int (res, GST_H265_PARSER_OK);
182 assert_equals_int (nalu.type, GST_H265_NAL_EOB);
183 assert_equals_int (nalu.size, 2);
184
185 gst_h265_parser_free (parser);
186 }
187
188 GST_END_TEST;
189
GST_START_TEST(test_h265_parse_pic_timing)190 GST_START_TEST (test_h265_parse_pic_timing)
191 {
192 GstH265NalUnit nalu;
193 GstH265Parser *parser = gst_h265_parser_new ();
194 const guint8 *buf = h265_sps;
195 guint i, buf_size = sizeof (h265_sps);
196 GArray *messages;
197 GstH265SEIMessage sei;
198 GstH265SPS sps;
199
200 assert_equals_int (gst_h265_parser_identify_nalu (parser, buf, 0, buf_size,
201 &nalu), GST_H265_PARSER_NO_NAL_END);
202 assert_equals_int (nalu.type, GST_H265_NAL_SPS);
203 assert_equals_int (nalu.size, buf_size - 4); /* 4 for start_code */
204
205 assert_equals_int (gst_h265_parser_parse_sps (parser, &nalu, &sps, TRUE),
206 GST_H265_PARSER_OK);
207
208 buf = h265_sei_pic_timing;
209 buf_size = sizeof (h265_sei_pic_timing);
210
211 assert_equals_int (gst_h265_parser_identify_nalu (parser, buf, 0, buf_size,
212 &nalu), GST_H265_PARSER_NO_NAL_END);
213 assert_equals_int (nalu.type, GST_H265_NAL_PREFIX_SEI);
214 assert_equals_int (nalu.size, buf_size - 4); /* 4 for start_code size */
215
216 assert_equals_int (gst_h265_parser_parse_sei (parser, &nalu, &messages),
217 GST_H265_PARSER_OK);
218
219 for (i = 0; i < messages->len; i++) {
220 sei = g_array_index (messages, GstH265SEIMessage, i);
221 assert_equals_int (sei.payloadType, GST_H265_SEI_PIC_TIMING);
222 assert_equals_int (sei.payload.pic_timing.pic_struct, 0);
223 assert_equals_int (sei.payload.pic_timing.source_scan_type, 1);
224 assert_equals_int (sei.payload.pic_timing.duplicate_flag, 0);
225 assert_equals_int (sei.payload.pic_timing.au_cpb_removal_delay_minus1, 0);
226 assert_equals_int (sei.payload.pic_timing.pic_dpb_output_delay, 0);
227 assert_equals_int (sei.payload.pic_timing.pic_dpb_output_du_delay, 0);
228 assert_equals_int (sei.payload.pic_timing.num_decoding_units_minus1, 33);
229 assert_equals_int (sei.payload.pic_timing.du_common_cpb_removal_delay_flag,
230 1);
231 assert_equals_int (sei.payload.
232 pic_timing.du_common_cpb_removal_delay_increment_minus1, 0);
233 }
234 g_array_free (messages, TRUE);
235 gst_h265_parser_free (parser);
236 }
237
238 GST_END_TEST;
239
GST_START_TEST(test_h265_parse_slice_6bytes)240 GST_START_TEST (test_h265_parse_slice_6bytes)
241 {
242 GstH265ParserResult res;
243 GstH265NalUnit nalu;
244 GstH265Parser *const parser = gst_h265_parser_new ();
245 const guint8 *buf = slice_eos_slice_eob;
246
247 res = gst_h265_parser_identify_nalu (parser, buf, 0, 6, &nalu);
248
249 assert_equals_int (res, GST_H265_PARSER_NO_NAL_END);
250 assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
251 assert_equals_int (nalu.size, 2);
252
253 gst_h265_parser_free (parser);
254 }
255
256 GST_END_TEST;
257
GST_START_TEST(test_h265_parse_identify_nalu_hevc)258 GST_START_TEST (test_h265_parse_identify_nalu_hevc)
259 {
260 GstH265ParserResult res;
261 GstH265NalUnit nalu;
262 GstH265Parser *parser = gst_h265_parser_new ();
263 /* Skip 4 bytes for the start code */
264 const gsize nal_size = sizeof (slice_eos_slice_eob) - 4;
265 const gsize buf_size = 4 + nal_size;
266 guint8 *buf = g_new (guint8, buf_size);
267
268 memcpy (buf + 4, slice_eos_slice_eob + 4, nal_size);
269
270 GST_WRITE_UINT16_BE (buf + 2, nal_size);
271 res = gst_h265_parser_identify_nalu_hevc (parser, buf, 2, buf_size, 2, &nalu);
272
273 assert_equals_int (res, GST_H265_PARSER_OK);
274 assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
275 assert_equals_int (nalu.offset, 4);
276 assert_equals_int (nalu.size, nal_size);
277
278 GST_WRITE_UINT32_BE (buf, nal_size);
279 res = gst_h265_parser_identify_nalu_hevc (parser, buf, 0, buf_size, 4, &nalu);
280
281 assert_equals_int (res, GST_H265_PARSER_OK);
282 assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
283 assert_equals_int (nalu.offset, 4);
284 assert_equals_int (nalu.size, nal_size);
285
286 GST_WRITE_UINT32_BE (buf, G_MAXUINT32);
287 res = gst_h265_parser_identify_nalu_hevc (parser, buf, 0, buf_size, 4, &nalu);
288
289 assert_equals_int (res, GST_H265_PARSER_BROKEN_DATA);
290
291 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 2);
292 res = gst_h265_parser_identify_nalu_hevc (parser, buf, 0, buf_size, 4, &nalu);
293
294 assert_equals_int (res, GST_H265_PARSER_BROKEN_DATA);
295
296 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 3);
297 res = gst_h265_parser_identify_nalu_hevc (parser, buf, 0, buf_size, 4, &nalu);
298
299 assert_equals_int (res, GST_H265_PARSER_BROKEN_DATA);
300
301 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 4);
302 res = gst_h265_parser_identify_nalu_hevc (parser, buf, 0, buf_size, 4, &nalu);
303
304 assert_equals_int (res, GST_H265_PARSER_NO_NAL_END);
305
306 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 6);
307 res = gst_h265_parser_identify_nalu_hevc (parser, buf, 0, buf_size, 4, &nalu);
308
309 assert_equals_int (res, GST_H265_PARSER_NO_NAL_END);
310
311 g_free (buf);
312 gst_h265_parser_free (parser);
313 }
314
315 GST_END_TEST;
316
GST_START_TEST(test_h265_base_profiles)317 GST_START_TEST (test_h265_base_profiles)
318 {
319 GstH265ProfileTierLevel ptl;
320
321 memset (&ptl, 0, sizeof (ptl));
322
323 ptl.profile_idc = 1;
324 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
325 GST_H265_PROFILE_MAIN);
326 ptl.profile_idc = 2;
327 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
328 GST_H265_PROFILE_MAIN_10);
329 ptl.profile_idc = 3;
330 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
331 GST_H265_PROFILE_MAIN_STILL_PICTURE);
332
333 ptl.profile_idc = 42;
334 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
335 GST_H265_PROFILE_INVALID);
336 }
337
338 GST_END_TEST;
339
GST_START_TEST(test_h265_base_profiles_compat)340 GST_START_TEST (test_h265_base_profiles_compat)
341 {
342 GstH265ProfileTierLevel ptl;
343
344 memset (&ptl, 0, sizeof (ptl));
345
346 ptl.profile_compatibility_flag[1] = 1;
347 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
348 GST_H265_PROFILE_MAIN);
349 ptl.profile_compatibility_flag[1] = 0;
350
351 ptl.profile_compatibility_flag[2] = 1;
352 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
353 GST_H265_PROFILE_MAIN_10);
354 ptl.profile_compatibility_flag[2] = 0;
355
356 ptl.profile_compatibility_flag[3] = 1;
357 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
358 GST_H265_PROFILE_MAIN_STILL_PICTURE);
359 ptl.profile_compatibility_flag[3] = 0;
360
361 ptl.profile_idc = 42;
362 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
363 GST_H265_PROFILE_INVALID);
364 }
365
366 GST_END_TEST;
367
368 static void
set_format_range_fields(GstH265ProfileTierLevel * ptl,guint8 max_14bit_constraint_flag,guint8 max_12bit_constraint_flag,guint8 max_10bit_constraint_flag,guint8 max_8bit_constraint_flag,guint8 max_422chroma_constraint_flag,guint8 max_420chroma_constraint_flag,guint8 max_monochrome_constraint_flag,guint8 intra_constraint_flag,guint8 one_picture_only_constraint_flag,guint8 lower_bit_rate_constraint_flag)369 set_format_range_fields (GstH265ProfileTierLevel * ptl,
370 guint8 max_14bit_constraint_flag,
371 guint8 max_12bit_constraint_flag,
372 guint8 max_10bit_constraint_flag,
373 guint8 max_8bit_constraint_flag,
374 guint8 max_422chroma_constraint_flag,
375 guint8 max_420chroma_constraint_flag,
376 guint8 max_monochrome_constraint_flag,
377 guint8 intra_constraint_flag,
378 guint8 one_picture_only_constraint_flag,
379 guint8 lower_bit_rate_constraint_flag)
380 {
381 ptl->max_14bit_constraint_flag = max_14bit_constraint_flag;
382 ptl->max_12bit_constraint_flag = max_12bit_constraint_flag;
383 ptl->max_10bit_constraint_flag = max_10bit_constraint_flag;
384 ptl->max_8bit_constraint_flag = max_8bit_constraint_flag;
385 ptl->max_422chroma_constraint_flag = max_422chroma_constraint_flag;
386 ptl->max_420chroma_constraint_flag = max_420chroma_constraint_flag;
387 ptl->max_monochrome_constraint_flag = max_monochrome_constraint_flag;
388 ptl->intra_constraint_flag = intra_constraint_flag;
389 ptl->one_picture_only_constraint_flag = one_picture_only_constraint_flag;
390 ptl->lower_bit_rate_constraint_flag = lower_bit_rate_constraint_flag;
391 }
392
393 static void
set_chroma_idc_and_depth(GstH265SPS * sps,guint8 chroma_idc,guint8 depth_luma,guint8 depth_chroma)394 set_chroma_idc_and_depth (GstH265SPS * sps, guint8 chroma_idc,
395 guint8 depth_luma, guint8 depth_chroma)
396 {
397 sps->chroma_format_idc = chroma_idc;
398 sps->bit_depth_luma_minus8 = depth_luma - 8;
399 sps->bit_depth_chroma_minus8 = depth_chroma - 8;
400 }
401
GST_START_TEST(test_h265_format_range_profiles_exact_match)402 GST_START_TEST (test_h265_format_range_profiles_exact_match)
403 {
404 /* Test all the combinations from Table A.2 */
405 GstH265ProfileTierLevel ptl;
406
407 memset (&ptl, 0, sizeof (ptl));
408 ptl.profile_idc = 4;
409
410 set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1);
411 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
412 GST_H265_PROFILE_MONOCHROME);
413
414 set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1);
415 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
416 GST_H265_PROFILE_MONOCHROME_12);
417
418 set_format_range_fields (&ptl, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1);
419 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
420 GST_H265_PROFILE_MONOCHROME_16);
421
422 set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1);
423 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
424 GST_H265_PROFILE_MAIN_12);
425
426 set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1);
427 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
428 GST_H265_PROFILE_MAIN_422_10);
429
430 set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1);
431 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
432 GST_H265_PROFILE_MAIN_422_12);
433
434 set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1);
435 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
436 GST_H265_PROFILE_MAIN_444);
437
438 set_format_range_fields (&ptl, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1);
439 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
440 GST_H265_PROFILE_MAIN_444_10);
441
442 set_format_range_fields (&ptl, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1);
443 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
444 GST_H265_PROFILE_MAIN_444_12);
445
446 set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0);
447 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
448 GST_H265_PROFILE_MAIN_INTRA);
449 set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1);
450 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
451 GST_H265_PROFILE_MAIN_INTRA);
452
453 set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0);
454 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
455 GST_H265_PROFILE_MAIN_10_INTRA);
456 set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1);
457 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
458 GST_H265_PROFILE_MAIN_10_INTRA);
459
460 set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0);
461 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
462 GST_H265_PROFILE_MAIN_12_INTRA);
463 set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1);
464 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
465 GST_H265_PROFILE_MAIN_12_INTRA);
466
467 set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0);
468 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
469 GST_H265_PROFILE_MAIN_422_10_INTRA);
470 set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1);
471 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
472 GST_H265_PROFILE_MAIN_422_10_INTRA);
473
474 set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0);
475 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
476 GST_H265_PROFILE_MAIN_422_12_INTRA);
477 set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1);
478 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
479 GST_H265_PROFILE_MAIN_422_12_INTRA);
480
481 set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0);
482 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
483 GST_H265_PROFILE_MAIN_444_INTRA);
484 set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1);
485 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
486 GST_H265_PROFILE_MAIN_444_INTRA);
487
488 set_format_range_fields (&ptl, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0);
489 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
490 GST_H265_PROFILE_MAIN_444_10_INTRA);
491 set_format_range_fields (&ptl, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1);
492 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
493 GST_H265_PROFILE_MAIN_444_10_INTRA);
494
495 set_format_range_fields (&ptl, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0);
496 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
497 GST_H265_PROFILE_MAIN_444_12_INTRA);
498 set_format_range_fields (&ptl, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1);
499 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
500 GST_H265_PROFILE_MAIN_444_12_INTRA);
501
502 set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
503 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
504 GST_H265_PROFILE_MAIN_444_16_INTRA);
505 set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1);
506 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
507 GST_H265_PROFILE_MAIN_444_16_INTRA);
508
509 set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0);
510 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
511 GST_H265_PROFILE_MAIN_444_STILL_PICTURE);
512 set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1);
513 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
514 GST_H265_PROFILE_MAIN_444_STILL_PICTURE);
515
516 set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0);
517 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
518 GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE);
519 set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1);
520 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
521 GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE);
522
523 ptl.profile_idc = 5;
524 set_format_range_fields (&ptl, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1);
525 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
526 GST_H265_PROFILE_HIGH_THROUGHPUT_444);
527 set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1);
528 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
529 GST_H265_PROFILE_HIGH_THROUGHPUT_444_10);
530 set_format_range_fields (&ptl, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1);
531 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
532 GST_H265_PROFILE_HIGH_THROUGHPUT_444_14);
533 set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
534 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
535 GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA);
536
537 ptl.profile_idc = 6;
538 set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1);
539 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
540 GST_H265_PROFILE_MULTIVIEW_MAIN);
541
542 ptl.profile_idc = 7;
543 set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1);
544 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
545 GST_H265_PROFILE_SCALABLE_MAIN_10);
546
547 ptl.profile_idc = 8;
548 set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1);
549 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
550 GST_H265_PROFILE_3D_MAIN);
551
552 ptl.profile_idc = 9;
553 set_format_range_fields (&ptl, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1);
554 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
555 GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
556 set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1);
557 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
558 GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
559
560 ptl.profile_idc = 10;
561 set_format_range_fields (&ptl, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1);
562 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
563 GST_H265_PROFILE_SCALABLE_MONOCHROME);
564 set_format_range_fields (&ptl, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1);
565 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
566 GST_H265_PROFILE_SCALABLE_MONOCHROME_16);
567
568 ptl.profile_idc = 11;
569 set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1);
570 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
571 GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10);
572 }
573
574 GST_END_TEST;
575
GST_START_TEST(test_h265_format_range_profiles_partial_match)576 GST_START_TEST (test_h265_format_range_profiles_partial_match)
577 {
578 /* Test matching compatible profiles from non-standard bitstream */
579 GstH265SPS sps;
580 GstH265ProfileTierLevel *ptl = &sps.profile_tier_level;
581
582 memset (&sps, 0, sizeof (sps));
583 ptl->profile_idc = 4;
584 set_format_range_fields (ptl, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1);
585 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
586 GST_H265_PROFILE_MAIN_444);
587
588 ptl->profile_idc = 5;
589 /* wrong max_monochrome_constraint_flag, should still be compatible
590 with GST_H265_PROFILE_HIGH_THROUGHPUT_444_10 */
591 set_format_range_fields (ptl, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1);
592 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
593 GST_H265_PROFILE_HIGH_THROUGHPUT_444_10);
594 /* wrong max_12bit_constraint_flag, should still be compatible
595 with GST_H265_PROFILE_HIGH_THROUGHPUT_444_14 */
596 set_format_range_fields (ptl, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1);
597 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
598 GST_H265_PROFILE_HIGH_THROUGHPUT_444_14);
599 /* wrong intra_constraint_flag, GST_H265_PROFILE_HIGH_THROUGHPUT_444_14
600 and GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA are both compatible,
601 but GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA should be chosen
602 because of the higher priority. */
603 set_format_range_fields (ptl, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0);
604 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
605 GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA);
606
607 ptl->profile_idc = 6;
608 /* wrong max_12bit_constraint_flag, should not be compatible with any */
609 set_format_range_fields (ptl, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1);
610 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
611 GST_H265_PROFILE_INVALID);
612
613 ptl->profile_idc = 7;
614 /* wrong max_monochrome_constraint_flag, and intra_constraint_flag,
615 still compatible with GST_H265_PROFILE_SCALABLE_MAIN_10 */
616 set_format_range_fields (ptl, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1);
617 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
618 GST_H265_PROFILE_SCALABLE_MAIN_10);
619
620 ptl->profile_idc = 8;
621 /* wrong one_picture_only_constraint_flag, still compatible
622 with GST_H265_PROFILE_3D_MAIN */
623 set_format_range_fields (ptl, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1);
624 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
625 GST_H265_PROFILE_3D_MAIN);
626
627 ptl->profile_idc = 9;
628 /* wrong one_picture_only_constraint_flag, still compatible
629 with GST_H265_PROFILE_SCREEN_EXTENDED_MAIN */
630 set_format_range_fields (ptl, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1);
631 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
632 GST_H265_PROFILE_SCREEN_EXTENDED_MAIN);
633 /* wrong indications but have right chroma_format_idc and bit_depth in SPS,
634 should be recognized as GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444 */
635 set_format_range_fields (ptl, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
636 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
637 GST_H265_PROFILE_INVALID);
638 set_chroma_idc_and_depth (&sps, 3, 8, 8);
639 g_assert_cmpuint (gst_h265_get_profile_from_sps (&sps), ==,
640 GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444);
641
642 ptl->profile_idc = 10;
643 /* wrong max_10bit_constraint_flag, still compatible
644 with GST_H265_PROFILE_SCALABLE_MONOCHROME_16 */
645 set_format_range_fields (ptl, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1);
646 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
647 GST_H265_PROFILE_SCALABLE_MONOCHROME_16);
648
649 ptl->profile_idc = 11;
650 /* wrong max_12bit_constraint_flag and max_422chroma_constraint_flag,
651 should be recognized as GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14 */
652 set_format_range_fields (ptl, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1);
653 g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (ptl), ==,
654 GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
655
656 ptl->profile_idc = 2;
657 /* main and main10 compatibility flags but with 10 bith depth */
658 ptl->profile_compatibility_flag[1] = 1;
659 ptl->profile_compatibility_flag[2] = 1;
660 set_format_range_fields (ptl, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
661 set_chroma_idc_and_depth (&sps, 1, 10, 10);
662 g_assert_cmpuint (gst_h265_get_profile_from_sps (&sps), ==,
663 GST_H265_PROFILE_MAIN_10);
664 }
665
666 GST_END_TEST;
667
GST_START_TEST(test_h265_parse_vps)668 GST_START_TEST (test_h265_parse_vps)
669 {
670 /* Parsing non-zero vps_max_layer_id in VPS
671 * https://bugzilla.gnome.org/show_bug.cgi?id=797279 */
672 GstH265Parser *parser;
673 GstH265NalUnit nalu;
674 GstH265ParserResult res;
675 GstH265VPS vps;
676 GstH265Profile profile;
677
678 parser = gst_h265_parser_new ();
679
680 res = gst_h265_parser_identify_nalu_unchecked (parser,
681 h265_vps_with_nonzero_max_layer_id, 0,
682 sizeof (h265_vps_with_nonzero_max_layer_id), &nalu);
683
684 assert_equals_int (res, GST_H265_PARSER_OK);
685 assert_equals_int (nalu.type, GST_H265_NAL_VPS);
686
687 res = gst_h265_parser_parse_vps (parser, &nalu, &vps);
688 assert_equals_int (res, GST_H265_PARSER_OK);
689
690 assert_equals_int (vps.id, 0);
691 assert_equals_int (vps.max_layers_minus1, 0);
692 assert_equals_int (vps.max_sub_layers_minus1, 0);
693 assert_equals_int (vps.temporal_id_nesting_flag, 1);
694
695 profile = gst_h265_profile_tier_level_get_profile (&vps.profile_tier_level);
696
697 assert_equals_int (profile, GST_H265_PROFILE_MAIN);
698 assert_equals_int (vps.sub_layer_ordering_info_present_flag, 1);
699
700 assert_equals_int (vps.max_dec_pic_buffering_minus1[0], 1);
701 assert_equals_int (vps.max_num_reorder_pics[0], 0);
702 assert_equals_int (vps.max_latency_increase_plus1[0], 0);
703
704 assert_equals_int (vps.max_layer_id, 5);
705 assert_equals_int (vps.num_layer_sets_minus1, 0);
706
707 assert_equals_int (vps.timing_info_present_flag, 0);
708 assert_equals_int (vps.vps_extension, 0);
709
710 gst_h265_parser_free (parser);
711 }
712
713 GST_END_TEST;
714
GST_START_TEST(test_h265_parse_pps)715 GST_START_TEST (test_h265_parse_pps)
716 {
717 GstH265Parser *parser;
718 GstH265NalUnit nalu;
719 GstH265ParserResult res;
720 GstH265PPS pps;
721
722 parser = gst_h265_parser_new ();
723
724 /*init sps[15] to avoid return error in gst_h265_parser_parse_pps */
725 parser->sps[15].valid = TRUE;
726 parser->sps[15].log2_diff_max_min_luma_coding_block_size = 1;
727
728 res = gst_h265_parser_identify_nalu_unchecked (parser,
729 h265_pps_with_range_extension, 0,
730 sizeof (h265_pps_with_range_extension), &nalu);
731
732 assert_equals_int (res, GST_H265_PARSER_OK);
733 assert_equals_int (nalu.type, GST_H265_NAL_PPS);
734
735 res = gst_h265_parser_parse_pps (parser, &nalu, &pps);
736
737 assert_equals_int (res, GST_H265_PARSER_OK);
738 assert_equals_int (pps.pps_range_extension_flag, 1);
739 assert_equals_int (pps.pps_multilayer_extension_flag, 0);
740 assert_equals_int (pps.pps_3d_extension_flag, 0);
741 assert_equals_int (pps.pps_extension_4bits, 0);
742 assert_equals_int (pps.
743 pps_extension_params.log2_max_transform_skip_block_size_minus2, 0);
744 assert_equals_int (pps.
745 pps_extension_params.cross_component_prediction_enabled_flag, 0);
746 assert_equals_int (pps.
747 pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
748 assert_equals_int (pps.pps_extension_params.diff_cu_chroma_qp_offset_depth,
749 1);
750 assert_equals_int (pps.pps_extension_params.chroma_qp_offset_list_len_minus1,
751 5);
752 assert_equals_int (pps.pps_extension_params.log2_sao_offset_scale_luma, 0);
753 assert_equals_int (pps.pps_extension_params.log2_sao_offset_scale_chroma, 0);
754
755 gst_h265_parser_free (parser);
756 }
757
758 GST_END_TEST;
759
GST_START_TEST(test_h265_parse_scc)760 GST_START_TEST (test_h265_parse_scc)
761 {
762 GstH265Parser *parser;
763 GstH265NalUnit nalu;
764 GstH265ParserResult res;
765 GstH265VPS vps;
766 GstH265PPS pps;
767 GstH265SPS sps;
768 guint offset;
769 gsize size;
770
771 parser = gst_h265_parser_new ();
772
773 offset = 0;
774 size = sizeof (h265_with_scc_extension);
775
776 res = gst_h265_parser_identify_nalu_unchecked (parser,
777 h265_with_scc_extension, offset, size, &nalu);
778 assert_equals_int (res, GST_H265_PARSER_OK);
779 assert_equals_int (nalu.type, GST_H265_NAL_VPS);
780 offset = nalu.offset;
781
782 res = gst_h265_parser_parse_vps (parser, &nalu, &vps);
783 assert_equals_int (res, GST_H265_PARSER_OK);
784
785 res = gst_h265_parser_identify_nalu_unchecked (parser,
786 h265_with_scc_extension, offset, size, &nalu);
787 assert_equals_int (res, GST_H265_PARSER_OK);
788 assert_equals_int (nalu.type, GST_H265_NAL_SPS);
789 offset = nalu.offset;
790
791 res = gst_h265_parser_parse_sps (parser, &nalu, &sps, FALSE);
792 assert_equals_int (res, GST_H265_PARSER_OK);
793 assert_equals_int (sps.profile_tier_level.profile_idc,
794 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING);
795 assert_equals_int (sps.profile_tier_level.profile_compatibility_flag[9], 1);
796 assert_equals_int (sps.sps_scc_extension_flag, 1);
797 assert_equals_int (sps.sps_extension_4bits, 0);
798 assert_equals_int (sps.sps_scc_extension_params.sps_curr_pic_ref_enabled_flag,
799 1);
800 assert_equals_int (sps.sps_scc_extension_params.palette_mode_enabled_flag, 1);
801 assert_equals_int (sps.
802 sps_scc_extension_params.delta_palette_max_predictor_size, 65);
803 assert_equals_int (sps.
804 sps_scc_extension_params.sps_palette_predictor_initializers_present_flag,
805 0);
806 assert_equals_int (sps.
807 sps_scc_extension_params.motion_vector_resolution_control_idc, 2);
808 assert_equals_int (sps.
809 sps_scc_extension_params.intra_boundary_filtering_disabled_flag, 1);
810
811 res = gst_h265_parser_identify_nalu_unchecked (parser,
812 h265_with_scc_extension, offset, size, &nalu);
813 assert_equals_int (res, GST_H265_PARSER_OK);
814 assert_equals_int (nalu.type, GST_H265_NAL_PPS);
815
816 res = gst_h265_parser_parse_pps (parser, &nalu, &pps);
817 assert_equals_int (res, GST_H265_PARSER_OK);
818 assert_equals_int (pps.pps_extension_4bits, 0);
819 assert_equals_int (pps.pps_scc_extension_flag, 1);
820 assert_equals_int (pps.pps_scc_extension_params.pps_curr_pic_ref_enabled_flag,
821 1);
822 assert_equals_int (pps.
823 pps_scc_extension_params.residual_adaptive_colour_transform_enabled_flag,
824 0);
825 assert_equals_int (pps.
826 pps_scc_extension_params.pps_palette_predictor_initializers_present_flag,
827 0);
828
829 gst_h265_parser_free (parser);
830 }
831
832 GST_END_TEST;
833
834 typedef struct
835 {
836 GstH265NalUnitType type;
837 gboolean is_idr;
838 gboolean is_irap;
839 gboolean is_bla;
840 gboolean is_cra;
841 gboolean is_radl;
842 gboolean is_rasl;
843 } H265NalTypeTestVector;
844
GST_START_TEST(test_h265_nal_type_classification)845 GST_START_TEST (test_h265_nal_type_classification)
846 {
847 gint i;
848 /* *INDENT-OFF* */
849 H265NalTypeTestVector test_vector[] = {
850 /* NAL-TYPE IDR IRAP BLA CRA RADL RASL */
851 {GST_H265_NAL_SLICE_TRAIL_N, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
852 {GST_H265_NAL_SLICE_TRAIL_R, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
853 {GST_H265_NAL_SLICE_TSA_N, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
854 {GST_H265_NAL_SLICE_TSA_R, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
855 {GST_H265_NAL_SLICE_STSA_N, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
856 {GST_H265_NAL_SLICE_STSA_R, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
857 {GST_H265_NAL_SLICE_RADL_N, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE},
858 {GST_H265_NAL_SLICE_RADL_R, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE},
859 {GST_H265_NAL_SLICE_RASL_N, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
860 {GST_H265_NAL_SLICE_RASL_R, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
861 /* 10 ~ 15: reserved non-irap sublayer nal */
862 {GST_H265_NAL_SLICE_BLA_W_LP, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE},
863 {GST_H265_NAL_SLICE_BLA_W_RADL, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE},
864 {GST_H265_NAL_SLICE_BLA_N_LP, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE},
865 {GST_H265_NAL_SLICE_IDR_W_RADL, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE},
866 {GST_H265_NAL_SLICE_IDR_N_LP, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE},
867 {GST_H265_NAL_SLICE_CRA_NUT, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE},
868 /* 22 ~ 23: reserved irap nal */
869 {(GstH265NalUnitType) 22, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE},
870 {(GstH265NalUnitType) 23, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE},
871 };
872 /* *INDENT-ON* */
873
874 for (i = 0; i < G_N_ELEMENTS (test_vector); i++) {
875 assert_equals_int (GST_H265_IS_NAL_TYPE_IDR (test_vector[i].type),
876 test_vector[i].is_idr);
877 assert_equals_int (GST_H265_IS_NAL_TYPE_IRAP (test_vector[i].type),
878 test_vector[i].is_irap);
879 assert_equals_int (GST_H265_IS_NAL_TYPE_BLA (test_vector[i].type),
880 test_vector[i].is_bla);
881 assert_equals_int (GST_H265_IS_NAL_TYPE_CRA (test_vector[i].type),
882 test_vector[i].is_cra);
883 assert_equals_int (GST_H265_IS_NAL_TYPE_RADL (test_vector[i].type),
884 test_vector[i].is_radl);
885 assert_equals_int (GST_H265_IS_NAL_TYPE_RASL (test_vector[i].type),
886 test_vector[i].is_rasl);
887 }
888
889 for (i = RESERVED_NON_IRAP_NAL_TYPE_MIN;
890 i <= UNSPECIFIED_NON_VCL_NAL_TYPE_MAX; i++) {
891 assert_equals_int (GST_H265_IS_NAL_TYPE_IDR (i), FALSE);
892 assert_equals_int (GST_H265_IS_NAL_TYPE_IRAP (i), FALSE);
893 assert_equals_int (GST_H265_IS_NAL_TYPE_BLA (i), FALSE);
894 assert_equals_int (GST_H265_IS_NAL_TYPE_CRA (i), FALSE);
895 assert_equals_int (GST_H265_IS_NAL_TYPE_RADL (i), FALSE);
896 assert_equals_int (GST_H265_IS_NAL_TYPE_RASL (i), FALSE);
897 }
898 }
899
900 GST_END_TEST;
901
GST_START_TEST(test_h265_sei_registered_user_data)902 GST_START_TEST (test_h265_sei_registered_user_data)
903 {
904 GstH265ParserResult res;
905 GstH265NalUnit nalu;
906 GArray *messages = NULL;
907 GstH265SEIMessage *sei;
908 GstH265SEIMessage other_sei;
909 GstH265RegisteredUserData *user_data;
910 GstH265RegisteredUserData *other_user_data;
911 GstH265Parser *parser = gst_h265_parser_new ();
912 guint payload_size;
913
914 res = gst_h265_parser_identify_nalu_unchecked (parser,
915 h265_sei_user_data_registered, 0,
916 G_N_ELEMENTS (h265_sei_user_data_registered), &nalu);
917 assert_equals_int (res, GST_H265_PARSER_OK);
918 assert_equals_int (nalu.type, GST_H265_NAL_PREFIX_SEI);
919
920 res = gst_h265_parser_parse_sei (parser, &nalu, &messages);
921 assert_equals_int (res, GST_H265_PARSER_OK);
922 fail_unless (messages != NULL);
923 assert_equals_int (messages->len, 1);
924
925 sei = &g_array_index (messages, GstH265SEIMessage, 0);
926 assert_equals_int (sei->payloadType, GST_H265_SEI_REGISTERED_USER_DATA);
927
928 user_data = &sei->payload.registered_user_data;
929 /* start code prefix 4 bytes
930 * nalu header 2 bytes
931 * payload type 1 byte
932 * payload size 1 byte
933 * country code 1 byte (0xb5)
934 */
935 payload_size = h265_sei_user_data_registered[4 + 2 + 1];
936
937 /* excluding country_code byte */
938 assert_equals_int (payload_size - 1, user_data->size);
939 fail_if (memcmp (user_data->data,
940 &h265_sei_user_data_registered[4 + 2 + 1 + 1 + 1], user_data->size));
941
942 memset (&other_sei, 0, sizeof (GstH265SEIMessage));
943 fail_unless (gst_h265_sei_copy (&other_sei, sei));
944 assert_equals_int (other_sei.payloadType, GST_H265_SEI_REGISTERED_USER_DATA);
945
946 other_user_data = &other_sei.payload.registered_user_data;
947 fail_if (memcmp (user_data->data, other_user_data->data, user_data->size));
948
949 g_array_unref (messages);
950 gst_h265_sei_free (&other_sei);
951 gst_h265_parser_free (parser);
952 }
953
954 GST_END_TEST;
955
956 typedef gboolean (*SEICheckFunc) (gconstpointer a, gconstpointer b);
957
958 static gboolean
check_sei_user_data_registered(const GstH265RegisteredUserData * a,const GstH265RegisteredUserData * b)959 check_sei_user_data_registered (const GstH265RegisteredUserData * a,
960 const GstH265RegisteredUserData * b)
961 {
962 if (a->country_code != b->country_code)
963 return FALSE;
964
965 if ((a->country_code == 0xff) &&
966 (a->country_code_extension != b->country_code_extension))
967 return FALSE;
968
969 if (a->size != b->size)
970 return FALSE;
971
972 return !memcmp (a->data, b->data, a->size);
973 }
974
975 static gboolean
check_sei_time_code(const GstH265TimeCode * a,const GstH265TimeCode * b)976 check_sei_time_code (const GstH265TimeCode * a, const GstH265TimeCode * b)
977 {
978 gint i;
979
980 if (a->num_clock_ts != b->num_clock_ts)
981 return FALSE;
982
983 for (i = 0; i < a->num_clock_ts; i++) {
984 if (a->clock_timestamp_flag[i] != b->clock_timestamp_flag[i])
985 return FALSE;
986
987 if (a->clock_timestamp_flag[i]) {
988 if ((a->units_field_based_flag[i] != b->units_field_based_flag[i]) ||
989 (a->counting_type[i] != b->counting_type[i]) ||
990 (a->full_timestamp_flag[i] != b->full_timestamp_flag[i]) ||
991 (a->discontinuity_flag[i] != b->discontinuity_flag[i]) ||
992 (a->cnt_dropped_flag[i] != b->cnt_dropped_flag[i]) ||
993 (a->n_frames[i] != b->n_frames[i])) {
994 return FALSE;
995 }
996
997 if (a->full_timestamp_flag[i]) {
998 if ((a->seconds_value[i] != b->seconds_value[i]) ||
999 (a->minutes_value[i] != b->minutes_value[i]) ||
1000 (a->hours_value[i] != b->hours_value[i])) {
1001 return FALSE;
1002 }
1003 } else {
1004 if (a->seconds_flag[i] != b->seconds_flag[i])
1005 return FALSE;
1006
1007 if (a->seconds_flag[i]) {
1008 if ((a->seconds_value[i] != b->seconds_value[i]) ||
1009 (a->minutes_flag[i] != b->minutes_flag[i])) {
1010 return FALSE;
1011 }
1012
1013 if (a->minutes_flag[i]) {
1014 if ((a->minutes_value[i] != b->minutes_value[i]) ||
1015 (a->hours_flag[i] != b->hours_flag[i])) {
1016 return FALSE;
1017 }
1018
1019 if (a->hours_flag[i]) {
1020 if (a->hours_value[i] != b->hours_value[i])
1021 return FALSE;
1022 }
1023 }
1024 }
1025 }
1026 }
1027 }
1028
1029 return TRUE;
1030 }
1031
1032 static gboolean
check_sei_mdcv(const GstH265MasteringDisplayColourVolume * a,const GstH265MasteringDisplayColourVolume * b)1033 check_sei_mdcv (const GstH265MasteringDisplayColourVolume * a,
1034 const GstH265MasteringDisplayColourVolume * b)
1035 {
1036 gint i;
1037 for (i = 0; i < 3; i++) {
1038 if (a->display_primaries_x[i] != b->display_primaries_x[i] ||
1039 a->display_primaries_y[i] != b->display_primaries_y[i])
1040 return FALSE;
1041 }
1042
1043 return (a->white_point_x == b->white_point_x) &&
1044 (a->white_point_y == b->white_point_y) &&
1045 (a->max_display_mastering_luminance == b->max_display_mastering_luminance)
1046 && (a->min_display_mastering_luminance ==
1047 b->min_display_mastering_luminance);
1048 }
1049
1050 static gboolean
check_sei_cll(const GstH265ContentLightLevel * a,const GstH265ContentLightLevel * b)1051 check_sei_cll (const GstH265ContentLightLevel * a,
1052 const GstH265ContentLightLevel * b)
1053 {
1054 return (a->max_content_light_level == b->max_content_light_level) &&
1055 (a->max_pic_average_light_level == b->max_pic_average_light_level);
1056 }
1057
GST_START_TEST(test_h265_create_sei)1058 GST_START_TEST (test_h265_create_sei)
1059 {
1060 GstH265Parser *parser;
1061 GstH265ParserResult parse_ret;
1062 GstH265NalUnit nalu;
1063 GArray *msg_array = NULL;
1064 GstMemory *mem;
1065 gint i;
1066 GstMapInfo info;
1067 struct
1068 {
1069 guint8 *raw_data;
1070 guint len;
1071 GstH265SEIPayloadType type;
1072 GstH265SEIMessage parsed_message;
1073 SEICheckFunc check_func;
1074 } test_list[] = {
1075 /* *INDENT-OFF* */
1076 {h265_sei_user_data_registered, G_N_ELEMENTS (h265_sei_user_data_registered),
1077 GST_H265_SEI_REGISTERED_USER_DATA, {0,},
1078 (SEICheckFunc) check_sei_user_data_registered},
1079 {h265_sei_time_code, G_N_ELEMENTS (h265_sei_time_code),
1080 GST_H265_SEI_TIME_CODE, {0,}, (
1081 SEICheckFunc) check_sei_time_code},
1082 {h265_sei_mdcv, G_N_ELEMENTS (h265_sei_mdcv),
1083 GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME, {0,},
1084 (SEICheckFunc) check_sei_mdcv},
1085 {h265_sei_cll, G_N_ELEMENTS (h265_sei_cll),
1086 GST_H265_SEI_CONTENT_LIGHT_LEVEL, {0,},
1087 (SEICheckFunc) check_sei_cll},
1088 /* *INDENT-ON* */
1089 };
1090
1091 parser = gst_h265_parser_new ();
1092
1093 /* test single sei message per sei nal unit */
1094 for (i = 0; i < G_N_ELEMENTS (test_list); i++) {
1095 gsize nal_size;
1096
1097 parse_ret = gst_h265_parser_identify_nalu_unchecked (parser,
1098 test_list[i].raw_data, 0, test_list[i].len, &nalu);
1099 assert_equals_int (parse_ret, GST_H265_PARSER_OK);
1100 assert_equals_int (nalu.type, GST_H265_NAL_PREFIX_SEI);
1101
1102 parse_ret = gst_h265_parser_parse_sei (parser, &nalu, &msg_array);
1103 assert_equals_int (parse_ret, GST_H265_PARSER_OK);
1104 assert_equals_int (msg_array->len, 1);
1105
1106 /* test bytestream */
1107 mem = gst_h265_create_sei_memory (nalu.layer_id,
1108 nalu.temporal_id_plus1, 4, msg_array);
1109 fail_unless (mem != NULL);
1110 fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
1111 GST_MEMDUMP ("created sei nal", info.data, info.size);
1112 GST_MEMDUMP ("original sei nal", test_list[i].raw_data, test_list[i].len);
1113 assert_equals_int (info.size, test_list[i].len);
1114 fail_if (memcmp (info.data, test_list[i].raw_data, test_list[i].len));
1115 gst_memory_unmap (mem, &info);
1116 gst_memory_unref (mem);
1117
1118 /* test packetized */
1119 mem = gst_h265_create_sei_memory_hevc (nalu.layer_id,
1120 nalu.temporal_id_plus1, 4, msg_array);
1121 fail_unless (mem != NULL);
1122 fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
1123 assert_equals_int (info.size, test_list[i].len);
1124 fail_if (memcmp (info.data + 4, test_list[i].raw_data + 4,
1125 test_list[i].len - 4));
1126 nal_size = GST_READ_UINT32_BE (info.data);
1127 assert_equals_int (nal_size, info.size - 4);
1128 gst_memory_unmap (mem, &info);
1129 gst_memory_unref (mem);
1130
1131 /* store parsed SEI for following tests */
1132 fail_unless (gst_h265_sei_copy (&test_list[i].parsed_message,
1133 &g_array_index (msg_array, GstH265SEIMessage, 0)));
1134
1135 g_array_unref (msg_array);
1136 }
1137
1138 /* test multiple SEI messages in a nal unit */
1139 msg_array = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
1140 for (i = 0; i < G_N_ELEMENTS (test_list); i++)
1141 g_array_append_val (msg_array, test_list[i].parsed_message);
1142
1143 mem = gst_h265_create_sei_memory (nalu.layer_id,
1144 nalu.temporal_id_plus1, 4, msg_array);
1145 fail_unless (mem != NULL);
1146 g_array_unref (msg_array);
1147
1148 /* parse sei message from buffer */
1149 fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
1150 parse_ret = gst_h265_parser_identify_nalu_unchecked (parser,
1151 info.data, 0, info.size, &nalu);
1152 assert_equals_int (parse_ret, GST_H265_PARSER_OK);
1153 assert_equals_int (nalu.type, GST_H265_NAL_PREFIX_SEI);
1154 parse_ret = gst_h265_parser_parse_sei (parser, &nalu, &msg_array);
1155 gst_memory_unmap (mem, &info);
1156 gst_memory_unref (mem);
1157
1158 assert_equals_int (parse_ret, GST_H265_PARSER_OK);
1159 assert_equals_int (msg_array->len, G_N_ELEMENTS (test_list));
1160 for (i = 0; i < msg_array->len; i++) {
1161 GstH265SEIMessage *msg = &g_array_index (msg_array, GstH265SEIMessage, i);
1162
1163 assert_equals_int (msg->payloadType, test_list[i].type);
1164 fail_unless (test_list[i].check_func (&msg->payload,
1165 &test_list[i].parsed_message.payload));
1166 }
1167
1168 /* clean up */
1169 for (i = 0; i < G_N_ELEMENTS (test_list); i++)
1170 gst_h265_sei_free (&test_list[i].parsed_message);
1171
1172 g_array_unref (msg_array);
1173 gst_h265_parser_free (parser);
1174 }
1175
1176 GST_END_TEST;
1177
1178 static Suite *
h265parser_suite(void)1179 h265parser_suite (void)
1180 {
1181 Suite *s = suite_create ("H265 Parser library");
1182
1183 TCase *tc_chain = tcase_create ("general");
1184
1185 suite_add_tcase (s, tc_chain);
1186 tcase_add_test (tc_chain, test_h265_parse_slice_eos_slice_eob);
1187 tcase_add_test (tc_chain, test_h265_parse_pic_timing);
1188 tcase_add_test (tc_chain, test_h265_parse_slice_6bytes);
1189 tcase_add_test (tc_chain, test_h265_parse_identify_nalu_hevc);
1190 tcase_add_test (tc_chain, test_h265_base_profiles);
1191 tcase_add_test (tc_chain, test_h265_base_profiles_compat);
1192 tcase_add_test (tc_chain, test_h265_format_range_profiles_exact_match);
1193 tcase_add_test (tc_chain, test_h265_format_range_profiles_partial_match);
1194 tcase_add_test (tc_chain, test_h265_parse_vps);
1195 tcase_add_test (tc_chain, test_h265_parse_pps);
1196 tcase_add_test (tc_chain, test_h265_parse_scc);
1197 tcase_add_test (tc_chain, test_h265_nal_type_classification);
1198 tcase_add_test (tc_chain, test_h265_sei_registered_user_data);
1199 tcase_add_test (tc_chain, test_h265_create_sei);
1200
1201 return s;
1202 }
1203
1204 GST_CHECK_MAIN (h265parser);
1205