1bd70be24152a62527bbd0a1d5499d43309aa8d5
[platform/upstream/gstreamer.git] / tests / check / libs / h265parser.c
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 guint8 h265_sps[] = {
89   0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x21, 0x60, 0x00, 0x00, 0x03,
90   0x00, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x99, 0xa0, 0x01,
91   0xe0, 0x20, 0x02, 0x1c, 0x59, 0x4b, 0x92, 0x42, 0x96, 0x11, 0x80, 0xb5,
92   0x01, 0x01, 0x01, 0x14, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x03,
93   0x00, 0xf3, 0xf2, 0x00, 0x6e, 0x00, 0x17, 0xbd, 0xf8, 0x00, 0x02, 0x94,
94   0xb4, 0x00, 0x06, 0x9b, 0x60, 0x00, 0xd3, 0x6c, 0x00, 0x01, 0x4a, 0x5a,
95   0x40, 0x00, 0x14, 0xa5, 0xa0, 0x00, 0x34, 0xdb, 0x00, 0x06, 0x9b, 0x60,
96   0x00, 0x0a, 0x52, 0xd0, 0x40,
97 };
98
99 static guint8 h265_sei_pic_timing[] = {
100   0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x01, 0x10, 0x04, 0x00, 0x00, 0x03, 0x00,
101   0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x08, 0xaf, 0xff, 0xff,
102   0xff, 0xfe, 0x80
103 };
104
105 /* hdr10plus dynamic metadata */
106 static guint8 h265_sei_user_data_registered[] = {
107   0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x04, 0x40, 0xb5, 0x00, 0x3c, 0x00, 0x01,
108   0x04, 0x01, 0x40, 0x00, 0x0c, 0x80, 0x8b, 0x4c, 0x41, 0xff, 0x1b, 0xd6,
109   0x01, 0x03, 0x64, 0x08, 0x00, 0x0c, 0x28, 0xdb, 0x20, 0x50, 0x00, 0xac,
110   0xc8, 0x00, 0xe1, 0x90, 0x03, 0x6e, 0x58, 0x10, 0x32, 0xd0, 0x2a, 0x6a,
111   0xf8, 0x48, 0xf3, 0x18, 0xe1, 0xb4, 0x00, 0x40, 0x44, 0x10, 0x25, 0x09,
112   0xa6, 0xae, 0x5c, 0x83, 0x50, 0xdd, 0xf9, 0x8e, 0xc7, 0xbd, 0x00, 0x80
113 };
114
115 static guint8 h265_sei_time_code[] = {
116   0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x88, 0x06, 0x60, 0x40, 0x00, 0x00, 0x03,
117   0x00, 0x10, 0x80
118 };
119
120 static guint8 h265_sei_mdcv[] = {
121   0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x89, 0x18, 0x33, 0xc2, 0x86, 0xc4, 0x1d,
122   0x4c, 0x0b, 0xb8, 0x84, 0xd0, 0x3e, 0x80, 0x3d, 0x13, 0x40, 0x42, 0x00, 0x98,
123   0x96, 0x80, 0x00, 0x00, 0x03, 0x00, 0x01, 0x80
124 };
125
126 static guint8 h265_sei_cll[] = {
127   0x00, 0x00, 0x00, 0x01, 0x4e, 0x01, 0x90, 0x04, 0x03, 0xe8, 0x01, 0x90, 0x80
128 };
129
130 GST_START_TEST (test_h265_parse_slice_eos_slice_eob)
131 {
132   GstH265ParserResult res;
133   GstH265NalUnit nalu;
134   GstH265Parser *parser = gst_h265_parser_new ();
135   const guint8 *buf = slice_eos_slice_eob;
136   guint n, buf_size = sizeof (slice_eos_slice_eob);
137
138   res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
139
140   assert_equals_int (res, GST_H265_PARSER_OK);
141   assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
142   assert_equals_int (nalu.size, buf_size / 2 - 10);     /* 2 slices, 1 start code(4) and EOx(6) */
143
144   n = nalu.offset + nalu.size;
145   buf += n;
146   buf_size -= n;
147
148   res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
149
150   assert_equals_int (res, GST_H265_PARSER_OK);
151   assert_equals_int (nalu.type, GST_H265_NAL_EOS);
152   assert_equals_int (nalu.size, 2);
153
154   n = nalu.offset + nalu.size;
155   buf += n;
156   buf_size -= n;
157
158   res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
159
160   assert_equals_int (res, GST_H265_PARSER_OK);
161   assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
162   assert_equals_int (nalu.size, 43);
163
164   n = nalu.offset + nalu.size;
165   buf += n;
166   buf_size -= n;
167
168   res = gst_h265_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
169
170   assert_equals_int (res, GST_H265_PARSER_OK);
171   assert_equals_int (nalu.type, GST_H265_NAL_EOB);
172   assert_equals_int (nalu.size, 2);
173
174   gst_h265_parser_free (parser);
175 }
176
177 GST_END_TEST;
178
179 GST_START_TEST (test_h265_parse_pic_timing)
180 {
181   GstH265NalUnit nalu;
182   GstH265Parser *parser = gst_h265_parser_new ();
183   const guint8 *buf = h265_sps;
184   guint i, buf_size = sizeof (h265_sps);
185   GArray *messages;
186   GstH265SEIMessage sei;
187   GstH265SPS sps;
188
189   assert_equals_int (gst_h265_parser_identify_nalu (parser, buf, 0, buf_size,
190           &nalu), GST_H265_PARSER_NO_NAL_END);
191   assert_equals_int (nalu.type, GST_H265_NAL_SPS);
192   assert_equals_int (nalu.size, buf_size - 4);  /* 4 for start_code */
193
194   assert_equals_int (gst_h265_parser_parse_sps (parser, &nalu, &sps, TRUE),
195       GST_H265_PARSER_OK);
196
197   buf = h265_sei_pic_timing;
198   buf_size = sizeof (h265_sei_pic_timing);
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_PREFIX_SEI);
203   assert_equals_int (nalu.size, buf_size - 4);  /* 4 for start_code size */
204
205   assert_equals_int (gst_h265_parser_parse_sei (parser, &nalu, &messages),
206       GST_H265_PARSER_OK);
207
208   for (i = 0; i < messages->len; i++) {
209     sei = g_array_index (messages, GstH265SEIMessage, i);
210     assert_equals_int (sei.payloadType, GST_H265_SEI_PIC_TIMING);
211     assert_equals_int (sei.payload.pic_timing.pic_struct, 0);
212     assert_equals_int (sei.payload.pic_timing.source_scan_type, 1);
213     assert_equals_int (sei.payload.pic_timing.duplicate_flag, 0);
214     assert_equals_int (sei.payload.pic_timing.au_cpb_removal_delay_minus1, 0);
215     assert_equals_int (sei.payload.pic_timing.pic_dpb_output_delay, 0);
216     assert_equals_int (sei.payload.pic_timing.pic_dpb_output_du_delay, 0);
217     assert_equals_int (sei.payload.pic_timing.num_decoding_units_minus1, 33);
218     assert_equals_int (sei.payload.pic_timing.du_common_cpb_removal_delay_flag,
219         1);
220     assert_equals_int (sei.payload.
221         pic_timing.du_common_cpb_removal_delay_increment_minus1, 0);
222   }
223   g_array_free (messages, TRUE);
224   gst_h265_parser_free (parser);
225 }
226
227 GST_END_TEST;
228
229 GST_START_TEST (test_h265_parse_slice_6bytes)
230 {
231   GstH265ParserResult res;
232   GstH265NalUnit nalu;
233   GstH265Parser *const parser = gst_h265_parser_new ();
234   const guint8 *buf = slice_eos_slice_eob;
235
236   res = gst_h265_parser_identify_nalu (parser, buf, 0, 6, &nalu);
237
238   assert_equals_int (res, GST_H265_PARSER_NO_NAL_END);
239   assert_equals_int (nalu.type, GST_H265_NAL_SLICE_IDR_W_RADL);
240   assert_equals_int (nalu.size, 2);
241
242   gst_h265_parser_free (parser);
243 }
244
245 GST_END_TEST;
246
247 GST_START_TEST (test_h265_base_profiles)
248 {
249   GstH265ProfileTierLevel ptl;
250
251   memset (&ptl, 0, sizeof (ptl));
252
253   ptl.profile_idc = 1;
254   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
255       GST_H265_PROFILE_MAIN);
256   ptl.profile_idc = 2;
257   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
258       GST_H265_PROFILE_MAIN_10);
259   ptl.profile_idc = 3;
260   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
261       GST_H265_PROFILE_MAIN_STILL_PICTURE);
262
263   ptl.profile_idc = 42;
264   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
265       GST_H265_PROFILE_INVALID);
266 }
267
268 GST_END_TEST;
269
270 GST_START_TEST (test_h265_base_profiles_compat)
271 {
272   GstH265ProfileTierLevel ptl;
273
274   memset (&ptl, 0, sizeof (ptl));
275
276   ptl.profile_compatibility_flag[1] = 1;
277   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
278       GST_H265_PROFILE_MAIN);
279   ptl.profile_compatibility_flag[1] = 0;
280
281   ptl.profile_compatibility_flag[2] = 1;
282   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
283       GST_H265_PROFILE_MAIN_10);
284   ptl.profile_compatibility_flag[2] = 0;
285
286   ptl.profile_compatibility_flag[3] = 1;
287   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
288       GST_H265_PROFILE_MAIN_STILL_PICTURE);
289   ptl.profile_compatibility_flag[3] = 0;
290
291   ptl.profile_idc = 42;
292   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
293       GST_H265_PROFILE_INVALID);
294 }
295
296 GST_END_TEST;
297
298 static void
299 set_format_range_fields (GstH265ProfileTierLevel * ptl,
300     guint8 max_14bit_constraint_flag,
301     guint8 max_12bit_constraint_flag,
302     guint8 max_10bit_constraint_flag,
303     guint8 max_8bit_constraint_flag,
304     guint8 max_422chroma_constraint_flag,
305     guint8 max_420chroma_constraint_flag,
306     guint8 max_monochrome_constraint_flag,
307     guint8 intra_constraint_flag,
308     guint8 one_picture_only_constraint_flag,
309     guint8 lower_bit_rate_constraint_flag)
310 {
311   ptl->max_14bit_constraint_flag = max_14bit_constraint_flag;
312   ptl->max_12bit_constraint_flag = max_12bit_constraint_flag;
313   ptl->max_10bit_constraint_flag = max_10bit_constraint_flag;
314   ptl->max_8bit_constraint_flag = max_8bit_constraint_flag;
315   ptl->max_422chroma_constraint_flag = max_422chroma_constraint_flag;
316   ptl->max_420chroma_constraint_flag = max_420chroma_constraint_flag;
317   ptl->max_monochrome_constraint_flag = max_monochrome_constraint_flag;
318   ptl->intra_constraint_flag = intra_constraint_flag;
319   ptl->one_picture_only_constraint_flag = one_picture_only_constraint_flag;
320   ptl->lower_bit_rate_constraint_flag = lower_bit_rate_constraint_flag;
321 }
322
323 GST_START_TEST (test_h265_format_range_profiles_exact_match)
324 {
325   /* Test all the combinations from Table A.2 */
326   GstH265ProfileTierLevel ptl;
327
328   memset (&ptl, 0, sizeof (ptl));
329   ptl.profile_idc = 4;
330
331   set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1);
332   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
333       GST_H265_PROFILE_MONOCHROME);
334
335   set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1);
336   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
337       GST_H265_PROFILE_MONOCHROME_12);
338
339   set_format_range_fields (&ptl, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1);
340   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
341       GST_H265_PROFILE_MONOCHROME_16);
342
343   set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1);
344   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
345       GST_H265_PROFILE_MAIN_12);
346
347   set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1);
348   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
349       GST_H265_PROFILE_MAIN_422_10);
350
351   set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1);
352   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
353       GST_H265_PROFILE_MAIN_422_12);
354
355   set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1);
356   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
357       GST_H265_PROFILE_MAIN_444);
358
359   set_format_range_fields (&ptl, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1);
360   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
361       GST_H265_PROFILE_MAIN_444_10);
362
363   set_format_range_fields (&ptl, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1);
364   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
365       GST_H265_PROFILE_MAIN_444_12);
366
367   set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0);
368   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
369       GST_H265_PROFILE_MAIN_INTRA);
370   set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1);
371   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
372       GST_H265_PROFILE_MAIN_INTRA);
373
374   set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0);
375   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
376       GST_H265_PROFILE_MAIN_10_INTRA);
377   set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1);
378   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
379       GST_H265_PROFILE_MAIN_10_INTRA);
380
381   set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0);
382   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
383       GST_H265_PROFILE_MAIN_12_INTRA);
384   set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1);
385   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
386       GST_H265_PROFILE_MAIN_12_INTRA);
387
388   set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0);
389   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
390       GST_H265_PROFILE_MAIN_422_10_INTRA);
391   set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1);
392   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
393       GST_H265_PROFILE_MAIN_422_10_INTRA);
394
395   set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0);
396   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
397       GST_H265_PROFILE_MAIN_422_12_INTRA);
398   set_format_range_fields (&ptl, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1);
399   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
400       GST_H265_PROFILE_MAIN_422_12_INTRA);
401
402   set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0);
403   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
404       GST_H265_PROFILE_MAIN_444_INTRA);
405   set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1);
406   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
407       GST_H265_PROFILE_MAIN_444_INTRA);
408
409   set_format_range_fields (&ptl, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0);
410   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
411       GST_H265_PROFILE_MAIN_444_10_INTRA);
412   set_format_range_fields (&ptl, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1);
413   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
414       GST_H265_PROFILE_MAIN_444_10_INTRA);
415
416   set_format_range_fields (&ptl, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0);
417   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
418       GST_H265_PROFILE_MAIN_444_12_INTRA);
419   set_format_range_fields (&ptl, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1);
420   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
421       GST_H265_PROFILE_MAIN_444_12_INTRA);
422
423   set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
424   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
425       GST_H265_PROFILE_MAIN_444_16_INTRA);
426   set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1);
427   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
428       GST_H265_PROFILE_MAIN_444_16_INTRA);
429
430   set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0);
431   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
432       GST_H265_PROFILE_MAIN_444_STILL_PICTURE);
433   set_format_range_fields (&ptl, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1);
434   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
435       GST_H265_PROFILE_MAIN_444_STILL_PICTURE);
436
437   set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0);
438   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
439       GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE);
440   set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1);
441   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
442       GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE);
443
444   ptl.profile_idc = 5;
445   set_format_range_fields (&ptl, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1);
446   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
447       GST_H265_PROFILE_HIGH_THROUGHPUT_444);
448   set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1);
449   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
450       GST_H265_PROFILE_HIGH_THROUGHPUT_444_10);
451   set_format_range_fields (&ptl, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1);
452   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
453       GST_H265_PROFILE_HIGH_THROUGHPUT_444_14);
454   set_format_range_fields (&ptl, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
455   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
456       GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA);
457
458   ptl.profile_idc = 6;
459   set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1);
460   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
461       GST_H265_PROFILE_MULTIVIEW_MAIN);
462
463   ptl.profile_idc = 7;
464   set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1);
465   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
466       GST_H265_PROFILE_SCALABLE_MAIN_10);
467
468   ptl.profile_idc = 8;
469   set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1);
470   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
471       GST_H265_PROFILE_3D_MAIN);
472
473   ptl.profile_idc = 9;
474   set_format_range_fields (&ptl, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1);
475   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
476       GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
477   set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1);
478   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
479       GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
480
481   ptl.profile_idc = 10;
482   set_format_range_fields (&ptl, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1);
483   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
484       GST_H265_PROFILE_SCALABLE_MONOCHROME);
485   set_format_range_fields (&ptl, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1);
486   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
487       GST_H265_PROFILE_SCALABLE_MONOCHROME_16);
488 }
489
490 GST_END_TEST;
491
492 GST_START_TEST (test_h265_format_range_profiles_partial_match)
493 {
494   /* Test matching compatible profiles from non-standard bitstream */
495   GstH265ProfileTierLevel ptl;
496
497   memset (&ptl, 0, sizeof (ptl));
498   ptl.profile_idc = 4;
499   set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1);
500   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
501       GST_H265_PROFILE_MAIN_444);
502
503   ptl.profile_idc = 5;
504   /* wrong max_monochrome_constraint_flag, should still be compatible
505      with GST_H265_PROFILE_HIGH_THROUGHPUT_444_10 */
506   set_format_range_fields (&ptl, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1);
507   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
508       GST_H265_PROFILE_HIGH_THROUGHPUT_444_10);
509   /* wrong max_12bit_constraint_flag, should still be compatible
510      with GST_H265_PROFILE_HIGH_THROUGHPUT_444_14 */
511   set_format_range_fields (&ptl, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1);
512   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
513       GST_H265_PROFILE_HIGH_THROUGHPUT_444_14);
514   /* wrong intra_constraint_flag, GST_H265_PROFILE_HIGH_THROUGHPUT_444_14
515      and GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA are both compatible,
516      but GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA should be chosen
517      because of the higher priority. */
518   set_format_range_fields (&ptl, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0);
519   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
520       GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA);
521
522   ptl.profile_idc = 6;
523   /* wrong max_12bit_constraint_flag, should not be compatible with any */
524   set_format_range_fields (&ptl, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1);
525   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
526       GST_H265_PROFILE_INVALID);
527
528   ptl.profile_idc = 7;
529   /* wrong max_monochrome_constraint_flag, and intra_constraint_flag,
530      still compatible with GST_H265_PROFILE_SCALABLE_MAIN_10 */
531   set_format_range_fields (&ptl, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1);
532   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
533       GST_H265_PROFILE_SCALABLE_MAIN_10);
534
535   ptl.profile_idc = 8;
536   /* wrong one_picture_only_constraint_flag, still compatible
537      with GST_H265_PROFILE_3D_MAIN */
538   set_format_range_fields (&ptl, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1);
539   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
540       GST_H265_PROFILE_3D_MAIN);
541
542   ptl.profile_idc = 9;
543   /* wrong one_picture_only_constraint_flag, still compatible
544      with GST_H265_PROFILE_SCREEN_EXTENDED_MAIN */
545   set_format_range_fields (&ptl, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1);
546   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
547       GST_H265_PROFILE_SCREEN_EXTENDED_MAIN);
548
549   ptl.profile_idc = 10;
550   /* wrong max_10bit_constraint_flag, still compatible
551      with GST_H265_PROFILE_SCALABLE_MONOCHROME_16 */
552   set_format_range_fields (&ptl, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1);
553   g_assert_cmpuint (gst_h265_profile_tier_level_get_profile (&ptl), ==,
554       GST_H265_PROFILE_SCALABLE_MONOCHROME_16);
555 }
556
557 GST_END_TEST;
558
559 GST_START_TEST (test_h265_parse_vps)
560 {
561   /* Parsing non-zero vps_max_layer_id in VPS
562    * https://bugzilla.gnome.org/show_bug.cgi?id=797279 */
563   GstH265Parser *parser;
564   GstH265NalUnit nalu;
565   GstH265ParserResult res;
566   GstH265VPS vps;
567   GstH265Profile profile;
568
569   parser = gst_h265_parser_new ();
570
571   res = gst_h265_parser_identify_nalu_unchecked (parser,
572       h265_vps_with_nonzero_max_layer_id, 0,
573       sizeof (h265_vps_with_nonzero_max_layer_id), &nalu);
574
575   assert_equals_int (res, GST_H265_PARSER_OK);
576   assert_equals_int (nalu.type, GST_H265_NAL_VPS);
577
578   res = gst_h265_parser_parse_vps (parser, &nalu, &vps);
579   assert_equals_int (res, GST_H265_PARSER_OK);
580
581   assert_equals_int (vps.id, 0);
582   assert_equals_int (vps.max_layers_minus1, 0);
583   assert_equals_int (vps.max_sub_layers_minus1, 0);
584   assert_equals_int (vps.temporal_id_nesting_flag, 1);
585
586   profile = gst_h265_profile_tier_level_get_profile (&vps.profile_tier_level);
587
588   assert_equals_int (profile, GST_H265_PROFILE_MAIN);
589   assert_equals_int (vps.sub_layer_ordering_info_present_flag, 1);
590
591   assert_equals_int (vps.max_dec_pic_buffering_minus1[0], 1);
592   assert_equals_int (vps.max_num_reorder_pics[0], 0);
593   assert_equals_int (vps.max_latency_increase_plus1[0], 0);
594
595   assert_equals_int (vps.max_layer_id, 5);
596   assert_equals_int (vps.num_layer_sets_minus1, 0);
597
598   assert_equals_int (vps.timing_info_present_flag, 0);
599   assert_equals_int (vps.vps_extension, 0);
600
601   gst_h265_parser_free (parser);
602 }
603
604 GST_END_TEST;
605
606 GST_START_TEST (test_h265_parse_pps)
607 {
608   GstH265Parser *parser;
609   GstH265NalUnit nalu;
610   GstH265ParserResult res;
611   GstH265PPS pps;
612
613   parser = gst_h265_parser_new ();
614
615   /*init sps[15] to avoid return error in gst_h265_parser_parse_pps */
616   parser->sps[15].valid = TRUE;
617   parser->sps[15].log2_diff_max_min_luma_coding_block_size = 1;
618
619   res = gst_h265_parser_identify_nalu_unchecked (parser,
620       h265_pps_with_range_extension, 0,
621       sizeof (h265_pps_with_range_extension), &nalu);
622
623   assert_equals_int (res, GST_H265_PARSER_OK);
624   assert_equals_int (nalu.type, GST_H265_NAL_PPS);
625
626   res = gst_h265_parser_parse_pps (parser, &nalu, &pps);
627
628   assert_equals_int (res, GST_H265_PARSER_OK);
629   assert_equals_int (pps.pps_range_extension_flag, 1);
630   assert_equals_int (pps.pps_multilayer_extension_flag, 0);
631   assert_equals_int (pps.pps_3d_extension_flag, 0);
632   assert_equals_int (pps.pps_extension_5bits, 0);
633   assert_equals_int (pps.
634       pps_extension_params.log2_max_transform_skip_block_size_minus2, 0);
635   assert_equals_int (pps.
636       pps_extension_params.cross_component_prediction_enabled_flag, 0);
637   assert_equals_int (pps.
638       pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
639   assert_equals_int (pps.pps_extension_params.diff_cu_chroma_qp_offset_depth,
640       1);
641   assert_equals_int (pps.pps_extension_params.chroma_qp_offset_list_len_minus1,
642       5);
643   assert_equals_int (pps.pps_extension_params.log2_sao_offset_scale_luma, 0);
644   assert_equals_int (pps.pps_extension_params.log2_sao_offset_scale_chroma, 0);
645
646   gst_h265_parser_free (parser);
647 }
648
649 GST_END_TEST;
650
651 typedef struct
652 {
653   GstH265NalUnitType type;
654   gboolean is_idr;
655   gboolean is_irap;
656   gboolean is_bla;
657   gboolean is_cra;
658   gboolean is_radl;
659   gboolean is_rasl;
660 } H265NalTypeTestVector;
661
662 GST_START_TEST (test_h265_nal_type_classification)
663 {
664   gint i;
665   /* *INDENT-OFF* */
666   H265NalTypeTestVector test_vector[] = {
667     /*         NAL-TYPE             IDR    IRAP   BLA    CRA    RADL   RASL */
668     {GST_H265_NAL_SLICE_TRAIL_N,    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
669     {GST_H265_NAL_SLICE_TRAIL_R,    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
670     {GST_H265_NAL_SLICE_TSA_N,      FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
671     {GST_H265_NAL_SLICE_TSA_R,      FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
672     {GST_H265_NAL_SLICE_STSA_N,     FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
673     {GST_H265_NAL_SLICE_STSA_R,     FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
674     {GST_H265_NAL_SLICE_RADL_N,     FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE},
675     {GST_H265_NAL_SLICE_RADL_R,     FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE},
676     {GST_H265_NAL_SLICE_RASL_N,     FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
677     {GST_H265_NAL_SLICE_RASL_R,     FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
678     /* 10 ~ 15: reserved non-irap sublayer nal */
679     {GST_H265_NAL_SLICE_BLA_W_LP,   FALSE, TRUE,  TRUE,  FALSE, FALSE, FALSE},
680     {GST_H265_NAL_SLICE_BLA_W_RADL, FALSE, TRUE,  TRUE,  FALSE, FALSE, FALSE},
681     {GST_H265_NAL_SLICE_BLA_N_LP,   FALSE, TRUE,  TRUE,  FALSE, FALSE, FALSE},
682     {GST_H265_NAL_SLICE_IDR_W_RADL, TRUE,  TRUE,  FALSE, FALSE, FALSE, FALSE},
683     {GST_H265_NAL_SLICE_IDR_N_LP,   TRUE,  TRUE,  FALSE, FALSE, FALSE, FALSE},
684     {GST_H265_NAL_SLICE_CRA_NUT,    FALSE, TRUE,  FALSE, TRUE,  FALSE, FALSE},
685     /* 22 ~ 23: reserved irap nal */
686     {(GstH265NalUnitType) 22,       FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE},
687     {(GstH265NalUnitType) 23,       FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE},
688   };
689   /* *INDENT-ON* */
690
691   for (i = 0; i < G_N_ELEMENTS (test_vector); i++) {
692     assert_equals_int (GST_H265_IS_NAL_TYPE_IDR (test_vector[i].type),
693         test_vector[i].is_idr);
694     assert_equals_int (GST_H265_IS_NAL_TYPE_IRAP (test_vector[i].type),
695         test_vector[i].is_irap);
696     assert_equals_int (GST_H265_IS_NAL_TYPE_BLA (test_vector[i].type),
697         test_vector[i].is_bla);
698     assert_equals_int (GST_H265_IS_NAL_TYPE_CRA (test_vector[i].type),
699         test_vector[i].is_cra);
700     assert_equals_int (GST_H265_IS_NAL_TYPE_RADL (test_vector[i].type),
701         test_vector[i].is_radl);
702     assert_equals_int (GST_H265_IS_NAL_TYPE_RASL (test_vector[i].type),
703         test_vector[i].is_rasl);
704   }
705
706   for (i = RESERVED_NON_IRAP_NAL_TYPE_MIN;
707       i <= UNSPECIFIED_NON_VCL_NAL_TYPE_MAX; i++) {
708     assert_equals_int (GST_H265_IS_NAL_TYPE_IDR (i), FALSE);
709     assert_equals_int (GST_H265_IS_NAL_TYPE_IRAP (i), FALSE);
710     assert_equals_int (GST_H265_IS_NAL_TYPE_BLA (i), FALSE);
711     assert_equals_int (GST_H265_IS_NAL_TYPE_CRA (i), FALSE);
712     assert_equals_int (GST_H265_IS_NAL_TYPE_RADL (i), FALSE);
713     assert_equals_int (GST_H265_IS_NAL_TYPE_RASL (i), FALSE);
714   }
715 }
716
717 GST_END_TEST;
718
719 GST_START_TEST (test_h265_sei_registered_user_data)
720 {
721   GstH265ParserResult res;
722   GstH265NalUnit nalu;
723   GArray *messages = NULL;
724   GstH265SEIMessage *sei;
725   GstH265SEIMessage other_sei;
726   GstH265RegisteredUserData *user_data;
727   GstH265RegisteredUserData *other_user_data;
728   GstH265Parser *parser = gst_h265_parser_new ();
729   guint payload_size;
730
731   res = gst_h265_parser_identify_nalu_unchecked (parser,
732       h265_sei_user_data_registered, 0,
733       G_N_ELEMENTS (h265_sei_user_data_registered), &nalu);
734   assert_equals_int (res, GST_H265_PARSER_OK);
735   assert_equals_int (nalu.type, GST_H265_NAL_PREFIX_SEI);
736
737   res = gst_h265_parser_parse_sei (parser, &nalu, &messages);
738   assert_equals_int (res, GST_H265_PARSER_OK);
739   fail_unless (messages != NULL);
740   assert_equals_int (messages->len, 1);
741
742   sei = &g_array_index (messages, GstH265SEIMessage, 0);
743   assert_equals_int (sei->payloadType, GST_H265_SEI_REGISTERED_USER_DATA);
744
745   user_data = &sei->payload.registered_user_data;
746   /* start code prefix 4 bytes
747    * nalu header 2 bytes
748    * payload type 1 byte
749    * payload size 1 byte
750    * country code 1 byte (0xb5)
751    */
752   payload_size = h265_sei_user_data_registered[4 + 2 + 1];
753
754   /* excluding country_code byte */
755   assert_equals_int (payload_size - 1, user_data->size);
756   fail_if (memcmp (user_data->data,
757           &h265_sei_user_data_registered[4 + 2 + 1 + 1 + 1], user_data->size));
758
759   memset (&other_sei, 0, sizeof (GstH265SEIMessage));
760   fail_unless (gst_h265_sei_copy (&other_sei, sei));
761   assert_equals_int (other_sei.payloadType, GST_H265_SEI_REGISTERED_USER_DATA);
762
763   other_user_data = &other_sei.payload.registered_user_data;
764   fail_if (memcmp (user_data->data, other_user_data->data, user_data->size));
765
766   g_array_unref (messages);
767   gst_h265_sei_free (&other_sei);
768   gst_h265_parser_free (parser);
769 }
770
771 GST_END_TEST;
772
773 typedef gboolean (*SEICheckFunc) (gconstpointer a, gconstpointer b);
774
775 static gboolean
776 check_sei_user_data_registered (const GstH265RegisteredUserData * a,
777     const GstH265RegisteredUserData * b)
778 {
779   if (a->country_code != b->country_code)
780     return FALSE;
781
782   if ((a->country_code == 0xff) &&
783       (a->country_code_extension != b->country_code_extension))
784     return FALSE;
785
786   if (a->size != b->size)
787     return FALSE;
788
789   return !memcmp (a->data, b->data, a->size);
790 }
791
792 static gboolean
793 check_sei_time_code (const GstH265TimeCode * a, const GstH265TimeCode * b)
794 {
795   gint i;
796
797   if (a->num_clock_ts != b->num_clock_ts)
798     return FALSE;
799
800   for (i = 0; i < a->num_clock_ts; i++) {
801     if (a->clock_timestamp_flag[i] != b->clock_timestamp_flag[i])
802       return FALSE;
803
804     if (a->clock_timestamp_flag[i]) {
805       if ((a->units_field_based_flag[i] != b->units_field_based_flag[i]) ||
806           (a->counting_type[i] != b->counting_type[i]) ||
807           (a->full_timestamp_flag[i] != b->full_timestamp_flag[i]) ||
808           (a->discontinuity_flag[i] != b->discontinuity_flag[i]) ||
809           (a->cnt_dropped_flag[i] != b->cnt_dropped_flag[i]) ||
810           (a->n_frames[i] != b->n_frames[i])) {
811         return FALSE;
812       }
813
814       if (a->full_timestamp_flag[i]) {
815         if ((a->seconds_value[i] != b->seconds_value[i]) ||
816             (a->minutes_value[i] != b->minutes_value[i]) ||
817             (a->hours_value[i] != b->hours_value[i])) {
818           return FALSE;
819         }
820       } else {
821         if (a->seconds_flag[i] != b->seconds_flag[i])
822           return FALSE;
823
824         if (a->seconds_flag[i]) {
825           if ((a->seconds_value[i] != b->seconds_value[i]) ||
826               (a->minutes_flag[i] != b->minutes_flag[i])) {
827             return FALSE;
828           }
829
830           if (a->minutes_flag[i]) {
831             if ((a->minutes_value[i] != b->minutes_value[i]) ||
832                 (a->hours_flag[i] != b->hours_flag[i])) {
833               return FALSE;
834             }
835
836             if (a->hours_flag[i]) {
837               if (a->hours_value[i] != b->hours_value[i])
838                 return FALSE;
839             }
840           }
841         }
842       }
843     }
844   }
845
846   return TRUE;
847 }
848
849 static gboolean
850 check_sei_mdcv (const GstH265MasteringDisplayColourVolume * a,
851     const GstH265MasteringDisplayColourVolume * b)
852 {
853   gint i;
854   for (i = 0; i < 3; i++) {
855     if (a->display_primaries_x[i] != b->display_primaries_x[i] ||
856         a->display_primaries_y[i] != b->display_primaries_y[i])
857       return FALSE;
858   }
859
860   return (a->white_point_x == b->white_point_x) &&
861       (a->white_point_y == b->white_point_y) &&
862       (a->max_display_mastering_luminance == b->max_display_mastering_luminance)
863       && (a->min_display_mastering_luminance ==
864       b->min_display_mastering_luminance);
865 }
866
867 static gboolean
868 check_sei_cll (const GstH265ContentLightLevel * a,
869     const GstH265ContentLightLevel * b)
870 {
871   return (a->max_content_light_level == b->max_content_light_level) &&
872       (a->max_pic_average_light_level == b->max_pic_average_light_level);
873 }
874
875 GST_START_TEST (test_h265_create_sei)
876 {
877   GstH265Parser *parser;
878   GstH265ParserResult parse_ret;
879   GstH265NalUnit nalu;
880   GArray *msg_array = NULL;
881   GstMemory *mem;
882   gint i;
883   GstMapInfo info;
884   struct
885   {
886     guint8 *raw_data;
887     guint len;
888     GstH265SEIPayloadType type;
889     GstH265SEIMessage parsed_message;
890     SEICheckFunc check_func;
891   } test_list[] = {
892     /* *INDENT-OFF* */
893     {h265_sei_user_data_registered, G_N_ELEMENTS (h265_sei_user_data_registered),
894         GST_H265_SEI_REGISTERED_USER_DATA, {0,},
895         (SEICheckFunc) check_sei_user_data_registered},
896     {h265_sei_time_code, G_N_ELEMENTS (h265_sei_time_code),
897         GST_H265_SEI_TIME_CODE, {0,}, (
898         SEICheckFunc) check_sei_time_code},
899     {h265_sei_mdcv, G_N_ELEMENTS (h265_sei_mdcv),
900         GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME, {0,},
901         (SEICheckFunc) check_sei_mdcv},
902     {h265_sei_cll, G_N_ELEMENTS (h265_sei_cll),
903         GST_H265_SEI_CONTENT_LIGHT_LEVEL, {0,},
904         (SEICheckFunc) check_sei_cll},
905     /* *INDENT-ON* */
906   };
907
908   parser = gst_h265_parser_new ();
909
910   /* test single sei message per sei nal unit */
911   for (i = 0; i < G_N_ELEMENTS (test_list); i++) {
912     gsize nal_size;
913
914     parse_ret = gst_h265_parser_identify_nalu_unchecked (parser,
915         test_list[i].raw_data, 0, test_list[i].len, &nalu);
916     assert_equals_int (parse_ret, GST_H265_PARSER_OK);
917     assert_equals_int (nalu.type, GST_H265_NAL_PREFIX_SEI);
918
919     parse_ret = gst_h265_parser_parse_sei (parser, &nalu, &msg_array);
920     assert_equals_int (parse_ret, GST_H265_PARSER_OK);
921     assert_equals_int (msg_array->len, 1);
922
923     /* test bytestream */
924     mem = gst_h265_create_sei_memory (nalu.layer_id,
925         nalu.temporal_id_plus1, 4, msg_array);
926     fail_unless (mem != NULL);
927     fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
928     GST_MEMDUMP ("created sei nal", info.data, info.size);
929     GST_MEMDUMP ("original sei nal", test_list[i].raw_data, test_list[i].len);
930     assert_equals_int (info.size, test_list[i].len);
931     fail_if (memcmp (info.data, test_list[i].raw_data, test_list[i].len));
932     gst_memory_unmap (mem, &info);
933     gst_memory_unref (mem);
934
935     /* test packetized */
936     mem = gst_h265_create_sei_memory_hevc (nalu.layer_id,
937         nalu.temporal_id_plus1, 4, msg_array);
938     fail_unless (mem != NULL);
939     fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
940     assert_equals_int (info.size, test_list[i].len);
941     fail_if (memcmp (info.data + 4, test_list[i].raw_data + 4,
942             test_list[i].len - 4));
943     nal_size = GST_READ_UINT32_BE (info.data);
944     assert_equals_int (nal_size, info.size - 4);
945     gst_memory_unmap (mem, &info);
946     gst_memory_unref (mem);
947
948     /* store parsed SEI for following tests */
949     fail_unless (gst_h265_sei_copy (&test_list[i].parsed_message,
950             &g_array_index (msg_array, GstH265SEIMessage, 0)));
951
952     g_array_unref (msg_array);
953   }
954
955   /* test multiple SEI messages in a nal unit */
956   msg_array = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
957   for (i = 0; i < G_N_ELEMENTS (test_list); i++)
958     g_array_append_val (msg_array, test_list[i].parsed_message);
959
960   mem = gst_h265_create_sei_memory (nalu.layer_id,
961       nalu.temporal_id_plus1, 4, msg_array);
962   fail_unless (mem != NULL);
963   g_array_unref (msg_array);
964
965   /* parse sei message from buffer */
966   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
967   parse_ret = gst_h265_parser_identify_nalu_unchecked (parser,
968       info.data, 0, info.size, &nalu);
969   assert_equals_int (parse_ret, GST_H265_PARSER_OK);
970   assert_equals_int (nalu.type, GST_H265_NAL_PREFIX_SEI);
971   parse_ret = gst_h265_parser_parse_sei (parser, &nalu, &msg_array);
972   gst_memory_unmap (mem, &info);
973   gst_memory_unref (mem);
974
975   assert_equals_int (parse_ret, GST_H265_PARSER_OK);
976   assert_equals_int (msg_array->len, G_N_ELEMENTS (test_list));
977   for (i = 0; i < msg_array->len; i++) {
978     GstH265SEIMessage *msg = &g_array_index (msg_array, GstH265SEIMessage, i);
979
980     assert_equals_int (msg->payloadType, test_list[i].type);
981     fail_unless (test_list[i].check_func (&msg->payload,
982             &test_list[i].parsed_message.payload));
983   }
984
985   /* clean up */
986   for (i = 0; i < G_N_ELEMENTS (test_list); i++)
987     gst_h265_sei_free (&test_list[i].parsed_message);
988
989   g_array_unref (msg_array);
990   gst_h265_parser_free (parser);
991 }
992
993 GST_END_TEST;
994
995 static Suite *
996 h265parser_suite (void)
997 {
998   Suite *s = suite_create ("H265 Parser library");
999
1000   TCase *tc_chain = tcase_create ("general");
1001
1002   suite_add_tcase (s, tc_chain);
1003   tcase_add_test (tc_chain, test_h265_parse_slice_eos_slice_eob);
1004   tcase_add_test (tc_chain, test_h265_parse_pic_timing);
1005   tcase_add_test (tc_chain, test_h265_parse_slice_6bytes);
1006   tcase_add_test (tc_chain, test_h265_base_profiles);
1007   tcase_add_test (tc_chain, test_h265_base_profiles_compat);
1008   tcase_add_test (tc_chain, test_h265_format_range_profiles_exact_match);
1009   tcase_add_test (tc_chain, test_h265_format_range_profiles_partial_match);
1010   tcase_add_test (tc_chain, test_h265_parse_vps);
1011   tcase_add_test (tc_chain, test_h265_parse_pps);
1012   tcase_add_test (tc_chain, test_h265_nal_type_classification);
1013   tcase_add_test (tc_chain, test_h265_sei_registered_user_data);
1014   tcase_add_test (tc_chain, test_h265_create_sei);
1015
1016   return s;
1017 }
1018
1019 GST_CHECK_MAIN (h265parser);