1 /* Gstreamer H.265 bitstream parser
2 * Copyright (C) 2012 Intel Corporation
3 * Copyright (C) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
4 *
5 * Contact: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 /**
24 * SECTION:gsth265parser
25 * @title: GstH265Parser
26 * @short_description: Convenience library for h265 video bitstream parsing.
27 *
28 * It offers you bitstream parsing in HEVC mode and non-HEVC mode. To identify
29 * Nals in a bitstream and parse its headers, you should call:
30 *
31 * * gst_h265_parser_identify_nalu() to identify the following nalu in
32 * non-HEVC bitstreams
33 *
34 * * gst_h265_parser_identify_nalu_hevc() to identify the nalu in
35 * HEVC bitstreams
36 *
37 * Then, depending on the #GstH265NalUnitType of the newly parsed #GstH265NalUnit,
38 * you should call the differents functions to parse the structure:
39 *
40 * * From #GST_H265_NAL_SLICE_TRAIL_N to #GST_H265_NAL_SLICE_CRA_NUT: gst_h265_parser_parse_slice_hdr()
41 *
42 * * `GST_H265_NAL_*_SEI`: gst_h265_parser_parse_sei()
43 *
44 * * #GST_H265_NAL_VPS: gst_h265_parser_parse_vps()
45 *
46 * * #GST_H265_NAL_SPS: gst_h265_parser_parse_sps()
47 *
48 * * #GST_H265_NAL_PPS: #gst_h265_parser_parse_pps()
49 *
50 * * Any other: gst_h265_parser_parse_nal()
51 *
52 * Note: You should always call gst_h265_parser_parse_nal() if you don't
53 * actually need #GstH265NalUnitType to be parsed for your personal use, in
54 * order to guarantee that the #GstH265Parser is always up to date.
55 *
56 * For more details about the structures, look at the ITU-T H.265
57 * specifications, you can download them from:
58 *
59 * * ITU-T H.265: http://www.itu.int/rec/T-REC-H.265
60 *
61 */
62
63 #ifdef HAVE_CONFIG_H
64 # include "config.h"
65 #endif
66
67 #include "nalutils.h"
68 #include "gsth265parser.h"
69
70 #include <gst/base/gstbytereader.h>
71 #include <gst/base/gstbitreader.h>
72 #include <string.h>
73 #include <math.h>
74
75 #ifndef GST_DISABLE_GST_DEBUG
76 #define GST_CAT_DEFAULT gst_h265_debug_category_get()
77 static GstDebugCategory *
gst_h265_debug_category_get(void)78 gst_h265_debug_category_get (void)
79 {
80 static gsize cat_gonce = 0;
81
82 if (g_once_init_enter (&cat_gonce)) {
83 GstDebugCategory *cat = NULL;
84
85 GST_DEBUG_CATEGORY_INIT (cat, "codecparsers_h265", 0, "h265 parse library");
86
87 g_once_init_leave (&cat_gonce, (gsize) cat);
88 }
89
90 return (GstDebugCategory *) cat_gonce;
91 }
92 #endif /* GST_DISABLE_GST_DEBUG */
93
94 /**** Default scaling_lists according to Table 7-5 and 7-6 *****/
95
96 /* Table 7-5 */
97 static const guint8 default_scaling_list0[16] = {
98 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
99 16, 16, 16, 16
100 };
101
102 /* Combined the values in Table 7-6 to make the calculation easier
103 * Default scaling list of 8x8 and 16x16 matrices for matrixId = 0, 1 and 2
104 * Default scaling list of 32x32 matrix for matrixId = 0
105 */
106 static const guint8 default_scaling_list1[64] = {
107 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16,
108 17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20,
109 21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24,
110 25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31,
111 29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70,
112 65, 88, 88, 115
113 };
114
115 /* Combined the values in Table 7-6 to make the calculation easier
116 * Default scaling list of 8x8 and 16x16 matrices for matrixId = 3, 4 and 5
117 * Default scaling list of 32x32 matrix for matrixId = 1
118 */
119 static const guint8 default_scaling_list2[64] = {
120 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
121 17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20,
122 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24,
123 25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28,
124 28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54,
125 54, 71, 71, 91
126 };
127
128 static const guint8 zigzag_4x4[16] = {
129 0, 1, 4, 8,
130 5, 2, 3, 6,
131 9, 12, 13, 10,
132 7, 11, 14, 15,
133 };
134
135 static const guint8 zigzag_8x8[64] = {
136 0, 1, 8, 16, 9, 2, 3, 10,
137 17, 24, 32, 25, 18, 11, 4, 5,
138 12, 19, 26, 33, 40, 48, 41, 34,
139 27, 20, 13, 6, 7, 14, 21, 28,
140 35, 42, 49, 56, 57, 50, 43, 36,
141 29, 22, 15, 23, 30, 37, 44, 51,
142 58, 59, 52, 45, 38, 31, 39, 46,
143 53, 60, 61, 54, 47, 55, 62, 63
144 };
145
146 static const guint8 uprightdiagonal_4x4[16] = {
147 0, 4, 1, 8,
148 5, 2, 12, 9,
149 6, 3, 13, 10,
150 7, 14, 11, 15
151 };
152
153 static const guint8 uprightdiagonal_8x8[64] = {
154 0, 8, 1, 16, 9, 2, 24, 17,
155 10, 3, 32, 25, 18, 11, 4, 40,
156 33, 26, 19, 12, 5, 48, 41, 34,
157 27, 20, 13, 6, 56, 49, 42, 35,
158 28, 21, 14, 7, 57, 50, 43, 36,
159 29, 22, 15, 58, 51, 44, 37, 30,
160 23, 59, 52, 45, 38, 31, 60, 53,
161 46, 39, 61, 54, 47, 62, 55, 63
162 };
163
164 typedef struct
165 {
166 guint par_n, par_d;
167 } PAR;
168
169 /* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
170 static const PAR aspect_ratios[17] = {
171 {0, 0},
172 {1, 1},
173 {12, 11},
174 {10, 11},
175 {16, 11},
176 {40, 33},
177 {24, 11},
178 {20, 11},
179 {32, 11},
180 {80, 33},
181 {18, 11},
182 {15, 11},
183 {64, 33},
184 {160, 99},
185 {4, 3},
186 {3, 2},
187 {2, 1}
188 };
189
190 /***** Utils ****/
191 #define EXTENDED_SAR 255
192
193 static GstH265VPS *
gst_h265_parser_get_vps(GstH265Parser * parser,guint8 vps_id)194 gst_h265_parser_get_vps (GstH265Parser * parser, guint8 vps_id)
195 {
196 GstH265VPS *vps;
197
198 vps = &parser->vps[vps_id];
199
200 if (vps->valid)
201 return vps;
202
203 return NULL;
204 }
205
206 static GstH265SPS *
gst_h265_parser_get_sps(GstH265Parser * parser,guint8 sps_id)207 gst_h265_parser_get_sps (GstH265Parser * parser, guint8 sps_id)
208 {
209 GstH265SPS *sps;
210
211 sps = &parser->sps[sps_id];
212
213 if (sps->valid)
214 return sps;
215
216 return NULL;
217 }
218
219 static GstH265PPS *
gst_h265_parser_get_pps(GstH265Parser * parser,guint8 pps_id)220 gst_h265_parser_get_pps (GstH265Parser * parser, guint8 pps_id)
221 {
222 GstH265PPS *pps;
223
224 pps = &parser->pps[pps_id];
225
226 if (pps->valid)
227 return pps;
228
229 return NULL;
230 }
231
232 static gboolean
gst_h265_parse_nalu_header(GstH265NalUnit * nalu)233 gst_h265_parse_nalu_header (GstH265NalUnit * nalu)
234 {
235 guint8 *data = nalu->data + nalu->offset;
236 GstBitReader br;
237
238 if (nalu->size < 2)
239 return FALSE;
240
241 gst_bit_reader_init (&br, data, nalu->size - nalu->offset);
242
243 /* skip the forbidden_zero_bit */
244 gst_bit_reader_skip_unchecked (&br, 1);
245
246 nalu->type = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
247 nalu->layer_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
248 nalu->temporal_id_plus1 = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
249 nalu->header_bytes = 2;
250
251 return TRUE;
252 }
253
254 struct h265_profile_string
255 {
256 GstH265Profile profile;
257 const gchar *name;
258 };
259
260 static const struct h265_profile_string h265_profiles[] = {
261 /* keep in sync with definition in the header */
262 {GST_H265_PROFILE_MAIN, "main"},
263 {GST_H265_PROFILE_MAIN_10, "main-10"},
264 {GST_H265_PROFILE_MAIN_STILL_PICTURE, "main-still-picture"},
265 {GST_H265_PROFILE_MONOCHROME, "monochrome"},
266 {GST_H265_PROFILE_MONOCHROME_12, "monochrome-12"},
267 {GST_H265_PROFILE_MONOCHROME_16, "monochrome-16"},
268 {GST_H265_PROFILE_MAIN_12, "main-12"},
269 {GST_H265_PROFILE_MAIN_422_10, "main-422-10"},
270 {GST_H265_PROFILE_MAIN_422_12, "main-422-12"},
271 {GST_H265_PROFILE_MAIN_444, "main-444"},
272 {GST_H265_PROFILE_MAIN_444_10, "main-444-10"},
273 {GST_H265_PROFILE_MAIN_444_12, "main-444-12"},
274 {GST_H265_PROFILE_MAIN_INTRA, "main-intra"},
275 {GST_H265_PROFILE_MAIN_10_INTRA, "main-10-intra"},
276 {GST_H265_PROFILE_MAIN_12_INTRA, "main-12-intra"},
277 {GST_H265_PROFILE_MAIN_422_10_INTRA, "main-422-10-intra"},
278 {GST_H265_PROFILE_MAIN_422_12_INTRA, "main-422-12-intra"},
279 {GST_H265_PROFILE_MAIN_444_INTRA, "main-444-intra"},
280 {GST_H265_PROFILE_MAIN_444_10_INTRA, "main-444-10-intra"},
281 {GST_H265_PROFILE_MAIN_444_12_INTRA, "main-444-12-intra"},
282 {GST_H265_PROFILE_MAIN_444_16_INTRA, "main-444-16-intra"},
283 {GST_H265_PROFILE_MAIN_444_STILL_PICTURE, "main-444-still-picture"},
284 {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE, "main-444-16-still-picture"},
285 {GST_H265_PROFILE_MONOCHROME_10, "monochrome-10"},
286 {GST_H265_PROFILE_HIGH_THROUGHPUT_444, "high-throughput-444"},
287 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10, "high-throughput-444-10"},
288 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14, "high-throughput-444-14"},
289 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
290 "high-throughput-444-16-intra"},
291 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN, "screen-extended-main"},
292 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10, "screen-extended-main-10"},
293 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444, "screen-extended-main-444"},
294 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10, "screen-extended-main-444-10"},
295 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
296 "screen-extended-high-throughput-444"},
297 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
298 "screen-extended-high-throughput-444-10"},
299 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
300 "screen-extended-high-throughput-444-14"},
301 {GST_H265_PROFILE_MULTIVIEW_MAIN, "multiview-main"},
302 {GST_H265_PROFILE_SCALABLE_MAIN, "scalable-main"},
303 {GST_H265_PROFILE_SCALABLE_MAIN_10, "scalable-main-10"},
304 {GST_H265_PROFILE_SCALABLE_MONOCHROME, "scalable-monochrome"},
305 {GST_H265_PROFILE_SCALABLE_MONOCHROME_12, "scalable-monochrome-12"},
306 {GST_H265_PROFILE_SCALABLE_MONOCHROME_16, "scalable-monochrome-16"},
307 {GST_H265_PROFILE_SCALABLE_MAIN_444, "scalable-main-444"},
308 {GST_H265_PROFILE_3D_MAIN, "3d-main"},
309 };
310
311 /****** Parsing functions *****/
312
313 static gboolean
gst_h265_parse_profile_tier_level(GstH265ProfileTierLevel * ptl,NalReader * nr,guint8 maxNumSubLayersMinus1)314 gst_h265_parse_profile_tier_level (GstH265ProfileTierLevel * ptl,
315 NalReader * nr, guint8 maxNumSubLayersMinus1)
316 {
317 guint i, j;
318 GST_DEBUG ("parsing \"ProfileTierLevel parameters\"");
319
320 READ_UINT8 (nr, ptl->profile_space, 2);
321 READ_UINT8 (nr, ptl->tier_flag, 1);
322 READ_UINT8 (nr, ptl->profile_idc, 5);
323
324 for (j = 0; j < 32; j++)
325 READ_UINT8 (nr, ptl->profile_compatibility_flag[j], 1);
326
327 READ_UINT8 (nr, ptl->progressive_source_flag, 1);
328 READ_UINT8 (nr, ptl->interlaced_source_flag, 1);
329 READ_UINT8 (nr, ptl->non_packed_constraint_flag, 1);
330 READ_UINT8 (nr, ptl->frame_only_constraint_flag, 1);
331
332 READ_UINT8 (nr, ptl->max_12bit_constraint_flag, 1);
333 READ_UINT8 (nr, ptl->max_10bit_constraint_flag, 1);
334 READ_UINT8 (nr, ptl->max_8bit_constraint_flag, 1);
335 READ_UINT8 (nr, ptl->max_422chroma_constraint_flag, 1);
336 READ_UINT8 (nr, ptl->max_420chroma_constraint_flag, 1);
337 READ_UINT8 (nr, ptl->max_monochrome_constraint_flag, 1);
338 READ_UINT8 (nr, ptl->intra_constraint_flag, 1);
339 READ_UINT8 (nr, ptl->one_picture_only_constraint_flag, 1);
340 READ_UINT8 (nr, ptl->lower_bit_rate_constraint_flag, 1);
341 READ_UINT8 (nr, ptl->max_14bit_constraint_flag, 1);
342
343 /* skip the reserved zero bits */
344 if (!nal_reader_skip (nr, 34))
345 goto error;
346
347 READ_UINT8 (nr, ptl->level_idc, 8);
348 for (j = 0; j < maxNumSubLayersMinus1; j++) {
349 READ_UINT8 (nr, ptl->sub_layer_profile_present_flag[j], 1);
350 READ_UINT8 (nr, ptl->sub_layer_level_present_flag[j], 1);
351 }
352
353 if (maxNumSubLayersMinus1 > 0) {
354 for (i = maxNumSubLayersMinus1; i < 8; i++)
355 if (!nal_reader_skip (nr, 2))
356 goto error;
357 }
358
359 for (i = 0; i < maxNumSubLayersMinus1; i++) {
360 if (ptl->sub_layer_profile_present_flag[i]) {
361 READ_UINT8 (nr, ptl->sub_layer_profile_space[i], 2);
362 READ_UINT8 (nr, ptl->sub_layer_tier_flag[i], 1);
363 READ_UINT8 (nr, ptl->sub_layer_profile_idc[i], 5);
364
365 for (j = 0; j < 32; j++)
366 READ_UINT8 (nr, ptl->sub_layer_profile_compatibility_flag[i][j], 1);
367
368 READ_UINT8 (nr, ptl->sub_layer_progressive_source_flag[i], 1);
369 READ_UINT8 (nr, ptl->sub_layer_interlaced_source_flag[i], 1);
370 READ_UINT8 (nr, ptl->sub_layer_non_packed_constraint_flag[i], 1);
371 READ_UINT8 (nr, ptl->sub_layer_frame_only_constraint_flag[i], 1);
372
373 if (!nal_reader_skip (nr, 44))
374 goto error;
375 }
376
377 if (ptl->sub_layer_level_present_flag[i])
378 READ_UINT8 (nr, ptl->sub_layer_level_idc[i], 8);
379 }
380
381 return TRUE;
382
383 error:
384 GST_WARNING ("error parsing \"ProfileTierLevel Parameters\"");
385 return FALSE;
386 }
387
388 static gboolean
gst_h265_parse_sub_layer_hrd_parameters(GstH265SubLayerHRDParams * sub_hrd,NalReader * nr,guint8 CpbCnt,guint8 sub_pic_hrd_params_present_flag)389 gst_h265_parse_sub_layer_hrd_parameters (GstH265SubLayerHRDParams * sub_hrd,
390 NalReader * nr, guint8 CpbCnt, guint8 sub_pic_hrd_params_present_flag)
391 {
392 guint i;
393
394 GST_DEBUG ("parsing \"SubLayer HRD Parameters\"");
395
396 for (i = 0; i <= CpbCnt; i++) {
397 READ_UE_MAX (nr, sub_hrd->bit_rate_value_minus1[i], G_MAXUINT32 - 1);
398 READ_UE_MAX (nr, sub_hrd->cpb_size_value_minus1[i], G_MAXUINT32 - 1);
399
400 if (sub_pic_hrd_params_present_flag) {
401 READ_UE_MAX (nr, sub_hrd->cpb_size_du_value_minus1[i], G_MAXUINT32 - 1);
402 READ_UE_MAX (nr, sub_hrd->bit_rate_du_value_minus1[i], G_MAXUINT32 - 1);
403 }
404
405 READ_UINT8 (nr, sub_hrd->cbr_flag[i], 1);
406 }
407
408 return TRUE;
409
410 error:
411 GST_WARNING ("error parsing \"SubLayerHRD Parameters \"");
412 return FALSE;
413 }
414
415 static gboolean
gst_h265_parse_hrd_parameters(GstH265HRDParams * hrd,NalReader * nr,guint8 commonInfPresentFlag,guint8 maxNumSubLayersMinus1)416 gst_h265_parse_hrd_parameters (GstH265HRDParams * hrd, NalReader * nr,
417 guint8 commonInfPresentFlag, guint8 maxNumSubLayersMinus1)
418 {
419 guint i;
420
421 GST_DEBUG ("parsing \"HRD Parameters\"");
422
423 /* set default values for fields that might not be present in the bitstream
424 and have valid defaults */
425 hrd->initial_cpb_removal_delay_length_minus1 = 23;
426 hrd->au_cpb_removal_delay_length_minus1 = 23;
427 hrd->dpb_output_delay_length_minus1 = 23;
428
429 if (commonInfPresentFlag) {
430 READ_UINT8 (nr, hrd->nal_hrd_parameters_present_flag, 1);
431 READ_UINT8 (nr, hrd->vcl_hrd_parameters_present_flag, 1);
432
433 if (hrd->nal_hrd_parameters_present_flag
434 || hrd->vcl_hrd_parameters_present_flag) {
435
436 READ_UINT8 (nr, hrd->sub_pic_hrd_params_present_flag, 1);
437
438 if (hrd->sub_pic_hrd_params_present_flag) {
439 READ_UINT8 (nr, hrd->tick_divisor_minus2, 8);
440 READ_UINT8 (nr, hrd->du_cpb_removal_delay_increment_length_minus1, 5);
441 READ_UINT8 (nr, hrd->sub_pic_cpb_params_in_pic_timing_sei_flag, 1);
442 READ_UINT8 (nr, hrd->dpb_output_delay_du_length_minus1, 5);
443 }
444
445 READ_UINT8 (nr, hrd->bit_rate_scale, 4);
446 READ_UINT8 (nr, hrd->cpb_size_scale, 4);
447
448 if (hrd->sub_pic_hrd_params_present_flag)
449 READ_UINT8 (nr, hrd->cpb_size_du_scale, 4);
450
451 READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
452 READ_UINT8 (nr, hrd->au_cpb_removal_delay_length_minus1, 5);
453 READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
454 }
455 }
456
457 for (i = 0; i <= maxNumSubLayersMinus1; i++) {
458 READ_UINT8 (nr, hrd->fixed_pic_rate_general_flag[i], 1);
459
460 if (!hrd->fixed_pic_rate_general_flag[i]) {
461 READ_UINT8 (nr, hrd->fixed_pic_rate_within_cvs_flag[i], 1);
462 } else
463 hrd->fixed_pic_rate_within_cvs_flag[i] = 1;
464
465 if (hrd->fixed_pic_rate_within_cvs_flag[i]) {
466 READ_UE_MAX (nr, hrd->elemental_duration_in_tc_minus1[i], 2047);
467 } else
468 READ_UINT8 (nr, hrd->low_delay_hrd_flag[i], 1);
469
470 if (!hrd->low_delay_hrd_flag[i])
471 READ_UE_MAX (nr, hrd->cpb_cnt_minus1[i], 31);
472
473 if (hrd->nal_hrd_parameters_present_flag)
474 if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
475 [i], nr, hrd->cpb_cnt_minus1[i],
476 hrd->sub_pic_hrd_params_present_flag))
477 goto error;
478
479 if (hrd->vcl_hrd_parameters_present_flag)
480 if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
481 [i], nr, hrd->cpb_cnt_minus1[i],
482 hrd->sub_pic_hrd_params_present_flag))
483 goto error;
484 }
485
486 return TRUE;
487
488 error:
489 GST_WARNING ("error parsing \"HRD Parameters\"");
490 return FALSE;
491 }
492
493 static gboolean
gst_h265_parse_vui_parameters(GstH265SPS * sps,NalReader * nr)494 gst_h265_parse_vui_parameters (GstH265SPS * sps, NalReader * nr)
495 {
496 GstH265VUIParams *vui = &sps->vui_params;
497
498 GST_DEBUG ("parsing \"VUI Parameters\"");
499
500 /* set default values for fields that might not be present in the bitstream
501 and have valid defaults */
502 vui->video_format = 5;
503 vui->colour_primaries = 2;
504 vui->transfer_characteristics = 2;
505 vui->matrix_coefficients = 2;
506 vui->motion_vectors_over_pic_boundaries_flag = 1;
507 vui->max_bytes_per_pic_denom = 2;
508 vui->max_bits_per_min_cu_denom = 1;
509 vui->log2_max_mv_length_horizontal = 15;
510 vui->log2_max_mv_length_vertical = 15;
511
512 if (sps && sps->profile_tier_level.progressive_source_flag
513 && sps->profile_tier_level.interlaced_source_flag)
514 vui->frame_field_info_present_flag = 1;
515
516 READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
517 if (vui->aspect_ratio_info_present_flag) {
518 READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
519 if (vui->aspect_ratio_idc == EXTENDED_SAR) {
520 READ_UINT16 (nr, vui->sar_width, 16);
521 READ_UINT16 (nr, vui->sar_height, 16);
522 vui->par_n = vui->sar_width;
523 vui->par_d = vui->sar_height;
524 } else if (vui->aspect_ratio_idc <= 16) {
525 vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
526 vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
527 }
528 }
529
530 READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
531 if (vui->overscan_info_present_flag)
532 READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);
533
534 READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
535 if (vui->video_signal_type_present_flag) {
536
537 READ_UINT8 (nr, vui->video_format, 3);
538 READ_UINT8 (nr, vui->video_full_range_flag, 1);
539 READ_UINT8 (nr, vui->colour_description_present_flag, 1);
540 if (vui->colour_description_present_flag) {
541 READ_UINT8 (nr, vui->colour_primaries, 8);
542 READ_UINT8 (nr, vui->transfer_characteristics, 8);
543 READ_UINT8 (nr, vui->matrix_coefficients, 8);
544 }
545 }
546
547 READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
548 if (vui->chroma_loc_info_present_flag) {
549 READ_UE_MAX (nr, vui->chroma_sample_loc_type_top_field, 5);
550 READ_UE_MAX (nr, vui->chroma_sample_loc_type_bottom_field, 5);
551 }
552
553 READ_UINT8 (nr, vui->neutral_chroma_indication_flag, 1);
554 READ_UINT8 (nr, vui->field_seq_flag, 1);
555 READ_UINT8 (nr, vui->frame_field_info_present_flag, 1);
556
557 READ_UINT8 (nr, vui->default_display_window_flag, 1);
558 if (vui->default_display_window_flag) {
559 READ_UE (nr, vui->def_disp_win_left_offset);
560 READ_UE (nr, vui->def_disp_win_right_offset);
561 READ_UE (nr, vui->def_disp_win_top_offset);
562 READ_UE (nr, vui->def_disp_win_bottom_offset);
563 }
564
565 READ_UINT8 (nr, vui->timing_info_present_flag, 1);
566 if (vui->timing_info_present_flag) {
567 READ_UINT32 (nr, vui->num_units_in_tick, 32);
568 if (vui->num_units_in_tick == 0)
569 GST_WARNING ("num_units_in_tick = 0 detected in stream "
570 "(incompliant to H.265 E.2.1).");
571
572 READ_UINT32 (nr, vui->time_scale, 32);
573 if (vui->time_scale == 0)
574 GST_WARNING ("time_scale = 0 detected in stream "
575 "(incompliant to H.265 E.2.1).");
576
577 READ_UINT8 (nr, vui->poc_proportional_to_timing_flag, 1);
578 if (vui->poc_proportional_to_timing_flag)
579 READ_UE_MAX (nr, vui->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
580
581 READ_UINT8 (nr, vui->hrd_parameters_present_flag, 1);
582 if (vui->hrd_parameters_present_flag)
583 if (!gst_h265_parse_hrd_parameters (&vui->hrd_params, nr, 1,
584 sps->max_sub_layers_minus1))
585 goto error;
586 }
587
588 READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
589 if (vui->bitstream_restriction_flag) {
590 READ_UINT8 (nr, vui->tiles_fixed_structure_flag, 1);
591 READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
592 READ_UINT8 (nr, vui->restricted_ref_pic_lists_flag, 1);
593 READ_UE_MAX (nr, vui->min_spatial_segmentation_idc, 4096);
594 READ_UE_MAX (nr, vui->max_bytes_per_pic_denom, 16);
595 READ_UE_MAX (nr, vui->max_bits_per_min_cu_denom, 16);
596 READ_UE_MAX (nr, vui->log2_max_mv_length_horizontal, 16);
597 READ_UE_MAX (nr, vui->log2_max_mv_length_vertical, 15);
598 }
599
600 return TRUE;
601
602 error:
603 GST_WARNING ("error parsing \"VUI Parameters\"");
604 return FALSE;
605 }
606
607 static gboolean
get_scaling_list_params(GstH265ScalingList * dest_scaling_list,guint8 sizeId,guint8 matrixId,guint8 ** sl,guint8 * size,gint16 ** scaling_list_dc_coef_minus8)608 get_scaling_list_params (GstH265ScalingList * dest_scaling_list,
609 guint8 sizeId, guint8 matrixId, guint8 ** sl, guint8 * size,
610 gint16 ** scaling_list_dc_coef_minus8)
611 {
612 switch (sizeId) {
613 case GST_H265_QUANT_MATIX_4X4:
614 *sl = dest_scaling_list->scaling_lists_4x4[matrixId];
615 if (size)
616 *size = 16;
617 break;
618 case GST_H265_QUANT_MATIX_8X8:
619 *sl = dest_scaling_list->scaling_lists_8x8[matrixId];
620 if (size)
621 *size = 64;
622 break;
623 case GST_H265_QUANT_MATIX_16X16:
624 *sl = dest_scaling_list->scaling_lists_16x16[matrixId];
625 if (size)
626 *size = 64;
627 if (scaling_list_dc_coef_minus8)
628 *scaling_list_dc_coef_minus8 =
629 dest_scaling_list->scaling_list_dc_coef_minus8_16x16;
630 break;
631 case GST_H265_QUANT_MATIX_32X32:
632 *sl = dest_scaling_list->scaling_lists_32x32[matrixId];
633 if (size)
634 *size = 64;
635 if (scaling_list_dc_coef_minus8)
636 *scaling_list_dc_coef_minus8 =
637 dest_scaling_list->scaling_list_dc_coef_minus8_32x32;
638 break;
639 default:
640 return FALSE;
641 }
642 return TRUE;
643 }
644
645 static gboolean
get_default_scaling_lists(guint8 ** sl,guint8 sizeId,guint8 matrixId)646 get_default_scaling_lists (guint8 ** sl, guint8 sizeId, guint8 matrixId)
647 {
648 switch (sizeId) {
649 case GST_H265_QUANT_MATIX_4X4:
650 memcpy (*sl, default_scaling_list0, 16);
651 break;
652
653 case GST_H265_QUANT_MATIX_8X8:
654 case GST_H265_QUANT_MATIX_16X16:
655 if (matrixId <= 2)
656 memcpy (*sl, default_scaling_list1, 64);
657 else
658 memcpy (*sl, default_scaling_list2, 64);
659 break;
660
661 case GST_H265_QUANT_MATIX_32X32:
662 if (matrixId == 0)
663 memcpy (*sl, default_scaling_list1, 64);
664 else
665 memcpy (*sl, default_scaling_list2, 64);
666 break;
667
668 default:
669 return FALSE;
670 break;
671 }
672 return TRUE;
673 }
674
675 static gboolean
gst_h265_parser_parse_scaling_lists(NalReader * nr,GstH265ScalingList * dest_scaling_list,gboolean use_default)676 gst_h265_parser_parse_scaling_lists (NalReader * nr,
677 GstH265ScalingList * dest_scaling_list, gboolean use_default)
678 {
679 guint8 sizeId;
680 guint8 matrixId;
681 guint8 scaling_list_pred_mode_flag = 0;
682 guint8 scaling_list_pred_matrix_id_delta = 0;
683 guint8 size, i;
684
685 GST_DEBUG ("parsing scaling lists");
686
687 for (sizeId = 0; sizeId < 4; sizeId++) {
688 for (matrixId = 0; matrixId < ((sizeId == 3) ? 2 : 6); matrixId++) {
689 gint16 *scaling_list_dc_coef_minus8 = NULL;
690 guint8 *sl;
691
692 if (!get_scaling_list_params (dest_scaling_list, sizeId, matrixId, &sl,
693 &size, &scaling_list_dc_coef_minus8))
694 goto error;
695
696 /* use_default_scaling_matrices forcefully which means,
697 * sps_scaling_list_enabled_flag=TRUE,
698 * sps_scaling_list_data_present_flag=FALSE,
699 * pps_scaling_list_data_present_falg=FALSE */
700 if (use_default) {
701 if (!get_default_scaling_lists (&sl, sizeId, matrixId))
702 goto error;
703
704 /* Inferring the value of scaling_list_dc_coef_minus8 */
705 if (sizeId > 1)
706 scaling_list_dc_coef_minus8[matrixId] = 8;
707
708 } else {
709 READ_UINT8 (nr, scaling_list_pred_mode_flag, 1);
710
711 if (!scaling_list_pred_mode_flag) {
712 guint8 refMatrixId;
713
714 READ_UE_MAX (nr, scaling_list_pred_matrix_id_delta, matrixId);
715
716 if (!scaling_list_pred_matrix_id_delta) {
717 if (!get_default_scaling_lists (&sl, sizeId, matrixId))
718 goto error;
719
720 /* Inferring the value of scaling_list_dc_coef_minus8 */
721 if (sizeId > 1)
722 scaling_list_dc_coef_minus8[matrixId] = 8;
723
724 } else {
725 guint8 *temp_sl;
726
727 refMatrixId = matrixId - scaling_list_pred_matrix_id_delta; /* 7-30 */
728
729 if (!get_scaling_list_params (dest_scaling_list, sizeId,
730 refMatrixId, &temp_sl, NULL, NULL))
731 goto error;
732
733 for (i = 0; i < size; i++)
734 sl[i] = temp_sl[i]; /* 7-31 */
735
736
737 /* Inferring the value of scaling_list_dc_coef_minus8 */
738 if (sizeId > 1)
739 scaling_list_dc_coef_minus8[matrixId] =
740 scaling_list_dc_coef_minus8[refMatrixId];
741 }
742 } else {
743 guint8 nextCoef = 8;
744 gint8 scaling_list_delta_coef;
745
746 if (sizeId > 1) {
747 READ_SE_ALLOWED (nr, scaling_list_dc_coef_minus8[matrixId], -7,
748 247);
749 nextCoef = scaling_list_dc_coef_minus8[matrixId] + 8;
750 }
751
752 for (i = 0; i < size; i++) {
753 READ_SE_ALLOWED (nr, scaling_list_delta_coef, -128, 127);
754 nextCoef = (nextCoef + scaling_list_delta_coef) & 0xff;
755 sl[i] = nextCoef;
756 }
757 }
758 }
759 }
760 }
761
762 return TRUE;
763
764 error:
765 GST_WARNING ("error parsing scaling lists");
766 return FALSE;
767 }
768
769 static gboolean
gst_h265_parser_parse_short_term_ref_pic_sets(GstH265ShortTermRefPicSet * stRPS,NalReader * nr,guint8 stRpsIdx,GstH265SPS * sps)770 gst_h265_parser_parse_short_term_ref_pic_sets (GstH265ShortTermRefPicSet *
771 stRPS, NalReader * nr, guint8 stRpsIdx, GstH265SPS * sps)
772 {
773 guint8 num_short_term_ref_pic_sets;
774 guint8 RefRpsIdx = 0;
775 gint16 deltaRps = 0;
776 guint8 use_delta_flag[16] = { 0 };
777 guint8 used_by_curr_pic_flag[16] = { 0 };
778 guint32 delta_poc_s0_minus1[16] = { 0 };
779 guint32 delta_poc_s1_minus1[16] = { 0 };
780 gint j, i = 0;
781 gint dPoc;
782
783 GST_DEBUG ("parsing \"ShortTermRefPicSetParameters\"");
784
785 /* set default values for fields that might not be present in the bitstream
786 and have valid defaults */
787 for (j = 0; j < 16; j++)
788 use_delta_flag[j] = 1;
789
790 num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
791
792 if (stRpsIdx != 0)
793 READ_UINT8 (nr, stRPS->inter_ref_pic_set_prediction_flag, 1);
794
795 if (stRPS->inter_ref_pic_set_prediction_flag) {
796 GstH265ShortTermRefPicSet *RefRPS;
797
798 if (stRpsIdx == num_short_term_ref_pic_sets)
799 READ_UE_MAX (nr, stRPS->delta_idx_minus1, stRpsIdx - 1);
800
801 READ_UINT8 (nr, stRPS->delta_rps_sign, 1);
802 READ_UE_MAX (nr, stRPS->abs_delta_rps_minus1, 32767);
803
804 RefRpsIdx = stRpsIdx - stRPS->delta_idx_minus1 - 1; /* 7-45 */
805 deltaRps = (1 - 2 * stRPS->delta_rps_sign) * (stRPS->abs_delta_rps_minus1 + 1); /* 7-46 */
806
807 RefRPS = &sps->short_term_ref_pic_set[RefRpsIdx];
808 stRPS->NumDeltaPocsOfRefRpsIdx = RefRPS->NumDeltaPocs;
809
810 for (j = 0; j <= RefRPS->NumDeltaPocs; j++) {
811 READ_UINT8 (nr, used_by_curr_pic_flag[j], 1);
812 if (!used_by_curr_pic_flag[j])
813 READ_UINT8 (nr, use_delta_flag[j], 1);
814 }
815
816 /* 7-47: calculate NumNegativePics, DeltaPocS0 and UsedByCurrPicS0 */
817 i = 0;
818 for (j = (RefRPS->NumPositivePics - 1); j >= 0; j--) {
819 dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
820 if (dPoc < 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
821 stRPS->DeltaPocS0[i] = dPoc;
822 stRPS->UsedByCurrPicS0[i++] =
823 used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
824 }
825 }
826 if (deltaRps < 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
827 stRPS->DeltaPocS0[i] = deltaRps;
828 stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
829 }
830 for (j = 0; j < RefRPS->NumNegativePics; j++) {
831 dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
832 if (dPoc < 0 && use_delta_flag[j]) {
833 stRPS->DeltaPocS0[i] = dPoc;
834 stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[j];
835 }
836 }
837 stRPS->NumNegativePics = i;
838
839 /* 7-48: calculate NumPositivePics, DeltaPocS1 and UsedByCurrPicS1 */
840 i = 0;
841 for (j = (RefRPS->NumNegativePics - 1); j >= 0; j--) {
842 dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
843 if (dPoc > 0 && use_delta_flag[j]) {
844 stRPS->DeltaPocS1[i] = dPoc;
845 stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[j];
846 }
847 }
848 if (deltaRps > 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
849 stRPS->DeltaPocS1[i] = deltaRps;
850 stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
851 }
852 for (j = 0; j < RefRPS->NumPositivePics; j++) {
853 dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
854 if (dPoc > 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
855 stRPS->DeltaPocS1[i] = dPoc;
856 stRPS->UsedByCurrPicS1[i++] =
857 used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
858 }
859 }
860 stRPS->NumPositivePics = i;
861
862 } else {
863 /* 7-49 */
864 READ_UE_MAX (nr, stRPS->NumNegativePics,
865 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1]);
866
867 /* 7-50 */
868 READ_UE_MAX (nr, stRPS->NumPositivePics,
869 (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] -
870 stRPS->NumNegativePics));
871
872 for (i = 0; i < stRPS->NumNegativePics; i++) {
873 READ_UE_MAX (nr, delta_poc_s0_minus1[i], 32767);
874 /* 7-51 */
875 READ_UINT8 (nr, stRPS->UsedByCurrPicS0[i], 1);
876
877 if (i == 0) {
878 /* 7-53 */
879 stRPS->DeltaPocS0[i] = -(delta_poc_s0_minus1[i] + 1);
880 } else {
881 /* 7-55 */
882 stRPS->DeltaPocS0[i] =
883 stRPS->DeltaPocS0[i - 1] - (delta_poc_s0_minus1[i] + 1);
884 }
885 }
886
887 for (j = 0; j < stRPS->NumPositivePics; j++) {
888 READ_UE_MAX (nr, delta_poc_s1_minus1[j], 32767);
889
890 /* 7-52 */
891 READ_UINT8 (nr, stRPS->UsedByCurrPicS1[j], 1);
892
893 if (j == 0) {
894 /* 7-54 */
895 stRPS->DeltaPocS1[j] = delta_poc_s1_minus1[j] + 1;
896 } else {
897 /* 7-56 */
898 stRPS->DeltaPocS1[j] =
899 stRPS->DeltaPocS1[j - 1] + (delta_poc_s1_minus1[j] + 1);
900 }
901 }
902
903 }
904
905 /* 7-57 */
906 stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;
907
908 return TRUE;
909
910 error:
911 GST_WARNING ("error parsing \"ShortTermRefPicSet Parameters\"");
912 return FALSE;
913 }
914
915 static gboolean
gst_h265_slice_parse_ref_pic_list_modification(GstH265SliceHdr * slice,NalReader * nr,gint NumPocTotalCurr)916 gst_h265_slice_parse_ref_pic_list_modification (GstH265SliceHdr * slice,
917 NalReader * nr, gint NumPocTotalCurr)
918 {
919 guint i;
920 GstH265RefPicListModification *rpl_mod = &slice->ref_pic_list_modification;
921 const guint n = ceil_log2 (NumPocTotalCurr);
922
923 READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l0, 1);
924
925 if (rpl_mod->ref_pic_list_modification_flag_l0) {
926 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
927 READ_UINT32 (nr, rpl_mod->list_entry_l0[i], n);
928 CHECK_ALLOWED_MAX (rpl_mod->list_entry_l0[i], (NumPocTotalCurr - 1));
929 }
930 }
931 if (GST_H265_IS_B_SLICE (slice)) {
932 READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l1, 1);
933 if (rpl_mod->ref_pic_list_modification_flag_l1)
934 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
935 READ_UINT32 (nr, rpl_mod->list_entry_l1[i], n);
936 CHECK_ALLOWED_MAX (rpl_mod->list_entry_l1[i], (NumPocTotalCurr - 1));
937 }
938 }
939
940 return TRUE;
941
942 error:
943 GST_WARNING ("error parsing \"Reference picture list modifications\"");
944 return FALSE;
945 }
946
947 static gboolean
gst_h265_slice_parse_pred_weight_table(GstH265SliceHdr * slice,NalReader * nr)948 gst_h265_slice_parse_pred_weight_table (GstH265SliceHdr * slice, NalReader * nr)
949 {
950 GstH265PredWeightTable *p;
951 gint i, j;
952 GstH265PPS *pps = slice->pps;
953 GstH265SPS *sps = pps->sps;
954
955 GST_DEBUG ("parsing \"Prediction weight table\"");
956
957 p = &slice->pred_weight_table;
958
959 READ_UE_MAX (nr, p->luma_log2_weight_denom, 7);
960
961 if (sps->chroma_format_idc != 0) {
962 READ_SE_ALLOWED (nr, p->delta_chroma_log2_weight_denom,
963 (0 - p->luma_log2_weight_denom), (7 - p->luma_log2_weight_denom));
964 }
965
966 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
967 READ_UINT8 (nr, p->luma_weight_l0_flag[i], 1);
968
969 if (sps->chroma_format_idc != 0)
970 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
971 READ_UINT8 (nr, p->chroma_weight_l0_flag[i], 1);
972
973 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
974 if (p->luma_weight_l0_flag[i]) {
975 READ_SE_ALLOWED (nr, p->delta_luma_weight_l0[i], -128, 127);
976 READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
977 }
978 if (p->chroma_weight_l0_flag[i])
979 for (j = 0; j < 2; j++) {
980 READ_SE_ALLOWED (nr, p->delta_chroma_weight_l0[i][j], -128, 127);
981 READ_SE_ALLOWED (nr, p->delta_chroma_offset_l0[i][j], -512, 511);
982 }
983 }
984
985 if (GST_H265_IS_B_SLICE (slice)) {
986 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
987 READ_UINT8 (nr, p->luma_weight_l1_flag[i], 1);
988 if (sps->chroma_format_idc != 0)
989 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
990 READ_UINT8 (nr, p->chroma_weight_l1_flag[i], 1);
991
992 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
993 if (p->luma_weight_l1_flag[i]) {
994 READ_SE_ALLOWED (nr, p->delta_luma_weight_l1[i], -128, 127);
995 READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
996 }
997 if (p->chroma_weight_l1_flag[i])
998 for (j = 0; j < 2; j++) {
999 READ_SE_ALLOWED (nr, p->delta_chroma_weight_l1[i][j], -128, 127);
1000 READ_SE_ALLOWED (nr, p->delta_chroma_offset_l1[i][j], -512, 511);
1001 }
1002 }
1003 }
1004
1005 return TRUE;
1006
1007 error:
1008 GST_WARNING ("error parsing \"Prediction weight table\"");
1009 return FALSE;
1010 }
1011
1012 static GstH265ParserResult
gst_h265_parser_parse_buffering_period(GstH265Parser * parser,GstH265BufferingPeriod * per,NalReader * nr)1013 gst_h265_parser_parse_buffering_period (GstH265Parser * parser,
1014 GstH265BufferingPeriod * per, NalReader * nr)
1015 {
1016 GstH265SPS *sps;
1017 guint8 sps_id;
1018 guint i;
1019 guint n;
1020
1021 GST_DEBUG ("parsing \"Buffering period\"");
1022
1023 READ_UE_MAX (nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
1024 sps = gst_h265_parser_get_sps (parser, sps_id);
1025 if (!sps) {
1026 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
1027 sps_id);
1028 return GST_H265_PARSER_BROKEN_LINK;
1029 }
1030 per->sps = sps;
1031
1032 if (sps->vui_parameters_present_flag) {
1033 GstH265VUIParams *vui = &sps->vui_params;
1034 GstH265HRDParams *hrd = &vui->hrd_params;
1035
1036 if (!hrd->sub_pic_hrd_params_present_flag)
1037 READ_UINT8 (nr, per->irap_cpb_params_present_flag, 1);
1038
1039 if (per->irap_cpb_params_present_flag) {
1040 READ_UINT8 (nr, per->cpb_delay_offset,
1041 (hrd->au_cpb_removal_delay_length_minus1 + 1));
1042 READ_UINT8 (nr, per->dpb_delay_offset,
1043 (hrd->dpb_output_delay_length_minus1 + 1));
1044 }
1045
1046 n = hrd->initial_cpb_removal_delay_length_minus1 + 1;
1047
1048 READ_UINT8 (nr, per->concatenation_flag, 1);
1049 READ_UINT8 (nr, per->au_cpb_removal_delay_delta_minus1,
1050 (hrd->au_cpb_removal_delay_length_minus1 + 1));
1051
1052 if (hrd->nal_hrd_parameters_present_flag) {
1053 for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
1054 READ_UINT8 (nr, per->nal_initial_cpb_removal_delay[i], n);
1055 READ_UINT8 (nr, per->nal_initial_cpb_removal_offset[i], n);
1056 if (hrd->sub_pic_hrd_params_present_flag
1057 || per->irap_cpb_params_present_flag) {
1058 READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_delay[i], n);
1059 READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_offset[i], n);
1060 }
1061 }
1062 }
1063
1064 if (hrd->vcl_hrd_parameters_present_flag) {
1065 for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
1066 READ_UINT8 (nr, per->vcl_initial_cpb_removal_delay[i], n);
1067 READ_UINT8 (nr, per->vcl_initial_cpb_removal_offset[i], n);
1068 if (hrd->sub_pic_hrd_params_present_flag
1069 || per->irap_cpb_params_present_flag) {
1070 READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_delay[i], n);
1071 READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_offset[i], n);
1072 }
1073 }
1074 }
1075
1076 }
1077 return GST_H265_PARSER_OK;
1078
1079 error:
1080 GST_WARNING ("error parsing \"Buffering period\"");
1081 return GST_H265_PARSER_ERROR;
1082 }
1083
1084 static GstH265ParserResult
gst_h265_parser_parse_pic_timing(GstH265Parser * parser,GstH265PicTiming * tim,NalReader * nr)1085 gst_h265_parser_parse_pic_timing (GstH265Parser * parser,
1086 GstH265PicTiming * tim, NalReader * nr)
1087 {
1088 GstH265ProfileTierLevel *profile_tier_level;
1089 guint i;
1090
1091 GST_DEBUG ("parsing \"Picture timing\"");
1092 if (!parser->last_sps || !parser->last_sps->valid) {
1093 GST_WARNING ("didn't get the associated sequence parameter set for the "
1094 "current access unit");
1095 goto error;
1096 }
1097
1098 profile_tier_level = &parser->last_sps->profile_tier_level;
1099
1100 /* set default values */
1101 if (!profile_tier_level->progressive_source_flag
1102 && profile_tier_level->interlaced_source_flag)
1103 tim->source_scan_type = 0;
1104 else if (profile_tier_level->progressive_source_flag
1105 && !profile_tier_level->interlaced_source_flag)
1106 tim->source_scan_type = 1;
1107 else
1108 tim->source_scan_type = 2;
1109
1110 if (parser->last_sps->vui_parameters_present_flag) {
1111 GstH265VUIParams *vui = &parser->last_sps->vui_params;
1112
1113 if (vui->frame_field_info_present_flag) {
1114 READ_UINT8 (nr, tim->pic_struct, 4);
1115 READ_UINT8 (nr, tim->source_scan_type, 2);
1116 READ_UINT8 (nr, tim->duplicate_flag, 1);
1117 } else {
1118 /* set default values */
1119 tim->pic_struct = 0;
1120 }
1121
1122 if (vui->hrd_parameters_present_flag) {
1123 GstH265HRDParams *hrd = &vui->hrd_params;
1124
1125 READ_UINT8 (nr, tim->au_cpb_removal_delay_minus1,
1126 (hrd->au_cpb_removal_delay_length_minus1 + 1));
1127 READ_UINT8 (nr, tim->pic_dpb_output_delay,
1128 (hrd->dpb_output_delay_length_minus1 + 1));
1129
1130 if (hrd->sub_pic_hrd_params_present_flag)
1131 READ_UINT8 (nr, tim->pic_dpb_output_du_delay,
1132 (hrd->dpb_output_delay_du_length_minus1 + 1));
1133
1134 if (hrd->sub_pic_hrd_params_present_flag
1135 && hrd->sub_pic_cpb_params_in_pic_timing_sei_flag) {
1136 READ_UE (nr, tim->num_decoding_units_minus1);
1137
1138 READ_UINT8 (nr, tim->du_common_cpb_removal_delay_flag, 1);
1139 if (tim->du_common_cpb_removal_delay_flag)
1140 READ_UINT8 (nr, tim->du_common_cpb_removal_delay_increment_minus1,
1141 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1142
1143 tim->num_nalus_in_du_minus1 =
1144 g_new0 (guint32, (tim->num_decoding_units_minus1 + 1));
1145 tim->du_cpb_removal_delay_increment_minus1 =
1146 g_new0 (guint8, (tim->num_decoding_units_minus1 + 1));
1147
1148 for (i = 0; i <= tim->num_decoding_units_minus1; i++) {
1149 READ_UE (nr, tim->num_nalus_in_du_minus1[i]);
1150
1151 if (!tim->du_common_cpb_removal_delay_flag
1152 && (i < tim->num_decoding_units_minus1))
1153 READ_UINT8 (nr, tim->du_cpb_removal_delay_increment_minus1[i],
1154 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1155 }
1156 }
1157 }
1158 }
1159 return GST_H265_PARSER_OK;
1160
1161 error:
1162 GST_WARNING ("error parsing \"Picture timing\"");
1163 return GST_H265_PARSER_ERROR;
1164 }
1165
1166 static GstH265ParserResult
gst_h265_parser_parse_recovery_point(GstH265Parser * parser,GstH265RecoveryPoint * rp,NalReader * nr)1167 gst_h265_parser_parse_recovery_point (GstH265Parser * parser,
1168 GstH265RecoveryPoint * rp, NalReader * nr)
1169 {
1170 GstH265SPS *const sps = parser->last_sps;
1171 gint32 max_pic_order_cnt_lsb;
1172
1173 GST_DEBUG ("parsing \"Recovery point\"");
1174 if (!sps || !sps->valid) {
1175 GST_WARNING ("didn't get the associated sequence parameter set for the "
1176 "current access unit");
1177 goto error;
1178 }
1179
1180 max_pic_order_cnt_lsb = pow (2, (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
1181 READ_SE_ALLOWED (nr, rp->recovery_poc_cnt, -max_pic_order_cnt_lsb / 2,
1182 max_pic_order_cnt_lsb - 1);
1183 READ_UINT8 (nr, rp->exact_match_flag, 1);
1184 READ_UINT8 (nr, rp->broken_link_flag, 1);
1185
1186 return GST_H265_PARSER_OK;
1187
1188 error:
1189 GST_WARNING ("error parsing \"Recovery point\"");
1190 return GST_H265_PARSER_ERROR;
1191 }
1192
1193
1194 static GstH265ParserResult
gst_h265_parser_parse_registered_user_data(GstH265Parser * parser,GstH265RegisteredUserData * rud,NalReader * nr,guint payload_size)1195 gst_h265_parser_parse_registered_user_data (GstH265Parser * parser,
1196 GstH265RegisteredUserData * rud, NalReader * nr, guint payload_size)
1197 {
1198 guint8 *data = NULL;
1199 guint i;
1200
1201 rud->data = NULL;
1202 rud->size = 0;
1203
1204 if (payload_size < 2) {
1205 GST_WARNING ("Too small payload size %d", payload_size);
1206 return GST_H265_PARSER_BROKEN_DATA;
1207 }
1208
1209 READ_UINT8 (nr, rud->country_code, 8);
1210 --payload_size;
1211
1212 if (rud->country_code == 0xFF) {
1213 READ_UINT8 (nr, rud->country_code_extension, 8);
1214 --payload_size;
1215 } else {
1216 rud->country_code_extension = 0;
1217 }
1218
1219 if (payload_size < 1) {
1220 GST_WARNING ("No more remaining payload data to store");
1221 return GST_H265_PARSER_BROKEN_DATA;
1222 }
1223
1224 data = g_malloc (payload_size);
1225 for (i = 0; i < payload_size; ++i) {
1226 READ_UINT8 (nr, data[i], 8);
1227 }
1228
1229 GST_MEMDUMP ("SEI user data", data, payload_size);
1230
1231 rud->data = data;
1232 rud->size = payload_size;
1233 return GST_H265_PARSER_OK;
1234
1235 error:
1236 {
1237 GST_WARNING ("error parsing \"Registered User Data\"");
1238 g_free (data);
1239 return GST_H265_PARSER_ERROR;
1240 }
1241 }
1242
1243
1244 static GstH265ParserResult
gst_h265_parser_parse_time_code(GstH265Parser * parser,GstH265TimeCode * tc,NalReader * nr)1245 gst_h265_parser_parse_time_code (GstH265Parser * parser,
1246 GstH265TimeCode * tc, NalReader * nr)
1247 {
1248 guint i;
1249
1250 GST_DEBUG ("parsing \"Time code\"");
1251
1252 READ_UINT8 (nr, tc->num_clock_ts, 2);
1253
1254 for (i = 0; i < tc->num_clock_ts; i++) {
1255 READ_UINT8 (nr, tc->clock_timestamp_flag[i], 1);
1256 if (tc->clock_timestamp_flag[i]) {
1257 READ_UINT8 (nr, tc->units_field_based_flag[i], 1);
1258 READ_UINT8 (nr, tc->counting_type[i], 5);
1259 READ_UINT8 (nr, tc->full_timestamp_flag[i], 1);
1260 READ_UINT8 (nr, tc->discontinuity_flag[i], 1);
1261 READ_UINT8 (nr, tc->cnt_dropped_flag[i], 1);
1262 READ_UINT16 (nr, tc->n_frames[i], 9);
1263
1264 if (tc->full_timestamp_flag[i]) {
1265 tc->seconds_flag[i] = TRUE;
1266 READ_UINT8 (nr, tc->seconds_value[i], 6);
1267
1268 tc->minutes_flag[i] = TRUE;
1269 READ_UINT8 (nr, tc->minutes_value[i], 6);
1270
1271 tc->hours_flag[i] = TRUE;
1272 READ_UINT8 (nr, tc->hours_value[i], 5);
1273 } else {
1274 READ_UINT8 (nr, tc->seconds_flag[i], 1);
1275 if (tc->seconds_flag[i]) {
1276 READ_UINT8 (nr, tc->seconds_value[i], 6);
1277 READ_UINT8 (nr, tc->minutes_flag[i], 1);
1278 if (tc->minutes_flag[i]) {
1279 READ_UINT8 (nr, tc->minutes_value[i], 6);
1280 READ_UINT8 (nr, tc->hours_flag[i], 1);
1281 if (tc->hours_flag[i]) {
1282 READ_UINT8 (nr, tc->hours_value[i], 5);
1283 }
1284 }
1285 }
1286 }
1287 }
1288
1289 READ_UINT8 (nr, tc->time_offset_length[i], 5);
1290
1291 if (tc->time_offset_length[i] > 0)
1292 READ_UINT32 (nr, tc->time_offset_value[i], tc->time_offset_length[i]);
1293 }
1294
1295 return GST_H265_PARSER_OK;
1296
1297 error:
1298 GST_WARNING ("error parsing \"Time code\"");
1299 return GST_H265_PARSER_ERROR;
1300 }
1301
1302 static GstH265ParserResult
gst_h265_parser_parse_mastering_display_colour_volume(GstH265Parser * parser,GstH265MasteringDisplayColourVolume * mdcv,NalReader * nr)1303 gst_h265_parser_parse_mastering_display_colour_volume (GstH265Parser * parser,
1304 GstH265MasteringDisplayColourVolume * mdcv, NalReader * nr)
1305 {
1306 guint i;
1307
1308 GST_DEBUG ("parsing \"Mastering display colour volume\"");
1309
1310 for (i = 0; i < 3; i++) {
1311 READ_UINT16 (nr, mdcv->display_primaries_x[i], 16);
1312 READ_UINT16 (nr, mdcv->display_primaries_y[i], 16);
1313 }
1314
1315 READ_UINT16 (nr, mdcv->white_point_x, 16);
1316 READ_UINT16 (nr, mdcv->white_point_y, 16);
1317 READ_UINT32 (nr, mdcv->max_display_mastering_luminance, 32);
1318 READ_UINT32 (nr, mdcv->min_display_mastering_luminance, 32);
1319
1320 return GST_H265_PARSER_OK;
1321
1322 error:
1323 GST_WARNING ("error parsing \"Mastering display colour volume\"");
1324 return GST_H265_PARSER_ERROR;
1325 }
1326
1327 static GstH265ParserResult
gst_h265_parser_parse_content_light_level_info(GstH265Parser * parser,GstH265ContentLightLevel * cll,NalReader * nr)1328 gst_h265_parser_parse_content_light_level_info (GstH265Parser * parser,
1329 GstH265ContentLightLevel * cll, NalReader * nr)
1330 {
1331 GST_DEBUG ("parsing \"Content light level\"");
1332
1333 READ_UINT16 (nr, cll->max_content_light_level, 16);
1334 READ_UINT16 (nr, cll->max_pic_average_light_level, 16);
1335
1336 return GST_H265_PARSER_OK;
1337
1338 error:
1339 GST_WARNING ("error parsing \"Content light level\"");
1340 return GST_H265_PARSER_ERROR;
1341 }
1342
1343 /******** API *************/
1344
1345 /**
1346 * gst_h265_parser_new:
1347 *
1348 * Creates a new #GstH265Parser. It should be freed with
1349 * gst_h265_parser_free after use.
1350 *
1351 * Returns: a new #GstH265Parser
1352 */
1353 GstH265Parser *
gst_h265_parser_new(void)1354 gst_h265_parser_new (void)
1355 {
1356 GstH265Parser *parser;
1357
1358 parser = g_slice_new0 (GstH265Parser);
1359
1360 return parser;
1361 }
1362
1363 /**
1364 * gst_h265_parser_free:
1365 * @parser: the #GstH265Parser to free
1366 *
1367 * Frees @parser and sets it to %NULL
1368 */
1369 void
gst_h265_parser_free(GstH265Parser * parser)1370 gst_h265_parser_free (GstH265Parser * parser)
1371 {
1372 g_slice_free (GstH265Parser, parser);
1373 parser = NULL;
1374 }
1375
1376 /**
1377 * gst_h265_parser_identify_nalu_unchecked:
1378 * @parser: a #GstH265Parser
1379 * @data: The data to parse
1380 * @offset: the offset from which to parse @data
1381 * @size: the size of @data
1382 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1383 *
1384 * Parses @data and fills @nalu from the next nalu data from @data.
1385 *
1386 * This differs from @gst_h265_parser_identify_nalu in that it doesn't
1387 * check whether the packet is complete or not.
1388 *
1389 * Note: Only use this function if you already know the provided @data
1390 * is a complete NALU, else use @gst_h265_parser_identify_nalu.
1391 *
1392 * Returns: a #GstH265ParserResult
1393 */
1394 GstH265ParserResult
gst_h265_parser_identify_nalu_unchecked(GstH265Parser * parser,const guint8 * data,guint offset,gsize size,GstH265NalUnit * nalu)1395 gst_h265_parser_identify_nalu_unchecked (GstH265Parser * parser,
1396 const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1397 {
1398 gint off1;
1399
1400 memset (nalu, 0, sizeof (*nalu));
1401
1402 if (size < offset + 4) {
1403 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1404 ", offset %u", size, offset);
1405 return GST_H265_PARSER_ERROR;
1406 }
1407
1408 off1 = scan_for_start_codes (data + offset, size - offset);
1409
1410 if (off1 < 0) {
1411 GST_DEBUG ("No start code prefix in this buffer");
1412 return GST_H265_PARSER_NO_NAL;
1413 }
1414
1415 nalu->sc_offset = offset + off1;
1416
1417 /* The scanner ensures one byte passed the start code but to
1418 * identify an HEVC NAL, we need 2. */
1419 if (size - nalu->sc_offset - 3 < 2) {
1420 GST_DEBUG ("Not enough bytes after start code to identify");
1421 return GST_H265_PARSER_NO_NAL;
1422 }
1423
1424 /* sc might have 2 or 3 0-bytes */
1425 if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
1426 nalu->sc_offset--;
1427
1428 nalu->offset = offset + off1 + 3;
1429 nalu->data = (guint8 *) data;
1430 nalu->size = size - nalu->offset;
1431
1432 if (!gst_h265_parse_nalu_header (nalu)) {
1433 GST_WARNING ("error parsing \"NAL unit header\"");
1434 nalu->size = 0;
1435 return GST_H265_PARSER_BROKEN_DATA;
1436 }
1437
1438 nalu->valid = TRUE;
1439
1440 if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB) {
1441 GST_DEBUG ("end-of-seq or end-of-stream nal found");
1442 nalu->size = 2;
1443 return GST_H265_PARSER_OK;
1444 }
1445
1446 return GST_H265_PARSER_OK;
1447 }
1448
1449 /**
1450 * gst_h265_parser_identify_nalu:
1451 * @parser: a #GstH265Parser
1452 * @data: The data to parse
1453 * @offset: the offset from which to parse @data
1454 * @size: the size of @data
1455 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1456 *
1457 * Parses @data and fills @nalu from the next nalu data from @data
1458 *
1459 * Returns: a #GstH265ParserResult
1460 */
1461 GstH265ParserResult
gst_h265_parser_identify_nalu(GstH265Parser * parser,const guint8 * data,guint offset,gsize size,GstH265NalUnit * nalu)1462 gst_h265_parser_identify_nalu (GstH265Parser * parser,
1463 const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1464 {
1465 GstH265ParserResult res;
1466 gint off2;
1467
1468 res =
1469 gst_h265_parser_identify_nalu_unchecked (parser, data, offset, size,
1470 nalu);
1471
1472 if (res != GST_H265_PARSER_OK)
1473 goto beach;
1474
1475 /* The two NALs are exactly 2 bytes size and are placed at the end of an AU,
1476 * there is no need to wait for the following */
1477 if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB)
1478 goto beach;
1479
1480 off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1481 if (off2 < 0) {
1482 GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1483
1484 return GST_H265_PARSER_NO_NAL_END;
1485 }
1486
1487 /* Callers assumes that enough data will available to identify the next NAL,
1488 * but scan_for_start_codes() only ensure 1 extra byte is available. Ensure
1489 * we have the required two header bytes (3 bytes start code and 2 byte
1490 * header). */
1491 if (size - (nalu->offset + off2) < 5) {
1492 GST_DEBUG ("Not enough bytes identify the next NAL.");
1493 return GST_H265_PARSER_NO_NAL_END;
1494 }
1495
1496 /* Mini performance improvement:
1497 * We could have a way to store how many 0s were skipped to avoid
1498 * parsing them again on the next NAL */
1499 while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1500 off2--;
1501
1502 nalu->size = off2;
1503 if (nalu->size < 3)
1504 return GST_H265_PARSER_BROKEN_DATA;
1505
1506 GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1507
1508 beach:
1509 return res;
1510 }
1511
1512 /**
1513 * gst_h265_parser_identify_nalu_hevc:
1514 * @parser: a #GstH265Parser
1515 * @data: The data to parse, must be the beging of the Nal unit
1516 * @offset: the offset from which to parse @data
1517 * @size: the size of @data
1518 * @nal_length_size: the size in bytes of the HEVC nal length prefix.
1519 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1520 *
1521 * Parses @data and sets @nalu.
1522 *
1523 * Returns: a #GstH265ParserResult
1524 */
1525 GstH265ParserResult
gst_h265_parser_identify_nalu_hevc(GstH265Parser * parser,const guint8 * data,guint offset,gsize size,guint8 nal_length_size,GstH265NalUnit * nalu)1526 gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
1527 const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1528 GstH265NalUnit * nalu)
1529 {
1530 GstBitReader br;
1531
1532 memset (nalu, 0, sizeof (*nalu));
1533
1534 /* Would overflow guint below otherwise: the callers needs to ensure that
1535 * this never happens */
1536 if (offset > G_MAXUINT32 - nal_length_size) {
1537 GST_WARNING ("offset + nal_length_size overflow");
1538 nalu->size = 0;
1539 return GST_H265_PARSER_BROKEN_DATA;
1540 }
1541
1542 if (size < offset + nal_length_size) {
1543 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1544 ", offset %u", size, offset);
1545 return GST_H265_PARSER_ERROR;
1546 }
1547
1548 size = size - offset;
1549 gst_bit_reader_init (&br, data + offset, size);
1550
1551 nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1552 nal_length_size * 8);
1553 nalu->sc_offset = offset;
1554 nalu->offset = offset + nal_length_size;
1555
1556 if (nalu->size > G_MAXUINT32 - nal_length_size) {
1557 GST_WARNING ("NALU size + nal_length_size overflow");
1558 nalu->size = 0;
1559 return GST_H265_PARSER_BROKEN_DATA;
1560 }
1561
1562 if (size < (gsize) nalu->size + nal_length_size) {
1563 nalu->size = 0;
1564
1565 return GST_H265_PARSER_NO_NAL_END;
1566 }
1567
1568 nalu->data = (guint8 *) data;
1569
1570 if (!gst_h265_parse_nalu_header (nalu)) {
1571 GST_WARNING ("error parsing \"NAL unit header\"");
1572 nalu->size = 0;
1573 return GST_H265_PARSER_BROKEN_DATA;
1574 }
1575
1576 if (nalu->size < 2)
1577 return GST_H265_PARSER_BROKEN_DATA;
1578
1579 nalu->valid = TRUE;
1580
1581 return GST_H265_PARSER_OK;
1582 }
1583
1584 /**
1585 * gst_h265_parser_parse_nal:
1586 * @parser: a #GstH265Parser
1587 * @nalu: The #GstH265NalUnit to parse
1588 *
1589 * This function should be called in the case one doesn't need to
1590 * parse a specific structure. It is necessary to do so to make
1591 * sure @parser is up to date.
1592 *
1593 * Returns: a #GstH265ParserResult
1594 */
1595 GstH265ParserResult
gst_h265_parser_parse_nal(GstH265Parser * parser,GstH265NalUnit * nalu)1596 gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
1597 {
1598 GstH265VPS vps;
1599 GstH265SPS sps;
1600 GstH265PPS pps;
1601
1602 switch (nalu->type) {
1603 case GST_H265_NAL_VPS:
1604 return gst_h265_parser_parse_vps (parser, nalu, &vps);
1605 break;
1606 case GST_H265_NAL_SPS:
1607 return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
1608 break;
1609 case GST_H265_NAL_PPS:
1610 return gst_h265_parser_parse_pps (parser, nalu, &pps);
1611 }
1612
1613 return GST_H265_PARSER_OK;
1614 }
1615
1616 /**
1617 * gst_h265_parser_parse_vps:
1618 * @parser: a #GstH265Parser
1619 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1620 * @vps: The #GstH265VPS to fill.
1621 *
1622 * Parses @data, and fills the @vps structure.
1623 *
1624 * Returns: a #GstH265ParserResult
1625 */
1626 GstH265ParserResult
gst_h265_parser_parse_vps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265VPS * vps)1627 gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
1628 GstH265VPS * vps)
1629 {
1630 GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);
1631
1632 if (res == GST_H265_PARSER_OK) {
1633 GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);
1634
1635 parser->vps[vps->id] = *vps;
1636 parser->last_vps = &parser->vps[vps->id];
1637 }
1638
1639 return res;
1640 }
1641
1642 /**
1643 * gst_h265_parse_vps:
1644 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1645 * @sps: The #GstH265VPS to fill.
1646 *
1647 * Parses @data, and fills the @vps structure.
1648 *
1649 * Returns: a #GstH265ParserResult
1650 */
1651 GstH265ParserResult
gst_h265_parse_vps(GstH265NalUnit * nalu,GstH265VPS * vps)1652 gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
1653 {
1654 NalReader nr;
1655 guint i, j;
1656
1657 GST_DEBUG ("parsing VPS");
1658
1659 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1660 nalu->size - nalu->header_bytes);
1661
1662 memset (vps, 0, sizeof (*vps));
1663
1664 vps->cprms_present_flag = 1;
1665
1666 READ_UINT8 (&nr, vps->id, 4);
1667
1668 READ_UINT8 (&nr, vps->base_layer_internal_flag, 1);
1669 READ_UINT8 (&nr, vps->base_layer_available_flag, 1);
1670
1671 READ_UINT8 (&nr, vps->max_layers_minus1, 6);
1672 READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
1673 CHECK_ALLOWED (vps->max_sub_layers_minus1, 0, 6);
1674 READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1675
1676 /* skip reserved_0xffff_16bits */
1677 if (!nal_reader_skip (&nr, 16))
1678 goto error;
1679
1680 if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1681 vps->max_sub_layers_minus1))
1682 goto error;
1683
1684 READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1685
1686 for (i =
1687 (vps->sub_layer_ordering_info_present_flag ? 0 :
1688 vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1689 READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1690 READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1691 vps->max_dec_pic_buffering_minus1[i]);
1692 READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1693 }
1694 /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1695 if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1696 for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1697 vps->max_dec_pic_buffering_minus1[i] =
1698 vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1699 vps->max_num_reorder_pics[i] =
1700 vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1701 vps->max_latency_increase_plus1[i] =
1702 vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1703 }
1704 }
1705
1706 READ_UINT8 (&nr, vps->max_layer_id, 6);
1707 /* shall allow 63 */
1708 CHECK_ALLOWED_MAX (vps->max_layer_id, 63);
1709
1710 READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1711 /* allowed range is 0 to 1023 */
1712 CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 1023);
1713
1714 for (i = 1; i <= vps->num_layer_sets_minus1; i++) {
1715 for (j = 0; j <= vps->max_layer_id; j++) {
1716 /* layer_id_included_flag[i][j] */
1717 /* FIXME: need to parse this when we can support parsing multi-layer info. */
1718 nal_reader_skip (&nr, 1);
1719 }
1720 }
1721
1722 READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1723
1724 if (vps->timing_info_present_flag) {
1725 READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1726 READ_UINT32 (&nr, vps->time_scale, 32);
1727 READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1728
1729 if (vps->poc_proportional_to_timing_flag)
1730 READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1731
1732 READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1733 /* allowed range is
1734 * 0 to vps_num_layer_sets_minus1 + 1 */
1735 CHECK_ALLOWED_MAX (vps->num_hrd_parameters, vps->num_layer_sets_minus1 + 1);
1736
1737 if (vps->num_hrd_parameters) {
1738 READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1739 /* allowed range is
1740 * ( vps_base_layer_internal_flag ? 0 : 1 ) to vps_num_layer_sets_minus1
1741 */
1742 CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, vps->num_layer_sets_minus1);
1743
1744 if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1745 vps->cprms_present_flag, vps->max_sub_layers_minus1))
1746 goto error;
1747 }
1748
1749 /* FIXME: VPS can have multiple hrd parameters, and therefore hrd_params
1750 * should be an array (like Garray). But it also requires new _clear()
1751 * method for free the array in GstH265VPS whenever gst_h265_parse_vps()
1752 * is called. Need to work for multi-layer related parsing supporting
1753 *
1754 * FIXME: Following code is just work around to find correct
1755 * vps_extension position */
1756
1757 /* skip the first parsed one above */
1758 for (i = 1; i < vps->num_hrd_parameters; i++) {
1759 guint16 hrd_layer_set_idx;
1760 guint8 cprms_present_flag;
1761 GstH265HRDParams hrd_params;
1762
1763 READ_UE_MAX (&nr, hrd_layer_set_idx, 1023);
1764 CHECK_ALLOWED_MAX (hrd_layer_set_idx, vps->num_layer_sets_minus1);
1765
1766 /* need parsing if (i > 1) */
1767 READ_UINT8 (&nr, cprms_present_flag, 1);
1768
1769 if (!gst_h265_parse_hrd_parameters (&hrd_params, &nr,
1770 cprms_present_flag, vps->max_sub_layers_minus1))
1771 goto error;
1772 }
1773 }
1774 READ_UINT8 (&nr, vps->vps_extension, 1);
1775 vps->valid = TRUE;
1776
1777 return GST_H265_PARSER_OK;
1778
1779 error:
1780 GST_WARNING ("error parsing \"Video parameter set\"");
1781 vps->valid = FALSE;
1782 return GST_H265_PARSER_ERROR;
1783 }
1784
1785 /**
1786 * gst_h265_parser_parse_sps:
1787 * @parser: a #GstH265Parser
1788 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1789 * @sps: The #GstH265SPS to fill.
1790 * @parse_vui_params: Whether to parse the vui_params or not
1791 *
1792 * Parses @data, and fills the @sps structure.
1793 *
1794 * Returns: a #GstH265ParserResult
1795 */
1796 GstH265ParserResult
gst_h265_parser_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1797 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1798 GstH265SPS * sps, gboolean parse_vui_params)
1799 {
1800 GstH265ParserResult res =
1801 gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1802
1803 if (res == GST_H265_PARSER_OK) {
1804 GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1805
1806 parser->sps[sps->id] = *sps;
1807 parser->last_sps = &parser->sps[sps->id];
1808 }
1809
1810 return res;
1811 }
1812
1813 /**
1814 * gst_h265_parse_sps:
1815 * parser: The #GstH265Parser
1816 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1817 * @sps: The #GstH265SPS to fill.
1818 * @parse_vui_params: Whether to parse the vui_params or not
1819 *
1820 * Parses @data, and fills the @sps structure.
1821 *
1822 * Returns: a #GstH265ParserResult
1823 */
1824 GstH265ParserResult
gst_h265_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1825 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1826 GstH265SPS * sps, gboolean parse_vui_params)
1827 {
1828 NalReader nr;
1829 GstH265VPS *vps;
1830 guint8 vps_id;
1831 guint i;
1832 guint subwc[] = { 1, 2, 2, 1, 1 };
1833 guint subhc[] = { 1, 2, 1, 1, 1 };
1834 GstH265VUIParams *vui = NULL;
1835
1836 GST_DEBUG ("parsing SPS");
1837
1838 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1839 nalu->size - nalu->header_bytes);
1840
1841 memset (sps, 0, sizeof (*sps));
1842
1843 READ_UINT8 (&nr, vps_id, 4);
1844 vps = gst_h265_parser_get_vps (parser, vps_id);
1845 if (!vps) {
1846 GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1847 vps_id);
1848 }
1849 sps->vps = vps;
1850
1851 READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1852 CHECK_ALLOWED (sps->max_sub_layers_minus1, 0, 6);
1853 READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1854
1855 if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1856 sps->max_sub_layers_minus1))
1857 goto error;
1858
1859 READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1860
1861 READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1862 if (sps->chroma_format_idc == 3)
1863 READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1864
1865 READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1866 READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1867
1868 READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1869 if (sps->conformance_window_flag) {
1870 READ_UE (&nr, sps->conf_win_left_offset);
1871 READ_UE (&nr, sps->conf_win_right_offset);
1872 READ_UE (&nr, sps->conf_win_top_offset);
1873 READ_UE (&nr, sps->conf_win_bottom_offset);
1874 }
1875
1876 READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1877 READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1878 READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1879
1880 READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1881 for (i =
1882 (sps->sub_layer_ordering_info_present_flag ? 0 :
1883 sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1884 READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1885 READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1886 sps->max_dec_pic_buffering_minus1[i]);
1887 READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1888 }
1889 /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1890 if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1891 for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1892 sps->max_dec_pic_buffering_minus1[i] =
1893 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1894 sps->max_num_reorder_pics[i] =
1895 sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1896 sps->max_latency_increase_plus1[i] =
1897 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1898 }
1899 }
1900
1901 /* The limits are calculted based on the profile_tier_level constraint
1902 * in Annex-A: CtbLog2SizeY = 4 to 6 */
1903 READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1904 READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1905 READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1906 READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1907 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1908 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1909
1910 READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1911 if (sps->scaling_list_enabled_flag) {
1912 READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1913
1914 if (sps->scaling_list_data_present_flag)
1915 if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1916 goto error;
1917 }
1918
1919 READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1920 READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1921 READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1922
1923 if (sps->pcm_enabled_flag) {
1924 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1925 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1926 READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1927 READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1928 READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1929 }
1930
1931 READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1932 for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1933 if (!gst_h265_parser_parse_short_term_ref_pic_sets
1934 (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1935 goto error;
1936
1937 READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1938 if (sps->long_term_ref_pics_present_flag) {
1939 READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1940 for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1941 READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1942 sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1943 READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1944 }
1945 }
1946
1947 READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1948 READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1949 READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1950
1951 if (sps->vui_parameters_present_flag && parse_vui_params) {
1952 if (!gst_h265_parse_vui_parameters (sps, &nr))
1953 goto error;
1954 vui = &sps->vui_params;
1955 }
1956
1957 READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1958
1959 if (sps->sps_extension_flag) {
1960 READ_UINT8 (&nr, sps->sps_range_extension_flag, 1);
1961 READ_UINT8 (&nr, sps->sps_multilayer_extension_flag, 1);
1962 READ_UINT8 (&nr, sps->sps_3d_extension_flag, 1);
1963 READ_UINT8 (&nr, sps->sps_scc_extension_flag, 1);
1964 READ_UINT8 (&nr, sps->sps_extension_4bits, 4);
1965 }
1966
1967 if (sps->sps_range_extension_flag) {
1968 READ_UINT8 (&nr,
1969 sps->sps_extnsion_params.transform_skip_rotation_enabled_flag, 1);
1970 READ_UINT8 (&nr,
1971 sps->sps_extnsion_params.transform_skip_context_enabled_flag, 1);
1972 READ_UINT8 (&nr, sps->sps_extnsion_params.implicit_rdpcm_enabled_flag, 1);
1973 READ_UINT8 (&nr, sps->sps_extnsion_params.explicit_rdpcm_enabled_flag, 1);
1974 READ_UINT8 (&nr,
1975 sps->sps_extnsion_params.extended_precision_processing_flag, 1);
1976 READ_UINT8 (&nr, sps->sps_extnsion_params.intra_smoothing_disabled_flag, 1);
1977 READ_UINT8 (&nr,
1978 sps->sps_extnsion_params.high_precision_offsets_enabled_flag, 1);
1979 READ_UINT8 (&nr,
1980 sps->sps_extnsion_params.persistent_rice_adaptation_enabled_flag, 1);
1981 READ_UINT8 (&nr,
1982 sps->sps_extnsion_params.cabac_bypass_alignment_enabled_flag, 1);
1983 }
1984
1985 if (sps->sps_multilayer_extension_flag) {
1986 GST_WARNING ("do not support multilayer extension, skip all"
1987 " remaining bits");
1988 goto done;
1989 }
1990 if (sps->sps_3d_extension_flag) {
1991 GST_WARNING ("do not support 3d extension, skip all remaining bits");
1992 goto done;
1993 }
1994
1995 if (sps->sps_scc_extension_flag) {
1996 READ_UINT8 (&nr,
1997 sps->sps_scc_extension_params.sps_curr_pic_ref_enabled_flag, 1);
1998 READ_UINT8 (&nr, sps->sps_scc_extension_params.palette_mode_enabled_flag,
1999 1);
2000 if (sps->sps_scc_extension_params.palette_mode_enabled_flag) {
2001 READ_UE_MAX (&nr, sps->sps_scc_extension_params.palette_max_size, 64);
2002 READ_UE_MAX (&nr,
2003 sps->sps_scc_extension_params.delta_palette_max_predictor_size,
2004 128 - sps->sps_scc_extension_params.palette_max_size);
2005
2006 READ_UINT8 (&nr,
2007 sps->sps_scc_extension_params.
2008 sps_palette_predictor_initializers_present_flag, 1);
2009 if (sps->sps_scc_extension_params.
2010 sps_palette_predictor_initializers_present_flag) {
2011 guint comp;
2012 READ_UE_MAX (&nr,
2013 sps->sps_scc_extension_params.
2014 sps_num_palette_predictor_initializer_minus1,
2015 sps->sps_scc_extension_params.palette_max_size +
2016 sps->sps_scc_extension_params.delta_palette_max_predictor_size - 1);
2017
2018 for (comp = 0; comp < (sps->chroma_format_idc == 0 ? 1 : 3); comp++) {
2019 guint num_bits;
2020 guint num =
2021 sps->sps_scc_extension_params.
2022 sps_num_palette_predictor_initializer_minus1 + 1;
2023
2024 num_bits = (comp == 0 ? sps->bit_depth_luma_minus8 + 8 :
2025 sps->bit_depth_chroma_minus8 + 8);
2026 for (i = 0; i < num; i++)
2027 READ_UINT32 (&nr,
2028 sps->sps_scc_extension_params.sps_palette_predictor_initializer
2029 [comp]
2030 [i], num_bits);
2031 }
2032 }
2033 }
2034
2035 READ_UINT8 (&nr,
2036 sps->sps_scc_extension_params.motion_vector_resolution_control_idc, 2);
2037 READ_UINT8 (&nr,
2038 sps->sps_scc_extension_params.intra_boundary_filtering_disabled_flag,
2039 1);
2040 }
2041
2042 done:
2043 /* calculate ChromaArrayType */
2044 if (!sps->separate_colour_plane_flag)
2045 sps->chroma_array_type = sps->chroma_format_idc;
2046
2047 /* Calculate width and height */
2048 sps->width = sps->pic_width_in_luma_samples;
2049 sps->height = sps->pic_height_in_luma_samples;
2050 if (sps->width < 0 || sps->height < 0) {
2051 GST_WARNING ("invalid width/height in SPS");
2052 goto error;
2053 }
2054
2055 if (sps->conformance_window_flag) {
2056 const guint crop_unit_x = subwc[sps->chroma_format_idc];
2057 const guint crop_unit_y = subhc[sps->chroma_format_idc];
2058
2059 sps->crop_rect_width = sps->width -
2060 (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
2061 sps->crop_rect_height = sps->height -
2062 (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
2063 sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
2064 sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
2065
2066 GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
2067 sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
2068 }
2069
2070 sps->fps_num = 0;
2071 sps->fps_den = 1;
2072
2073 if (vui && vui->timing_info_present_flag) {
2074 /* derive framerate for progressive stream if the pic_struct
2075 * syntax element is not present in picture timing SEI messages */
2076 /* Fixme: handle other cases also */
2077 if (parse_vui_params && vui->timing_info_present_flag
2078 && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
2079 sps->fps_num = vui->time_scale;
2080 sps->fps_den = vui->num_units_in_tick;
2081 GST_LOG ("framerate %d/%d in VUI", sps->fps_num, sps->fps_den);
2082 }
2083 } else if (vps && vps->timing_info_present_flag) {
2084 sps->fps_num = vps->time_scale;
2085 sps->fps_den = vps->num_units_in_tick;
2086 GST_LOG ("framerate %d/%d in VPS", sps->fps_num, sps->fps_den);
2087 } else {
2088 GST_LOG ("No VUI, unknown framerate");
2089 }
2090
2091 sps->valid = TRUE;
2092
2093 return GST_H265_PARSER_OK;
2094
2095 error:
2096 GST_WARNING ("error parsing \"Sequence parameter set\"");
2097 sps->valid = FALSE;
2098 return GST_H265_PARSER_ERROR;
2099 }
2100
2101 /**
2102 * gst_h265_parse_pps:
2103 * @parser: a #GstH265Parser
2104 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2105 * @pps: The #GstH265PPS to fill.
2106 *
2107 * Parses @data, and fills the @pps structure.
2108 *
2109 * Returns: a #GstH265ParserResult
2110 */
2111 GstH265ParserResult
gst_h265_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2112 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
2113 GstH265PPS * pps)
2114 {
2115 NalReader nr;
2116 GstH265SPS *sps;
2117 gint sps_id;
2118 gint qp_bd_offset;
2119 guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY, MaxBitDepthY, MaxBitDepthC;
2120 guint8 i;
2121
2122 GST_DEBUG ("parsing PPS");
2123
2124 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2125 nalu->size - nalu->header_bytes);
2126
2127 memset (pps, 0, sizeof (*pps));
2128
2129 READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
2130 READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
2131
2132 sps = gst_h265_parser_get_sps (parser, sps_id);
2133 if (!sps) {
2134 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
2135 sps_id);
2136 return GST_H265_PARSER_BROKEN_LINK;
2137 }
2138 pps->sps = sps;
2139 qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
2140
2141 MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
2142 CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
2143 CtbSizeY = 1 << CtbLog2SizeY;
2144 pps->PicHeightInCtbsY =
2145 ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
2146 pps->PicWidthInCtbsY =
2147 ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
2148
2149 /* set default values for fields that might not be present in the bitstream
2150 and have valid defaults */
2151 pps->uniform_spacing_flag = 1;
2152 pps->loop_filter_across_tiles_enabled_flag = 1;
2153
2154 READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
2155 READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
2156 READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
2157 READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
2158 READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
2159
2160 READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
2161 READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
2162 READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
2163
2164 READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
2165 READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
2166
2167 READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
2168 if (pps->cu_qp_delta_enabled_flag)
2169 READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
2170 sps->log2_diff_max_min_luma_coding_block_size);
2171
2172 READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
2173 READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
2174
2175 READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
2176 READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
2177 READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
2178 READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
2179 READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
2180 READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
2181
2182 if (pps->tiles_enabled_flag) {
2183 READ_UE_ALLOWED (&nr,
2184 pps->num_tile_columns_minus1, 0, pps->PicWidthInCtbsY - 1);
2185 READ_UE_ALLOWED (&nr,
2186 pps->num_tile_rows_minus1, 0, pps->PicHeightInCtbsY - 1);
2187
2188 if (pps->num_tile_columns_minus1 + 1 >
2189 G_N_ELEMENTS (pps->column_width_minus1)) {
2190 GST_WARNING ("Invalid \"num_tile_columns_minus1\" %d",
2191 pps->num_tile_columns_minus1);
2192 goto error;
2193 }
2194
2195 if (pps->num_tile_rows_minus1 + 1 > G_N_ELEMENTS (pps->row_height_minus1)) {
2196 GST_WARNING ("Invalid \"num_tile_rows_minus1\" %d",
2197 pps->num_tile_rows_minus1);
2198 goto error;
2199 }
2200
2201 READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
2202 /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
2203 if (pps->uniform_spacing_flag) {
2204 guint8 num_col = pps->num_tile_columns_minus1 + 1;
2205 guint8 num_row = pps->num_tile_rows_minus1 + 1;
2206 for (i = 0; i < num_col; i++) {
2207 pps->column_width_minus1[i] =
2208 ((i + 1) * pps->PicWidthInCtbsY / num_col
2209 - i * pps->PicWidthInCtbsY / num_col) - 1;
2210 }
2211 for (i = 0; i < num_row; i++) {
2212 pps->row_height_minus1[i] =
2213 ((i + 1) * pps->PicHeightInCtbsY / num_row
2214 - i * pps->PicHeightInCtbsY / num_row) - 1;
2215 }
2216 } else {
2217 pps->column_width_minus1[pps->num_tile_columns_minus1] =
2218 pps->PicWidthInCtbsY - 1;
2219 for (i = 0; i < pps->num_tile_columns_minus1; i++) {
2220 READ_UE (&nr, pps->column_width_minus1[i]);
2221 pps->column_width_minus1[pps->num_tile_columns_minus1] -=
2222 (pps->column_width_minus1[i] + 1);
2223 }
2224
2225 pps->row_height_minus1[pps->num_tile_rows_minus1] =
2226 pps->PicHeightInCtbsY - 1;
2227 for (i = 0; i < pps->num_tile_rows_minus1; i++) {
2228 READ_UE (&nr, pps->row_height_minus1[i]);
2229 pps->row_height_minus1[pps->num_tile_rows_minus1] -=
2230 (pps->row_height_minus1[i] + 1);
2231 }
2232 }
2233 READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
2234 }
2235
2236 READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
2237
2238 READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
2239 if (pps->deblocking_filter_control_present_flag) {
2240 READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
2241
2242 READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
2243 if (!pps->deblocking_filter_disabled_flag) {
2244 READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
2245 READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
2246 }
2247 }
2248
2249 READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
2250 if (pps->scaling_list_data_present_flag)
2251 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
2252 goto error;
2253 if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
2254 && !pps->scaling_list_data_present_flag)
2255 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
2256 goto error;
2257
2258 READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
2259 READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
2260 READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
2261 READ_UINT8 (&nr, pps->pps_extension_flag, 1);
2262
2263 if (pps->pps_extension_flag) {
2264 READ_UINT8 (&nr, pps->pps_range_extension_flag, 1);
2265 READ_UINT8 (&nr, pps->pps_multilayer_extension_flag, 1);
2266 READ_UINT8 (&nr, pps->pps_3d_extension_flag, 1);
2267 READ_UINT8 (&nr, pps->pps_scc_extension_flag, 1);
2268 READ_UINT8 (&nr, pps->pps_extension_4bits, 4);
2269 }
2270
2271 if (pps->pps_range_extension_flag) {
2272 if (pps->transform_skip_enabled_flag)
2273 READ_UE (&nr,
2274 pps->pps_extension_params.log2_max_transform_skip_block_size_minus2);
2275 READ_UINT8 (&nr,
2276 pps->pps_extension_params.cross_component_prediction_enabled_flag, 1);
2277 READ_UINT8 (&nr,
2278 pps->pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
2279 if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag) {
2280 READ_UE_MAX (&nr,
2281 pps->pps_extension_params.diff_cu_chroma_qp_offset_depth,
2282 sps->log2_diff_max_min_luma_coding_block_size);
2283 READ_UE_MAX (&nr,
2284 pps->pps_extension_params.chroma_qp_offset_list_len_minus1, 5);
2285 for (i = 0;
2286 i <= pps->pps_extension_params.chroma_qp_offset_list_len_minus1;
2287 i++) {
2288 READ_SE_ALLOWED (&nr, pps->pps_extension_params.cb_qp_offset_list[i],
2289 -12, 12);
2290 READ_SE_ALLOWED (&nr, pps->pps_extension_params.cr_qp_offset_list[i],
2291 -12, 12);
2292 }
2293 }
2294 MaxBitDepthY =
2295 sps->bit_depth_luma_minus8 > 2 ? sps->bit_depth_luma_minus8 - 2 : 0;
2296 MaxBitDepthC =
2297 sps->bit_depth_chroma_minus8 > 2 ? sps->bit_depth_chroma_minus8 - 2 : 0;
2298 READ_UE_ALLOWED (&nr, pps->pps_extension_params.log2_sao_offset_scale_luma,
2299 0, MaxBitDepthY);
2300 READ_UE_ALLOWED (&nr,
2301 pps->pps_extension_params.log2_sao_offset_scale_chroma, 0,
2302 MaxBitDepthC);
2303 }
2304
2305 if (pps->pps_multilayer_extension_flag) {
2306 GST_WARNING ("do not support multilayer extension, skip all"
2307 " remaining bits");
2308 goto done;
2309 }
2310 if (pps->pps_3d_extension_flag) {
2311 GST_WARNING ("do not support 3d extension, skip all remaining bits");
2312 goto done;
2313 }
2314
2315 if (pps->pps_scc_extension_flag) {
2316 READ_UINT8 (&nr,
2317 pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag, 1);
2318 READ_UINT8 (&nr,
2319 pps->pps_scc_extension_params.
2320 residual_adaptive_colour_transform_enabled_flag, 1);
2321 if (pps->pps_scc_extension_params.
2322 residual_adaptive_colour_transform_enabled_flag) {
2323 READ_UINT8 (&nr,
2324 pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag,
2325 1);
2326 READ_SE_ALLOWED (&nr,
2327 pps->pps_scc_extension_params.pps_act_y_qp_offset_plus5, -7, 17);
2328 READ_SE_ALLOWED (&nr,
2329 pps->pps_scc_extension_params.pps_act_cb_qp_offset_plus5, -7, 17);
2330 READ_SE_ALLOWED (&nr,
2331 pps->pps_scc_extension_params.pps_act_cr_qp_offset_plus3, -9, 15);
2332 }
2333
2334 READ_UINT8 (&nr,
2335 pps->pps_scc_extension_params.
2336 pps_palette_predictor_initializers_present_flag, 1);
2337 if (pps->pps_scc_extension_params.
2338 pps_palette_predictor_initializers_present_flag) {
2339 READ_UE_MAX (&nr,
2340 pps->pps_scc_extension_params.pps_num_palette_predictor_initializer,
2341 sps->sps_scc_extension_params.palette_max_size +
2342 sps->sps_scc_extension_params.delta_palette_max_predictor_size);
2343 if (pps->pps_scc_extension_params.pps_num_palette_predictor_initializer >
2344 0) {
2345 guint comp;
2346
2347 READ_UINT8 (&nr, pps->pps_scc_extension_params.monochrome_palette_flag,
2348 1);
2349 /* It is a requirement of bitstream conformance that the value of
2350 luma_bit_depth_entry_minus8 shall be equal to the value of
2351 bit_depth_luma_minus8 */
2352 READ_UE_ALLOWED (&nr,
2353 pps->pps_scc_extension_params.luma_bit_depth_entry_minus8,
2354 sps->bit_depth_luma_minus8, sps->bit_depth_luma_minus8);
2355 if (!pps->pps_scc_extension_params.monochrome_palette_flag) {
2356 /* It is a requirement of bitstream conformance that the value
2357 of chroma_bit_depth_entry_minus8 shall be equal to the value
2358 of bit_depth_chroma_minus8. */
2359 READ_UE_ALLOWED (&nr,
2360 pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8,
2361 sps->bit_depth_chroma_minus8, sps->bit_depth_chroma_minus8);
2362 }
2363
2364 for (comp = 0; comp <
2365 (pps->pps_scc_extension_params.monochrome_palette_flag ? 1 : 3);
2366 comp++) {
2367 guint num_bits;
2368 guint num =
2369 pps->pps_scc_extension_params.
2370 pps_num_palette_predictor_initializer;
2371
2372 num_bits = (comp == 0 ?
2373 pps->pps_scc_extension_params.luma_bit_depth_entry_minus8 + 8 :
2374 pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8 + 8);
2375 for (i = 0; i < num; i++)
2376 READ_UINT32 (&nr,
2377 pps->pps_scc_extension_params.pps_palette_predictor_initializer
2378 [comp][i], num_bits);
2379 }
2380 }
2381 }
2382 }
2383
2384 done:
2385 pps->valid = TRUE;
2386 return GST_H265_PARSER_OK;
2387
2388 error:
2389 GST_WARNING ("error parsing \"Picture parameter set\"");
2390 pps->valid = FALSE;
2391 return GST_H265_PARSER_ERROR;
2392 }
2393
2394 /**
2395 * gst_h265_parser_parse_pps:
2396 * @parser: a #GstH265Parser
2397 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2398 * @pps: The #GstH265PPS to fill.
2399 *
2400 * Parses @data, and fills the @pps structure.
2401 *
2402 * Returns: a #GstH265ParserResult
2403 */
2404 GstH265ParserResult
gst_h265_parser_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2405 gst_h265_parser_parse_pps (GstH265Parser * parser,
2406 GstH265NalUnit * nalu, GstH265PPS * pps)
2407 {
2408 GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
2409 if (res == GST_H265_PARSER_OK) {
2410 GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
2411
2412 parser->pps[pps->id] = *pps;
2413 parser->last_pps = &parser->pps[pps->id];
2414 }
2415
2416 return res;
2417 }
2418
2419 /**
2420 * gst_h265_parser_parse_slice_hdr:
2421 * @parser: a #GstH265Parser
2422 * @nalu: The `GST_H265_NAL_SLICE` #GstH265NalUnit to parse
2423 * @slice: The #GstH265SliceHdr to fill.
2424 *
2425 * Parses @data, and fills the @slice structure.
2426 * The resulting @slice_hdr structure shall be deallocated with
2427 * gst_h265_slice_hdr_free() when it is no longer needed
2428 *
2429 * Returns: a #GstH265ParserResult
2430 */
2431 GstH265ParserResult
gst_h265_parser_parse_slice_hdr(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SliceHdr * slice)2432 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
2433 GstH265NalUnit * nalu, GstH265SliceHdr * slice)
2434 {
2435 NalReader nr;
2436 gint pps_id;
2437 GstH265PPS *pps;
2438 GstH265SPS *sps;
2439 guint i;
2440 GstH265ShortTermRefPicSet *stRPS = NULL;
2441 guint32 UsedByCurrPicLt[16];
2442 guint32 PicSizeInCtbsY;
2443 gint NumPocTotalCurr = 0;
2444
2445 memset (slice, 0, sizeof (*slice));
2446
2447 if (!nalu->size) {
2448 GST_DEBUG ("Invalid Nal Unit");
2449 return GST_H265_PARSER_ERROR;
2450 }
2451
2452 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2453 nalu->size - nalu->header_bytes);
2454
2455 GST_DEBUG ("parsing \"Slice header\", slice type");
2456
2457 READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
2458
2459 if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type))
2460 READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
2461
2462 READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
2463 pps = gst_h265_parser_get_pps (parser, pps_id);
2464 if (!pps) {
2465 GST_WARNING
2466 ("couldn't find associated picture parameter set with id: %d", pps_id);
2467 return GST_H265_PARSER_BROKEN_LINK;
2468 }
2469
2470 slice->pps = pps;
2471 sps = pps->sps;
2472 if (!sps) {
2473 GST_WARNING
2474 ("couldn't find associated sequence parameter set with id: %d",
2475 pps->id);
2476 return GST_H265_PARSER_BROKEN_LINK;
2477 }
2478
2479 PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
2480 /* set default values for fields that might not be present in the bitstream
2481 * and have valid defaults */
2482 slice->pic_output_flag = 1;
2483 slice->collocated_from_l0_flag = 1;
2484 slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
2485 slice->beta_offset_div2 = pps->beta_offset_div2;
2486 slice->tc_offset_div2 = pps->tc_offset_div2;
2487 slice->loop_filter_across_slices_enabled_flag =
2488 pps->loop_filter_across_slices_enabled_flag;
2489
2490 if (!slice->first_slice_segment_in_pic_flag) {
2491 const guint n = ceil_log2 (PicSizeInCtbsY);
2492
2493 if (pps->dependent_slice_segments_enabled_flag)
2494 READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
2495 /* sice_segment_address parsing */
2496 READ_UINT32 (&nr, slice->segment_address, n);
2497 }
2498
2499 if (!slice->dependent_slice_segment_flag) {
2500 for (i = 0; i < pps->num_extra_slice_header_bits; i++)
2501 nal_reader_skip (&nr, 1);
2502 READ_UE_MAX (&nr, slice->type, 63);
2503
2504
2505 if (pps->output_flag_present_flag)
2506 READ_UINT8 (&nr, slice->pic_output_flag, 1);
2507 if (sps->separate_colour_plane_flag == 1)
2508 READ_UINT8 (&nr, slice->colour_plane_id, 2);
2509
2510 if (!GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
2511 READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
2512 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2513
2514 READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
2515 if (!slice->short_term_ref_pic_set_sps_flag) {
2516 guint pos = nal_reader_get_pos (&nr);
2517 if (!gst_h265_parser_parse_short_term_ref_pic_sets
2518 (&slice->short_term_ref_pic_sets, &nr,
2519 sps->num_short_term_ref_pic_sets, sps))
2520 goto error;
2521
2522 slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
2523 } else if (sps->num_short_term_ref_pic_sets > 1) {
2524 const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
2525 READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
2526 CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
2527 sps->num_short_term_ref_pic_sets - 1);
2528 }
2529
2530 if (sps->long_term_ref_pics_present_flag) {
2531 guint32 limit;
2532
2533 if (sps->num_long_term_ref_pics_sps > 0)
2534 READ_UE_MAX (&nr, slice->num_long_term_sps,
2535 sps->num_long_term_ref_pics_sps);
2536
2537 READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2538 limit = slice->num_long_term_sps + slice->num_long_term_pics;
2539 for (i = 0; i < limit; i++) {
2540 if (i < slice->num_long_term_sps) {
2541 if (sps->num_long_term_ref_pics_sps > 1) {
2542 const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2543 READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2544 }
2545 } else {
2546 READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2547 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2548 READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2549 }
2550
2551 /* calculate UsedByCurrPicLt */
2552 if (i < slice->num_long_term_sps)
2553 UsedByCurrPicLt[i] =
2554 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2555 else
2556 UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2557 READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2558 if (slice->delta_poc_msb_present_flag[i])
2559 READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2560 }
2561 }
2562 if (sps->temporal_mvp_enabled_flag)
2563 READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2564 }
2565
2566 if (sps->sample_adaptive_offset_enabled_flag) {
2567 READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2568 if (sps->chroma_array_type)
2569 READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2570 }
2571
2572 if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2573 READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2574
2575 if (slice->num_ref_idx_active_override_flag) {
2576 READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2577 if (GST_H265_IS_B_SLICE (slice))
2578 READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2579 } else {
2580 /*set default values */
2581 slice->num_ref_idx_l0_active_minus1 =
2582 pps->num_ref_idx_l0_default_active_minus1;
2583 slice->num_ref_idx_l1_active_minus1 =
2584 pps->num_ref_idx_l1_default_active_minus1;
2585 }
2586
2587 /* calculate NumPocTotalCurr */
2588 if (slice->short_term_ref_pic_set_sps_flag)
2589 stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2590 else
2591 stRPS = &slice->short_term_ref_pic_sets;
2592
2593 for (i = 0; i < stRPS->NumNegativePics; i++)
2594 if (stRPS->UsedByCurrPicS0[i])
2595 NumPocTotalCurr++;
2596 for (i = 0; i < stRPS->NumPositivePics; i++)
2597 if (stRPS->UsedByCurrPicS1[i])
2598 NumPocTotalCurr++;
2599 for (i = 0;
2600 i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2601 if (UsedByCurrPicLt[i])
2602 NumPocTotalCurr++;
2603 slice->NumPocTotalCurr = NumPocTotalCurr;
2604
2605 if (pps->lists_modification_present_flag) {
2606 if (NumPocTotalCurr > 1)
2607 if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2608 NumPocTotalCurr))
2609 goto error;
2610 }
2611
2612 if (GST_H265_IS_B_SLICE (slice))
2613 READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2614 if (pps->cabac_init_present_flag)
2615 READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2616 if (slice->temporal_mvp_enabled_flag) {
2617 if (GST_H265_IS_B_SLICE (slice))
2618 READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2619
2620 if ((slice->collocated_from_l0_flag
2621 && slice->num_ref_idx_l0_active_minus1 > 0)
2622 || (!slice->collocated_from_l0_flag
2623 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2624
2625 /*fixme: add optimization */
2626 if ((GST_H265_IS_P_SLICE (slice))
2627 || ((GST_H265_IS_B_SLICE (slice))
2628 && (slice->collocated_from_l0_flag))) {
2629 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2630 slice->num_ref_idx_l0_active_minus1);
2631 } else if ((GST_H265_IS_B_SLICE (slice))
2632 && (!slice->collocated_from_l0_flag)) {
2633 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2634 slice->num_ref_idx_l1_active_minus1);
2635 }
2636 }
2637 }
2638 if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2639 (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2640 if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2641 goto error;
2642 READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2643
2644 if (sps->sps_scc_extension_params.motion_vector_resolution_control_idc
2645 == 2)
2646 READ_UINT8 (&nr, slice->use_integer_mv_flag, 1);
2647 }
2648
2649 READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2650 if (pps->slice_chroma_qp_offsets_present_flag) {
2651 READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2652 READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2653 }
2654
2655 if (pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag) {
2656 READ_SE_ALLOWED (&nr, slice->slice_act_y_qp_offset, -12, 12);
2657 READ_SE_ALLOWED (&nr, slice->slice_act_cb_qp_offset, -12, 12);
2658 READ_SE_ALLOWED (&nr, slice->slice_act_cr_qp_offset, -12, 12);
2659 }
2660
2661 if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag)
2662 READ_UINT8 (&nr, slice->cu_chroma_qp_offset_enabled_flag, 1);
2663
2664 if (pps->deblocking_filter_override_enabled_flag)
2665 READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2666 if (slice->deblocking_filter_override_flag) {
2667 READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2668 if (!slice->deblocking_filter_disabled_flag) {
2669 READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2670 READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2671 }
2672 }
2673
2674 if (pps->loop_filter_across_slices_enabled_flag &&
2675 (slice->sao_luma_flag || slice->sao_chroma_flag ||
2676 !slice->deblocking_filter_disabled_flag))
2677 READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2678 }
2679
2680 if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2681 guint32 offset_max;
2682
2683 if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2684 offset_max = pps->PicHeightInCtbsY - 1;
2685 else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2686 offset_max =
2687 (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2688 1;
2689 else
2690 offset_max =
2691 (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2692
2693 READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2694 if (slice->num_entry_point_offsets > 0) {
2695 READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2696 slice->entry_point_offset_minus1 =
2697 g_new0 (guint32, slice->num_entry_point_offsets);
2698 for (i = 0; i < slice->num_entry_point_offsets; i++)
2699 READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2700 (slice->offset_len_minus1 + 1));
2701 }
2702 }
2703
2704 if (pps->slice_segment_header_extension_present_flag) {
2705 guint16 slice_segment_header_extension_length;
2706 READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2707 for (i = 0; i < slice_segment_header_extension_length; i++)
2708 if (!nal_reader_skip (&nr, 8))
2709 goto error;
2710 }
2711
2712 /* Skip the byte alignment bits */
2713 if (!nal_reader_skip (&nr, 1))
2714 goto error;
2715 while (!nal_reader_is_byte_aligned (&nr)) {
2716 if (!nal_reader_skip (&nr, 1))
2717 goto error;
2718 }
2719
2720 slice->header_size = nal_reader_get_pos (&nr);
2721 slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2722
2723 return GST_H265_PARSER_OK;
2724
2725 error:
2726 GST_WARNING ("error parsing \"Slice header\"");
2727
2728 gst_h265_slice_hdr_free (slice);
2729
2730 return GST_H265_PARSER_ERROR;
2731 }
2732
2733 static gboolean
nal_reader_has_more_data_in_payload(NalReader * nr,guint32 payload_start_pos_bit,guint32 payloadSize)2734 nal_reader_has_more_data_in_payload (NalReader * nr,
2735 guint32 payload_start_pos_bit, guint32 payloadSize)
2736 {
2737 if (nal_reader_is_byte_aligned (nr) &&
2738 (nal_reader_get_pos (nr) >= (payload_start_pos_bit + 8 * payloadSize)))
2739 return FALSE;
2740
2741 return TRUE;
2742 }
2743
2744 static GstH265ParserResult
gst_h265_parser_parse_sei_message(GstH265Parser * parser,guint8 nal_type,NalReader * nr,GstH265SEIMessage * sei)2745 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2746 guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2747 {
2748 guint32 payloadSize;
2749 guint8 payload_type_byte, payload_size_byte;
2750 guint remaining, payload_size;
2751 guint32 payload_start_pos_bit;
2752 GstH265ParserResult res = GST_H265_PARSER_OK;
2753
2754 GST_DEBUG ("parsing \"Sei message\"");
2755
2756 memset (sei, 0, sizeof (*sei));
2757
2758 do {
2759 READ_UINT8 (nr, payload_type_byte, 8);
2760 sei->payloadType += payload_type_byte;
2761 } while (payload_type_byte == 0xff);
2762 payloadSize = 0;
2763 do {
2764 READ_UINT8 (nr, payload_size_byte, 8);
2765 payloadSize += payload_size_byte;
2766 }
2767 while (payload_size_byte == 0xff);
2768
2769 remaining = nal_reader_get_remaining (nr);
2770 payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
2771
2772 payload_start_pos_bit = nal_reader_get_pos (nr);
2773 GST_DEBUG
2774 ("SEI message received: payloadType %u, payloadSize = %u bits",
2775 sei->payloadType, payload_size);
2776
2777 if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2778 switch (sei->payloadType) {
2779 case GST_H265_SEI_BUF_PERIOD:
2780 /* size not set; might depend on emulation_prevention_three_byte */
2781 res = gst_h265_parser_parse_buffering_period (parser,
2782 &sei->payload.buffering_period, nr);
2783 break;
2784 case GST_H265_SEI_PIC_TIMING:
2785 /* size not set; might depend on emulation_prevention_three_byte */
2786 res = gst_h265_parser_parse_pic_timing (parser,
2787 &sei->payload.pic_timing, nr);
2788 break;
2789 case GST_H265_SEI_REGISTERED_USER_DATA:
2790 res = gst_h265_parser_parse_registered_user_data (parser,
2791 &sei->payload.registered_user_data, nr, payload_size >> 3);
2792 break;
2793 case GST_H265_SEI_RECOVERY_POINT:
2794 res = gst_h265_parser_parse_recovery_point (parser,
2795 &sei->payload.recovery_point, nr);
2796 break;
2797 case GST_H265_SEI_TIME_CODE:
2798 res = gst_h265_parser_parse_time_code (parser,
2799 &sei->payload.time_code, nr);
2800 break;
2801 case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
2802 res = gst_h265_parser_parse_mastering_display_colour_volume (parser,
2803 &sei->payload.mastering_display_colour_volume, nr);
2804 break;
2805 case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
2806 res = gst_h265_parser_parse_content_light_level_info (parser,
2807 &sei->payload.content_light_level, nr);
2808 break;
2809 default:
2810 /* Just consume payloadSize bytes, which does not account for
2811 emulation prevention bytes */
2812 if (!nal_reader_skip_long (nr, payload_size))
2813 goto error;
2814 res = GST_H265_PARSER_OK;
2815 break;
2816 }
2817 } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2818 switch (sei->payloadType) {
2819 default:
2820 /* Just consume payloadSize bytes, which does not account for
2821 emulation prevention bytes */
2822 if (!nal_reader_skip_long (nr, payload_size))
2823 goto error;
2824 res = GST_H265_PARSER_OK;
2825 break;
2826 }
2827 }
2828
2829 /* Not parsing the reserved_payload_extension, but it shouldn't be
2830 * an issue because of 1: There shall not be any reserved_payload_extension
2831 * present in bitstreams conforming to the specification.2. Even though
2832 * it is present, the size will be less than total PayloadSize since the
2833 * size of reserved_payload_extension is supposed to be
2834 * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2835 * the current implementation will still skip all unnecessary bits correctly.
2836 * In theory, we can have a more optimized implementation by skipping the
2837 * data left in PayLoadSize without out individually checking for each bits,
2838 * since the totoal size will be always less than payloadSize*/
2839 while (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
2840 payloadSize)) {
2841 /* Skip the byte alignment bits */
2842 if (!nal_reader_skip (nr, 1))
2843 goto error;
2844 while (!nal_reader_is_byte_aligned (nr)) {
2845 if (!nal_reader_skip (nr, 1))
2846 goto error;
2847 }
2848 }
2849
2850 return res;
2851
2852 error:
2853 GST_WARNING ("error parsing \"Sei message\"");
2854 return GST_H265_PARSER_ERROR;
2855 }
2856
2857 /**
2858 * gst_h265_slice_hdr_copy:
2859 * @dst_slice: The destination #GstH265SliceHdr to copy into
2860 * @src_slice: The source #GstH265SliceHdr to copy from
2861 *
2862 * Copies @src_slice into @dst_slice
2863 *
2864 * Returns: %TRUE if everything went fine, %FALSE otherwise
2865 */
2866 gboolean
gst_h265_slice_hdr_copy(GstH265SliceHdr * dst_slice,const GstH265SliceHdr * src_slice)2867 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2868 const GstH265SliceHdr * src_slice)
2869 {
2870 guint i;
2871
2872 g_return_val_if_fail (dst_slice != NULL, FALSE);
2873 g_return_val_if_fail (src_slice != NULL, FALSE);
2874
2875 gst_h265_slice_hdr_free (dst_slice);
2876
2877 *dst_slice = *src_slice;
2878
2879 if (dst_slice->num_entry_point_offsets > 0) {
2880 dst_slice->entry_point_offset_minus1 =
2881 g_new0 (guint32, dst_slice->num_entry_point_offsets);
2882 for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2883 dst_slice->entry_point_offset_minus1[i] =
2884 src_slice->entry_point_offset_minus1[i];
2885 }
2886
2887 return TRUE;
2888 }
2889
2890 /**
2891 * gst_h265_slice_hdr_free:
2892 * slice_hdr: The #GstH265SliceHdr to free
2893 *
2894 * Frees @slice_hdr fields.
2895 */
2896 void
gst_h265_slice_hdr_free(GstH265SliceHdr * slice_hdr)2897 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2898 {
2899 g_return_if_fail (slice_hdr != NULL);
2900
2901 if (slice_hdr->num_entry_point_offsets > 0)
2902 g_free (slice_hdr->entry_point_offset_minus1);
2903 slice_hdr->entry_point_offset_minus1 = 0;
2904 }
2905
2906 /**
2907 * gst_h265_sei_copy:
2908 * @dst_sei: The destination #GstH265SEIMessage to copy into
2909 * @src_sei: The source #GstH265SEIMessage to copy from
2910 *
2911 * Copies @src_sei into @dst_sei
2912 *
2913 * Returns: %TRUE if everything went fine, %FALSE otherwise
2914 */
2915 gboolean
gst_h265_sei_copy(GstH265SEIMessage * dst_sei,const GstH265SEIMessage * src_sei)2916 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2917 const GstH265SEIMessage * src_sei)
2918 {
2919 guint i;
2920
2921 g_return_val_if_fail (dst_sei != NULL, FALSE);
2922 g_return_val_if_fail (src_sei != NULL, FALSE);
2923
2924 gst_h265_sei_free (dst_sei);
2925
2926 *dst_sei = *src_sei;
2927
2928 if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2929 GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2930 const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2931
2932 if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2933 dst_pic_timing->num_nalus_in_du_minus1 =
2934 g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2935 dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2936 g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2937
2938 for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2939 dst_pic_timing->num_nalus_in_du_minus1[i] =
2940 src_pic_timing->num_nalus_in_du_minus1[i];
2941 dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2942 src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2943 }
2944 }
2945 } else if (dst_sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2946 GstH265RegisteredUserData *dst_rud = &dst_sei->payload.registered_user_data;
2947 const GstH265RegisteredUserData *src_rud =
2948 &src_sei->payload.registered_user_data;
2949
2950 if (src_rud->size) {
2951 dst_rud->data = g_malloc (src_rud->size);
2952 memcpy ((guint8 *) dst_rud->data, src_rud->data, src_rud->size);
2953 }
2954 }
2955
2956 return TRUE;
2957 }
2958
2959 /**
2960 * gst_h265_sei_free:
2961 * sei: The #GstH265SEIMessage to free
2962 *
2963 * Frees @sei fields.
2964 */
2965 void
gst_h265_sei_free(GstH265SEIMessage * sei)2966 gst_h265_sei_free (GstH265SEIMessage * sei)
2967 {
2968 g_return_if_fail (sei != NULL);
2969
2970 if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2971 GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2972 if (pic_timing->num_decoding_units_minus1 > 0) {
2973 g_free (pic_timing->num_nalus_in_du_minus1);
2974 g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2975 }
2976 pic_timing->num_nalus_in_du_minus1 = 0;
2977 pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2978 } else if (sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2979 GstH265RegisteredUserData *rud = &sei->payload.registered_user_data;
2980 g_free ((guint8 *) rud->data);
2981 rud->data = NULL;
2982 }
2983 }
2984
2985 /**
2986 * gst_h265_parser_parse_sei:
2987 * @nalparser: a #GstH265Parser
2988 * @nalu: The `GST_H265_NAL_*_SEI` #GstH265NalUnit to parse
2989 * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2990 *
2991 * Parses @data, create and fills the @messages array.
2992 *
2993 * Returns: a #GstH265ParserResult
2994 */
2995 GstH265ParserResult
gst_h265_parser_parse_sei(GstH265Parser * nalparser,GstH265NalUnit * nalu,GArray ** messages)2996 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2997 GArray ** messages)
2998 {
2999 NalReader nr;
3000 GstH265SEIMessage sei;
3001 GstH265ParserResult res;
3002
3003 GST_DEBUG ("parsing SEI nal");
3004 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
3005 nalu->size - nalu->header_bytes);
3006 *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
3007 g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
3008
3009 do {
3010 res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
3011 if (res == GST_H265_PARSER_OK)
3012 g_array_append_val (*messages, sei);
3013 else
3014 break;
3015 } while (nal_reader_has_more_data (&nr));
3016
3017 return res;
3018 }
3019
3020 /**
3021 * gst_h265_parser_update_vps:
3022 * @parser: a #GstH265Parser
3023 * @vps: (transfer none): a #GstH265VPS.
3024 *
3025 * Replace internal Video Parameter Set struct corresponding to id of @vps
3026 * with @vps. @nalparser will mark @vps as last parsed vps.
3027 *
3028 * Returns: a #GstH265ParserResult
3029 *
3030 * Since: 1.18
3031 */
3032 GstH265ParserResult
gst_h265_parser_update_vps(GstH265Parser * parser,GstH265VPS * vps)3033 gst_h265_parser_update_vps (GstH265Parser * parser, GstH265VPS * vps)
3034 {
3035 g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3036 g_return_val_if_fail (vps != NULL, GST_H265_PARSER_ERROR);
3037 g_return_val_if_fail (vps->id < GST_H265_MAX_VPS_COUNT,
3038 GST_H265_PARSER_ERROR);
3039
3040 if (!vps->valid) {
3041 GST_WARNING ("Cannot update with invalid VPS");
3042 return GST_H265_PARSER_ERROR;
3043 }
3044
3045 GST_DEBUG ("Updating video parameter set with id: %d", vps->id);
3046
3047 parser->vps[vps->id] = *vps;
3048 parser->last_vps = &parser->vps[vps->id];
3049
3050 return GST_H265_PARSER_OK;
3051 }
3052
3053 /**
3054 * gst_h265_parser_update_sps:
3055 * @parser: a #GstH265Parser
3056 * @sps: (transfer none): a #GstH265SPS.
3057 *
3058 * Replace internal Sequence Parameter Set struct corresponding to id of @sps
3059 * with @sps. @nalparser will mark @sps as last parsed sps.
3060 *
3061 * Returns: a #GstH265ParserResult
3062 *
3063 * Since: 1.18
3064 */
3065 GstH265ParserResult
gst_h265_parser_update_sps(GstH265Parser * parser,GstH265SPS * sps)3066 gst_h265_parser_update_sps (GstH265Parser * parser, GstH265SPS * sps)
3067 {
3068 g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3069 g_return_val_if_fail (sps != NULL, GST_H265_PARSER_ERROR);
3070 g_return_val_if_fail (sps->id < GST_H265_MAX_SPS_COUNT,
3071 GST_H265_PARSER_ERROR);
3072
3073 if (!sps->valid) {
3074 GST_WARNING ("Cannot update with invalid SPS");
3075 return GST_H265_PARSER_ERROR;
3076 }
3077
3078 if (sps->vps) {
3079 GstH265VPS *vps = gst_h265_parser_get_vps (parser, sps->vps->id);
3080 if (!vps || vps != sps->vps) {
3081 GST_WARNING ("Linked VPS is not identical to internal VPS");
3082 return GST_H265_PARSER_BROKEN_LINK;
3083 }
3084 }
3085
3086 GST_DEBUG ("Updating sequence parameter set with id: %d", sps->id);
3087
3088 parser->sps[sps->id] = *sps;
3089 parser->last_sps = &parser->sps[sps->id];
3090
3091 return GST_H265_PARSER_OK;
3092 }
3093
3094 /**
3095 * gst_h265_parser_update_pps:
3096 * @parser: a #GstH265Parser
3097 * @pps: (transfer none): a #GstH265PPS.
3098 *
3099 * Replace internal Sequence Parameter Set struct corresponding to id of @pps
3100 * with @pps. @nalparser will mark @pps as last parsed sps.
3101 *
3102 * Returns: a #GstH265ParserResult
3103 *
3104 * Since: 1.18
3105 */
3106 GstH265ParserResult
gst_h265_parser_update_pps(GstH265Parser * parser,GstH265PPS * pps)3107 gst_h265_parser_update_pps (GstH265Parser * parser, GstH265PPS * pps)
3108 {
3109 GstH265SPS *sps;
3110
3111 g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3112 g_return_val_if_fail (pps != NULL, GST_H265_PARSER_ERROR);
3113 g_return_val_if_fail (pps->id < GST_H265_MAX_PPS_COUNT,
3114 GST_H265_PARSER_ERROR);
3115
3116 if (!pps->valid) {
3117 GST_WARNING ("Cannot update with invalid PPS");
3118 return GST_H265_PARSER_ERROR;
3119 }
3120
3121 if (!pps->sps) {
3122 GST_WARNING ("No linked SPS struct");
3123 return GST_H265_PARSER_BROKEN_LINK;
3124 }
3125
3126 sps = gst_h265_parser_get_sps (parser, pps->sps->id);
3127 if (!sps || sps != pps->sps) {
3128 GST_WARNING ("Linked SPS is not identical to internal SPS");
3129 return GST_H265_PARSER_BROKEN_LINK;
3130 }
3131
3132 GST_DEBUG ("Updating picture parameter set with id: %d", pps->id);
3133
3134 parser->pps[pps->id] = *pps;
3135 parser->last_pps = &parser->pps[pps->id];
3136
3137 return GST_H265_PARSER_OK;
3138 }
3139
3140 /**
3141 * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
3142 * @out_quant: (out): The resulting quantization matrix
3143 * @quant: The source quantization matrix
3144 *
3145 * Converts quantization matrix @quant from raster scan order to
3146 * zigzag scan order and store the resulting factors into @out_quant.
3147 *
3148 * Note: it is an error to pass the same table in both @quant and
3149 * @out_quant arguments.
3150 *
3151 * Since: 1.6
3152 */
3153 void
gst_h265_quant_matrix_4x4_get_zigzag_from_raster(guint8 out_quant[16],const guint8 quant[16])3154 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
3155 const guint8 quant[16])
3156 {
3157 guint i;
3158
3159 g_return_if_fail (out_quant != quant);
3160
3161 for (i = 0; i < 16; i++)
3162 out_quant[i] = quant[zigzag_4x4[i]];
3163 }
3164
3165 /**
3166 * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
3167 * @out_quant: (out): The resulting quantization matrix
3168 * @quant: The source quantization matrix
3169 *
3170 * Converts quantization matrix @quant from zigzag scan order to
3171 * raster scan order and store the resulting factors into @out_quant.
3172 *
3173 * Note: it is an error to pass the same table in both @quant and
3174 * @out_quant arguments.
3175 *
3176 * Since: 1.6
3177 */
3178 void
gst_h265_quant_matrix_4x4_get_raster_from_zigzag(guint8 out_quant[16],const guint8 quant[16])3179 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
3180 const guint8 quant[16])
3181 {
3182 guint i;
3183
3184 g_return_if_fail (out_quant != quant);
3185
3186 for (i = 0; i < 16; i++)
3187 out_quant[zigzag_4x4[i]] = quant[i];
3188 }
3189
3190 /**
3191 * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
3192 * @out_quant: (out): The resulting quantization matrix
3193 * @quant: The source quantization matrix
3194 *
3195 * Converts quantization matrix @quant from raster scan order to
3196 * zigzag scan order and store the resulting factors into @out_quant.
3197 *
3198 * Note: it is an error to pass the same table in both @quant and
3199 * @out_quant arguments.
3200 *
3201 * Since: 1.6
3202 */
3203 void
gst_h265_quant_matrix_8x8_get_zigzag_from_raster(guint8 out_quant[64],const guint8 quant[64])3204 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
3205 const guint8 quant[64])
3206 {
3207 guint i;
3208
3209 g_return_if_fail (out_quant != quant);
3210
3211 for (i = 0; i < 64; i++)
3212 out_quant[i] = quant[zigzag_8x8[i]];
3213 }
3214
3215 /**
3216 * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
3217 * @out_quant: (out): The resulting quantization matrix
3218 * @quant: The source quantization matrix
3219 *
3220 * Converts quantization matrix @quant from zigzag scan order to
3221 * raster scan order and store the resulting factors into @out_quant.
3222 *
3223 * Note: it is an error to pass the same table in both @quant and
3224 * @out_quant arguments.
3225 *
3226 * Since: 1.6
3227 */
3228 void
gst_h265_quant_matrix_8x8_get_raster_from_zigzag(guint8 out_quant[64],const guint8 quant[64])3229 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
3230 const guint8 quant[64])
3231 {
3232 guint i;
3233
3234 g_return_if_fail (out_quant != quant);
3235
3236 for (i = 0; i < 64; i++)
3237 out_quant[zigzag_8x8[i]] = quant[i];
3238 }
3239
3240 /**
3241 * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
3242 * @out_quant: (out): The resulting quantization matrix
3243 * @quant: The source quantization matrix
3244 *
3245 * Converts quantization matrix @quant from raster scan order to
3246 * uprightdiagonal scan order and store the resulting factors
3247 * into @out_quant.
3248 *
3249 * Note: it is an error to pass the same table in both @quant and
3250 * @out_quant arguments.
3251 *
3252 * Since: 1.6
3253 */
3254 void
gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster(guint8 out_quant[16],const guint8 quant[16])3255 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
3256 const guint8 quant[16])
3257 {
3258 guint i;
3259
3260 g_return_if_fail (out_quant != quant);
3261
3262 for (i = 0; i < 16; i++)
3263 out_quant[i] = quant[uprightdiagonal_4x4[i]];
3264 }
3265
3266 /**
3267 * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
3268 * @out_quant: (out): The resulting quantization matrix
3269 * @quant: The source quantization matrix
3270 *
3271 * Converts quantization matrix @quant from uprightdiagonal scan order to
3272 * raster scan order and store the resulting factors into @out_quant.
3273 *
3274 * Note: it is an error to pass the same table in both @quant and
3275 * @out_quant arguments.
3276 *
3277 * Since: 1.6
3278 */
3279 void
gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal(guint8 out_quant[16],const guint8 quant[16])3280 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
3281 const guint8 quant[16])
3282 {
3283 guint i;
3284
3285 g_return_if_fail (out_quant != quant);
3286
3287 for (i = 0; i < 16; i++)
3288 out_quant[uprightdiagonal_4x4[i]] = quant[i];
3289 }
3290
3291 /**
3292 * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
3293 * @out_quant: (out): The resulting quantization matrix
3294 * @quant: The source quantization matrix
3295 *
3296 * Converts quantization matrix @quant from raster scan order to
3297 * uprightdiagonal scan order and store the resulting factors
3298 * into @out_quant.
3299 *
3300 * Note: it is an error to pass the same table in both @quant and
3301 * @out_quant arguments.
3302 *
3303 * Since: 1.6
3304 */
3305 void
gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster(guint8 out_quant[64],const guint8 quant[64])3306 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
3307 const guint8 quant[64])
3308 {
3309 guint i;
3310
3311 g_return_if_fail (out_quant != quant);
3312
3313 for (i = 0; i < 64; i++)
3314 out_quant[i] = quant[uprightdiagonal_8x8[i]];
3315 }
3316
3317 /**
3318 * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
3319 * @out_quant: (out): The resulting quantization matrix
3320 * @quant: The source quantization matrix
3321 *
3322 * Converts quantization matrix @quant from uprightdiagonal scan order to
3323 * raster scan order and store the resulting factors into @out_quant.
3324 *
3325 * Note: it is an error to pass the same table in both @quant and
3326 * @out_quant arguments.
3327 *
3328 * Since: 1.6
3329 */
3330 void
gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal(guint8 out_quant[64],const guint8 quant[64])3331 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
3332 const guint8 quant[64])
3333 {
3334 guint i;
3335
3336 g_return_if_fail (out_quant != quant);
3337
3338 for (i = 0; i < 64; i++)
3339 out_quant[uprightdiagonal_8x8[i]] = quant[i];
3340 }
3341
3342 typedef struct
3343 {
3344 GstH265Profile profile;
3345
3346 guint8 max_14bit_constraint_flag;
3347 guint8 max_12bit_constraint_flag;
3348 guint8 max_10bit_constraint_flag;
3349 guint8 max_8bit_constraint_flag;
3350 guint8 max_422chroma_constraint_flag;
3351 guint8 max_420chroma_constraint_flag;
3352 guint8 max_monochrome_constraint_flag;
3353 guint8 intra_constraint_flag;
3354 guint8 one_picture_only_constraint_flag;
3355 gboolean lower_bit_rate_constraint_flag_set;
3356
3357 /* Tie breaker if more than one profiles are matching */
3358 guint priority;
3359 } H265ExtensionProfile;
3360
3361 typedef struct
3362 {
3363 H265ExtensionProfile *profile;
3364 guint extra_constraints;
3365 } H265ExtensionProfileMatch;
3366
3367 static gint
sort_fre_profile_matches(H265ExtensionProfileMatch * a,H265ExtensionProfileMatch * b)3368 sort_fre_profile_matches (H265ExtensionProfileMatch * a,
3369 H265ExtensionProfileMatch * b)
3370 {
3371 gint d;
3372
3373 d = a->extra_constraints - b->extra_constraints;
3374 if (d)
3375 return d;
3376
3377 return b->profile->priority - a->profile->priority;
3378 }
3379
3380 static GstH265Profile
get_extension_profile(H265ExtensionProfile * profiles,guint num,const GstH265ProfileTierLevel * ptl)3381 get_extension_profile (H265ExtensionProfile * profiles, guint num,
3382 const GstH265ProfileTierLevel * ptl)
3383 {
3384 GstH265Profile result = GST_H265_PROFILE_INVALID;
3385 guint i;
3386 GList *matches = NULL;
3387
3388 for (i = 0; i < num; i++) {
3389 H265ExtensionProfile p = profiles[i];
3390 guint extra_constraints = 0;
3391 H265ExtensionProfileMatch *m;
3392
3393 /* Filter out all the profiles having constraints not satisfied by @ptl.
3394 * Then pick the one having the least extra constraints. This allow us
3395 * to match the closest profile if bitstream contains not standard
3396 * constraints. */
3397 if (p.max_14bit_constraint_flag != ptl->max_14bit_constraint_flag) {
3398 if (p.max_14bit_constraint_flag)
3399 continue;
3400 extra_constraints++;
3401 }
3402
3403 if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
3404 if (p.max_12bit_constraint_flag)
3405 continue;
3406 extra_constraints++;
3407 }
3408
3409 if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
3410 if (p.max_10bit_constraint_flag)
3411 continue;
3412 extra_constraints++;
3413 }
3414
3415 if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
3416 if (p.max_8bit_constraint_flag)
3417 continue;
3418 extra_constraints++;
3419 }
3420
3421 if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
3422 if (p.max_422chroma_constraint_flag)
3423 continue;
3424 extra_constraints++;
3425 }
3426
3427 if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
3428 if (p.max_420chroma_constraint_flag)
3429 continue;
3430 extra_constraints++;
3431 }
3432
3433 if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
3434 if (p.max_monochrome_constraint_flag)
3435 continue;
3436 extra_constraints++;
3437 }
3438
3439 if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
3440 if (p.intra_constraint_flag)
3441 continue;
3442 extra_constraints++;
3443 }
3444
3445 if (p.one_picture_only_constraint_flag !=
3446 ptl->one_picture_only_constraint_flag) {
3447 if (p.one_picture_only_constraint_flag)
3448 continue;
3449 extra_constraints++;
3450 }
3451
3452 if (p.lower_bit_rate_constraint_flag_set
3453 && !ptl->lower_bit_rate_constraint_flag)
3454 continue;
3455
3456 if (extra_constraints == 0) {
3457 result = p.profile;
3458 break;
3459 }
3460
3461 m = g_new0 (H265ExtensionProfileMatch, 1);
3462 m->profile = &profiles[i];
3463 m->extra_constraints = extra_constraints;
3464 matches = g_list_prepend (matches, m);
3465 }
3466
3467 if (result == GST_H265_PROFILE_INVALID && matches) {
3468 H265ExtensionProfileMatch *m;
3469
3470 matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
3471 m = matches->data;
3472 result = m->profile->profile;
3473 GST_INFO ("Fail to find the profile matches all extensions bits,"
3474 " select the closest %s with %d bit diff",
3475 gst_h265_profile_to_string (result), m->extra_constraints);
3476 }
3477
3478 if (matches)
3479 g_list_free_full (matches, g_free);
3480
3481 return result;
3482 }
3483
3484 static GstH265Profile
get_format_range_extension_profile(const GstH265ProfileTierLevel * ptl)3485 get_format_range_extension_profile (const GstH265ProfileTierLevel * ptl)
3486 {
3487 /* Profile idc: GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
3488 See Table A.2 for the definition of those formats */
3489 static H265ExtensionProfile profiles[] = {
3490 {GST_H265_PROFILE_MONOCHROME,
3491 0, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3492 {GST_H265_PROFILE_MONOCHROME_10,
3493 0, 1, 1, 0, 1, 1, 1, 0, 0, TRUE, 1},
3494 {GST_H265_PROFILE_MONOCHROME_12,
3495 0, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3496 {GST_H265_PROFILE_MONOCHROME_16,
3497 0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 3},
3498 {GST_H265_PROFILE_MAIN_12,
3499 0, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 4},
3500 {GST_H265_PROFILE_MAIN_422_10,
3501 0, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 5},
3502 {GST_H265_PROFILE_MAIN_422_12,
3503 0, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 6},
3504 {GST_H265_PROFILE_MAIN_444,
3505 0, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 7},
3506 {GST_H265_PROFILE_MAIN_444_10,
3507 0, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 8},
3508 {GST_H265_PROFILE_MAIN_444_12,
3509 0, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 9},
3510 {GST_H265_PROFILE_MAIN_INTRA,
3511 0, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 10},
3512 {GST_H265_PROFILE_MAIN_10_INTRA,
3513 0, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 11},
3514 {GST_H265_PROFILE_MAIN_12_INTRA,
3515 0, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 12},
3516 {GST_H265_PROFILE_MAIN_422_10_INTRA,
3517 0, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 13},
3518 {GST_H265_PROFILE_MAIN_422_12_INTRA,
3519 0, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 14},
3520 {GST_H265_PROFILE_MAIN_444_INTRA,
3521 0, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 15},
3522 {GST_H265_PROFILE_MAIN_444_10_INTRA,
3523 0, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 16},
3524 {GST_H265_PROFILE_MAIN_444_12_INTRA,
3525 0, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
3526 {GST_H265_PROFILE_MAIN_444_16_INTRA,
3527 0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 18},
3528 {GST_H265_PROFILE_MAIN_444_STILL_PICTURE,
3529 0, 1, 1, 1, 0, 0, 0, 1, 1, FALSE, 19},
3530 {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE,
3531 0, 0, 0, 0, 0, 0, 0, 1, 1, FALSE, 20},
3532 };
3533
3534 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3535 }
3536
3537 static GstH265Profile
get_3d_profile(const GstH265ProfileTierLevel * ptl)3538 get_3d_profile (const GstH265ProfileTierLevel * ptl)
3539 {
3540 /* profile idc: GST_H265_PROFILE_IDC_3D_MAIN */
3541 static H265ExtensionProfile profiles[] = {
3542 {GST_H265_PROFILE_3D_MAIN,
3543 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3544 };
3545
3546 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3547 }
3548
3549 static GstH265Profile
get_multiview_profile(const GstH265ProfileTierLevel * ptl)3550 get_multiview_profile (const GstH265ProfileTierLevel * ptl)
3551 {
3552 static H265ExtensionProfile profiles[] = {
3553 {GST_H265_PROFILE_MULTIVIEW_MAIN,
3554 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3555 };
3556
3557 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3558 }
3559
3560 static GstH265Profile
get_scalable_profile(const GstH265ProfileTierLevel * ptl)3561 get_scalable_profile (const GstH265ProfileTierLevel * ptl)
3562 {
3563 static H265ExtensionProfile profiles[] = {
3564 {GST_H265_PROFILE_SCALABLE_MAIN,
3565 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3566 {GST_H265_PROFILE_SCALABLE_MAIN_10,
3567 0, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3568 };
3569
3570 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3571 }
3572
3573 static GstH265Profile
get_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3574 get_high_throughput_profile (const GstH265ProfileTierLevel * ptl)
3575 {
3576 static H265ExtensionProfile profiles[] = {
3577 {GST_H265_PROFILE_HIGH_THROUGHPUT_444,
3578 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3579 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10,
3580 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3581 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14,
3582 1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3583 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
3584 0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 3},
3585 };
3586
3587 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3588 }
3589
3590 static GstH265Profile
get_screen_content_coding_extensions_profile(const GstH265ProfileTierLevel * ptl)3591 get_screen_content_coding_extensions_profile (const GstH265ProfileTierLevel *
3592 ptl)
3593 {
3594 static H265ExtensionProfile profiles[] = {
3595 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN,
3596 1, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3597 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10,
3598 1, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3599 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
3600 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 2},
3601 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10,
3602 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 3},
3603 };
3604
3605 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3606 }
3607
3608 static GstH265Profile
get_scalable_format_range_extensions_profile(const GstH265ProfileTierLevel * ptl)3609 get_scalable_format_range_extensions_profile (const GstH265ProfileTierLevel *
3610 ptl)
3611 {
3612 static H265ExtensionProfile profiles[] = {
3613 {GST_H265_PROFILE_SCALABLE_MONOCHROME,
3614 1, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3615 {GST_H265_PROFILE_SCALABLE_MONOCHROME_12,
3616 1, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 1},
3617 {GST_H265_PROFILE_SCALABLE_MONOCHROME_16,
3618 0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3619 {GST_H265_PROFILE_SCALABLE_MAIN_444,
3620 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 3},
3621 };
3622
3623 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3624 }
3625
3626 static GstH265Profile
get_screen_content_coding_extensions_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3627 get_screen_content_coding_extensions_high_throughput_profile
3628 (const GstH265ProfileTierLevel * ptl)
3629 {
3630 static H265ExtensionProfile profiles[] = {
3631 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
3632 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3633 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
3634 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3635 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
3636 1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3637 };
3638
3639 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3640 }
3641
3642 static inline void
append_profile(GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * idx,GstH265Profile profile)3643 append_profile (GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * idx,
3644 GstH265Profile profile)
3645 {
3646 if (profile == GST_H265_PROFILE_INVALID)
3647 return;
3648 profiles[*idx] = profile;
3649 (*idx)++;
3650 }
3651
3652 /* *INDENT-OFF* */
3653 struct h265_profiles_map
3654 {
3655 GstH265ProfileIDC profile_idc;
3656 GstH265Profile (*get_profile) (const GstH265ProfileTierLevel *);
3657 GstH265Profile profile;
3658 };
3659 /* *INDENT-ON* */
3660
3661 static const struct h265_profiles_map profiles_map[] = {
3662 /* keep profile check in asc order */
3663 {GST_H265_PROFILE_IDC_MAIN, NULL, GST_H265_PROFILE_MAIN},
3664 {GST_H265_PROFILE_IDC_MAIN_10, NULL, GST_H265_PROFILE_MAIN_10},
3665 {GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE, NULL,
3666 GST_H265_PROFILE_MAIN_STILL_PICTURE},
3667 {GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3668 get_format_range_extension_profile, GST_H265_PROFILE_INVALID},
3669 {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT, get_high_throughput_profile,
3670 GST_H265_PROFILE_INVALID},
3671 {GST_H265_PROFILE_IDC_MULTIVIEW_MAIN, get_multiview_profile,
3672 GST_H265_PROFILE_INVALID},
3673 {GST_H265_PROFILE_IDC_SCALABLE_MAIN, get_scalable_profile,
3674 GST_H265_PROFILE_INVALID},
3675 {GST_H265_PROFILE_IDC_3D_MAIN, get_3d_profile, GST_H265_PROFILE_INVALID},
3676 {GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3677 get_screen_content_coding_extensions_profile,
3678 GST_H265_PROFILE_INVALID},
3679 {GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3680 get_scalable_format_range_extensions_profile,
3681 GST_H265_PROFILE_INVALID},
3682 {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION,
3683 get_screen_content_coding_extensions_high_throughput_profile,
3684 GST_H265_PROFILE_INVALID},
3685 };
3686
3687 static void
gst_h265_profile_tier_level_get_profiles(const GstH265ProfileTierLevel * ptl,GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * len)3688 gst_h265_profile_tier_level_get_profiles (const GstH265ProfileTierLevel * ptl,
3689 GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * len)
3690 {
3691 guint i = 0, j;
3692
3693 /* First add profile idc */
3694 for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3695 if (ptl->profile_idc == profiles_map[j].profile_idc) {
3696 if (profiles_map[j].get_profile)
3697 append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3698 else
3699 profiles[i++] = profiles_map[j].profile;
3700 break;
3701 }
3702 }
3703
3704 /* Later add compatibility flags */
3705 for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3706 if (i > 0 && ptl->profile_idc == profiles_map[j].profile_idc)
3707 continue;
3708 if (ptl->profile_compatibility_flag[profiles_map[j].profile_idc]) {
3709 if (profiles_map[j].get_profile)
3710 append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3711 else
3712 profiles[i++] = profiles_map[j].profile;
3713 }
3714 }
3715
3716 *len = i;
3717 }
3718
3719 /**
3720 * gst_h265_profile_tier_level_get_profile:
3721 * @ptl: a #GstH265ProfileTierLevel
3722 *
3723 * Return the H265 profile defined in @ptl.
3724 *
3725 * Returns: a #GstH265Profile
3726 * Since: 1.14
3727 */
3728 GstH265Profile
gst_h265_profile_tier_level_get_profile(const GstH265ProfileTierLevel * ptl)3729 gst_h265_profile_tier_level_get_profile (const GstH265ProfileTierLevel * ptl)
3730 {
3731 guint len = 0;
3732 GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
3733
3734 gst_h265_profile_tier_level_get_profiles (ptl, profiles, &len);
3735
3736 if (len > 0)
3737 return profiles[0];
3738
3739 return GST_H265_PROFILE_INVALID;
3740 }
3741
3742 /**
3743 * gst_h265_profile_to_string:
3744 * @profile: a #GstH265Profile
3745 *
3746 * Returns the descriptive name for the #GstH265Profile.
3747 *
3748 * Returns: (nullable): the name for @profile or %NULL on error
3749 *
3750 * Since: 1.18
3751 */
3752 const gchar *
gst_h265_profile_to_string(GstH265Profile profile)3753 gst_h265_profile_to_string (GstH265Profile profile)
3754 {
3755 guint i;
3756
3757 if (profile == GST_H265_PROFILE_INVALID || profile == GST_H265_PROFILE_MAX)
3758 return NULL;
3759
3760 for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3761 if (profile == h265_profiles[i].profile)
3762 return h265_profiles[i].name;
3763 }
3764
3765 return NULL;
3766 }
3767
3768 /**
3769 * gst_h265_profile_from_string:
3770 * @string: the descriptive name for #GstH265Profile
3771 *
3772 * Returns a #GstH265Profile for the @string.
3773 *
3774 * Returns: the #GstH265Profile of @string or %GST_H265_PROFILE_INVALID on error
3775 *
3776 * Since: 1.18
3777 */
3778 GstH265Profile
gst_h265_profile_from_string(const gchar * string)3779 gst_h265_profile_from_string (const gchar * string)
3780 {
3781 guint i;
3782
3783 if (string == NULL)
3784 return GST_H265_PROFILE_INVALID;
3785
3786 for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3787 if (g_strcmp0 (string, h265_profiles[i].name) == 0) {
3788 return h265_profiles[i].profile;
3789 }
3790 }
3791
3792 return GST_H265_PROFILE_INVALID;
3793 }
3794
3795 static gboolean
gst_h265_write_sei_registered_user_data(NalWriter * nw,GstH265RegisteredUserData * rud)3796 gst_h265_write_sei_registered_user_data (NalWriter * nw,
3797 GstH265RegisteredUserData * rud)
3798 {
3799 WRITE_UINT8 (nw, rud->country_code, 8);
3800 if (rud->country_code == 0xff)
3801 WRITE_UINT8 (nw, rud->country_code_extension, 8);
3802
3803 WRITE_BYTES (nw, rud->data, rud->size);
3804
3805 return TRUE;
3806
3807 error:
3808 return FALSE;
3809 }
3810
3811 static gboolean
gst_h265_write_sei_time_code(NalWriter * nw,GstH265TimeCode * tc)3812 gst_h265_write_sei_time_code (NalWriter * nw, GstH265TimeCode * tc)
3813 {
3814 gint i;
3815
3816 WRITE_UINT8 (nw, tc->num_clock_ts, 2);
3817
3818 for (i = 0; i < tc->num_clock_ts; i++) {
3819 WRITE_UINT8 (nw, tc->clock_timestamp_flag[i], 1);
3820 if (tc->clock_timestamp_flag[i]) {
3821 WRITE_UINT8 (nw, tc->units_field_based_flag[i], 1);
3822 WRITE_UINT8 (nw, tc->counting_type[i], 5);
3823 WRITE_UINT8 (nw, tc->full_timestamp_flag[i], 1);
3824 WRITE_UINT8 (nw, tc->discontinuity_flag[i], 1);
3825 WRITE_UINT8 (nw, tc->cnt_dropped_flag[i], 1);
3826 WRITE_UINT16 (nw, tc->n_frames[i], 9);
3827
3828 if (tc->full_timestamp_flag[i]) {
3829 WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3830 WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3831 WRITE_UINT8 (nw, tc->hours_value[i], 5);
3832 } else {
3833 WRITE_UINT8 (nw, tc->seconds_flag[i], 1);
3834 if (tc->seconds_flag[i]) {
3835 WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3836 WRITE_UINT8 (nw, tc->minutes_flag[i], 1);
3837 if (tc->minutes_flag[i]) {
3838 WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3839 WRITE_UINT8 (nw, tc->hours_flag[i], 1);
3840 if (tc->hours_flag[i]) {
3841 WRITE_UINT8 (nw, tc->hours_value[i], 5);
3842 }
3843 }
3844 }
3845 }
3846 }
3847
3848 WRITE_UINT8 (nw, tc->time_offset_length[i], 5);
3849
3850 if (tc->time_offset_length[i] > 0)
3851 WRITE_UINT8 (nw, tc->time_offset_value[i], tc->time_offset_length[i]);
3852 }
3853
3854 return TRUE;
3855
3856 error:
3857 return FALSE;
3858 }
3859
3860 static gboolean
gst_h265_write_sei_mastering_display_colour_volume(NalWriter * nw,GstH265MasteringDisplayColourVolume * mdcv)3861 gst_h265_write_sei_mastering_display_colour_volume (NalWriter * nw,
3862 GstH265MasteringDisplayColourVolume * mdcv)
3863 {
3864 gint i;
3865
3866 for (i = 0; i < 3; i++) {
3867 WRITE_UINT16 (nw, mdcv->display_primaries_x[i], 16);
3868 WRITE_UINT16 (nw, mdcv->display_primaries_y[i], 16);
3869 }
3870
3871 WRITE_UINT16 (nw, mdcv->white_point_x, 16);
3872 WRITE_UINT16 (nw, mdcv->white_point_y, 16);
3873 WRITE_UINT32 (nw, mdcv->max_display_mastering_luminance, 32);
3874 WRITE_UINT32 (nw, mdcv->min_display_mastering_luminance, 32);
3875
3876 return TRUE;
3877
3878 error:
3879 return FALSE;
3880 }
3881
3882 static gboolean
gst_h265_write_sei_content_light_level_info(NalWriter * nw,GstH265ContentLightLevel * cll)3883 gst_h265_write_sei_content_light_level_info (NalWriter * nw,
3884 GstH265ContentLightLevel * cll)
3885 {
3886 WRITE_UINT16 (nw, cll->max_content_light_level, 16);
3887 WRITE_UINT16 (nw, cll->max_pic_average_light_level, 16);
3888
3889 return TRUE;
3890
3891 error:
3892 return FALSE;
3893 }
3894
3895 static GstMemory *
gst_h265_create_sei_memory_internal(guint8 layer_id,guint8 temporal_id_plus1,guint nal_prefix_size,gboolean packetized,GArray * messages)3896 gst_h265_create_sei_memory_internal (guint8 layer_id, guint8 temporal_id_plus1,
3897 guint nal_prefix_size, gboolean packetized, GArray * messages)
3898 {
3899 NalWriter nw;
3900 gint i;
3901 gboolean have_written_data = FALSE;
3902
3903 nal_writer_init (&nw, nal_prefix_size, packetized);
3904
3905 if (messages->len == 0)
3906 goto error;
3907
3908 GST_DEBUG ("Create SEI nal from array, len: %d", messages->len);
3909
3910 /* nal header */
3911 /* forbidden_zero_bit */
3912 WRITE_UINT8 (&nw, 0, 1);
3913 /* nal_unit_type */
3914 WRITE_UINT8 (&nw, GST_H265_NAL_PREFIX_SEI, 6);
3915 /* nuh_layer_id */
3916 WRITE_UINT8 (&nw, layer_id, 6);
3917 /* nuh_temporal_id_plus1 */
3918 WRITE_UINT8 (&nw, temporal_id_plus1, 3);
3919
3920 for (i = 0; i < messages->len; i++) {
3921 GstH265SEIMessage *msg = &g_array_index (messages, GstH265SEIMessage, i);
3922 guint32 payload_size_data = 0;
3923 guint32 payload_size_in_bits = 0;
3924 guint32 payload_type_data = msg->payloadType;
3925 gboolean need_align = FALSE;
3926
3927 switch (payload_type_data) {
3928 case GST_H265_SEI_REGISTERED_USER_DATA:{
3929 GstH265RegisteredUserData *rud = &msg->payload.registered_user_data;
3930
3931 /* itu_t_t35_country_code: 8 bits */
3932 payload_size_data = 1;
3933 if (rud->country_code == 0xff) {
3934 /* itu_t_t35_country_code_extension_byte */
3935 payload_size_data++;
3936 }
3937
3938 payload_size_data += rud->size;
3939 break;
3940 }
3941 case GST_H265_SEI_TIME_CODE:{
3942 gint j;
3943 GstH265TimeCode *tc = &msg->payload.time_code;
3944 /* num_clock_ts: 2 bits */
3945 payload_size_in_bits = 2;
3946 for (j = 0; j < tc->num_clock_ts; j++) {
3947 /* clock_timestamp_flag: 1 bit */
3948 payload_size_in_bits += 1;
3949
3950 if (tc->clock_timestamp_flag[j]) {
3951 /* units_field_based_flag: 1 bit
3952 * counting_type: 5 bits
3953 * full_timestamp_flag: 1 bit
3954 * discontinuity_flag: 1 bit
3955 * cnt_dropped_flag: 1 bit
3956 * n_frames: 9 bit
3957 */
3958 payload_size_in_bits += 18;
3959
3960 if (tc->full_timestamp_flag[j]) {
3961 /* seconds_value: 6 bits
3962 * minutes_value: 6 bits
3963 * hours_value: 5 bits
3964 */
3965 payload_size_in_bits += 17;
3966 } else {
3967 /* seconds_flag: 1 bit */
3968 payload_size_in_bits += 1;
3969
3970 if (tc->seconds_flag[j]) {
3971 /* seconds_value: 6 bits
3972 * minutes_flag: 1 bit
3973 */
3974 payload_size_in_bits += 7;
3975
3976 if (tc->minutes_flag[j]) {
3977 /* minutes_value: 6 bits
3978 * hours_flag: 1 bit
3979 */
3980 payload_size_in_bits += 7;
3981 if (tc->hours_flag[j]) {
3982 /* hours_value: 5 bits */
3983 payload_size_in_bits += 5;
3984 }
3985 }
3986 }
3987 }
3988
3989 /* time_offset_length: 5bits
3990 * time_offset_value: time_offset_length bits
3991 */
3992 payload_size_in_bits += (5 + tc->time_offset_length[j]);
3993 }
3994 }
3995
3996 payload_size_data = payload_size_in_bits >> 3;
3997
3998 if ((payload_size_in_bits & 0x7) != 0) {
3999 GST_INFO ("Bits for Time Code SEI is not byte aligned");
4000 payload_size_data++;
4001 need_align = TRUE;
4002 }
4003 break;
4004 }
4005 case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4006 /* x, y 16 bits per RGB channel
4007 * x, y 16 bits white point
4008 * max, min luminance 32 bits
4009 *
4010 * (2 * 2 * 3) + (2 * 2) + (4 * 2) = 24 bytes
4011 */
4012 payload_size_data = 24;
4013 break;
4014 case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4015 /* maxCLL and maxFALL per 16 bits
4016 *
4017 * 2 * 2 = 4 bytes
4018 */
4019 payload_size_data = 4;
4020 break;
4021 default:
4022 break;
4023 }
4024
4025 if (payload_size_data == 0) {
4026 GST_FIXME ("Unsupported SEI type %d", msg->payloadType);
4027 continue;
4028 }
4029
4030 /* write payload type bytes */
4031 while (payload_type_data >= 0xff) {
4032 WRITE_UINT8 (&nw, 0xff, 8);
4033 payload_type_data -= 0xff;
4034 }
4035 WRITE_UINT8 (&nw, payload_type_data, 8);
4036
4037 /* write payload size bytes */
4038 while (payload_size_data >= 0xff) {
4039 WRITE_UINT8 (&nw, 0xff, 8);
4040 payload_size_data -= 0xff;
4041 }
4042 WRITE_UINT8 (&nw, payload_size_data, 8);
4043
4044 switch (msg->payloadType) {
4045 case GST_H265_SEI_REGISTERED_USER_DATA:
4046 GST_DEBUG ("Writing \"Registered user data\" done");
4047 if (!gst_h265_write_sei_registered_user_data (&nw,
4048 &msg->payload.registered_user_data)) {
4049 GST_WARNING ("Failed to write \"Registered user data\"");
4050 goto error;
4051 }
4052 have_written_data = TRUE;
4053 break;
4054 case GST_H265_SEI_TIME_CODE:
4055 GST_DEBUG ("Wrtiting \"Time code\"");
4056 if (!gst_h265_write_sei_time_code (&nw, &msg->payload.time_code)) {
4057 GST_WARNING ("Failed to write \"Time code\"");
4058 goto error;
4059 }
4060 have_written_data = TRUE;
4061 break;
4062 case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4063 GST_DEBUG ("Wrtiting \"Mastering display colour volume\"");
4064 if (!gst_h265_write_sei_mastering_display_colour_volume (&nw,
4065 &msg->payload.mastering_display_colour_volume)) {
4066 GST_WARNING ("Failed to write \"Mastering display colour volume\"");
4067 goto error;
4068 }
4069 have_written_data = TRUE;
4070 break;
4071 case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4072 GST_DEBUG ("Writing \"Content light level\" done");
4073 if (!gst_h265_write_sei_content_light_level_info (&nw,
4074 &msg->payload.content_light_level)) {
4075 GST_WARNING ("Failed to write \"Content light level\"");
4076 goto error;
4077 }
4078 have_written_data = TRUE;
4079 break;
4080 default:
4081 break;
4082 }
4083
4084 if (need_align && !nal_writer_do_rbsp_trailing_bits (&nw)) {
4085 GST_WARNING ("Cannot insert traling bits");
4086 goto error;
4087 }
4088 }
4089
4090 if (!have_written_data) {
4091 GST_WARNING ("No written sei data");
4092 goto error;
4093 }
4094
4095 if (!nal_writer_do_rbsp_trailing_bits (&nw)) {
4096 GST_WARNING ("Failed to insert rbsp trailing bits");
4097 goto error;
4098 }
4099
4100 return nal_writer_reset_and_get_memory (&nw);
4101
4102 error:
4103 nal_writer_reset (&nw);
4104
4105 return NULL;
4106 }
4107
4108 /**
4109 * gst_h265_create_sei_memory:
4110 * @layer_id: a nal unit layer id
4111 * @temporal_id_plus1: a nal unit temporal identifier
4112 * @start_code_prefix_length: a length of start code prefix, must be 3 or 4
4113 * @messages: (transfer none): a GArray of #GstH265SEIMessage
4114 *
4115 * Creates raw byte-stream format (a.k.a Annex B type) SEI nal unit data
4116 * from @messages
4117 *
4118 * Returns: a #GstMemory containing a PREFIX SEI nal unit
4119 *
4120 * Since: 1.18
4121 */
4122 GstMemory *
gst_h265_create_sei_memory(guint8 layer_id,guint8 temporal_id_plus1,guint8 start_code_prefix_length,GArray * messages)4123 gst_h265_create_sei_memory (guint8 layer_id, guint8 temporal_id_plus1,
4124 guint8 start_code_prefix_length, GArray * messages)
4125 {
4126 g_return_val_if_fail (start_code_prefix_length == 3
4127 || start_code_prefix_length == 4, NULL);
4128 g_return_val_if_fail (messages != NULL, NULL);
4129 g_return_val_if_fail (messages->len > 0, NULL);
4130
4131 return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4132 start_code_prefix_length, FALSE, messages);
4133 }
4134
4135 /**
4136 * gst_h265_create_sei_memory_hevc:
4137 * @layer_id: a nal unit layer id
4138 * @temporal_id_plus1: a nal unit temporal identifier
4139 * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4140 * @messages: (transfer none): a GArray of #GstH265SEIMessage
4141 *
4142 * Creates raw packetized format SEI nal unit data from @messages
4143 *
4144 * Returns: a #GstMemory containing a PREFIX SEI nal unit
4145 *
4146 * Since: 1.18
4147 */
4148 GstMemory *
gst_h265_create_sei_memory_hevc(guint8 layer_id,guint8 temporal_id_plus1,guint8 nal_length_size,GArray * messages)4149 gst_h265_create_sei_memory_hevc (guint8 layer_id, guint8 temporal_id_plus1,
4150 guint8 nal_length_size, GArray * messages)
4151 {
4152 return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4153 nal_length_size, TRUE, messages);
4154 }
4155
4156 static GstBuffer *
gst_h265_parser_insert_sei_internal(GstH265Parser * parser,guint8 nal_prefix_size,gboolean packetized,GstBuffer * au,GstMemory * sei)4157 gst_h265_parser_insert_sei_internal (GstH265Parser * parser,
4158 guint8 nal_prefix_size, gboolean packetized, GstBuffer * au,
4159 GstMemory * sei)
4160 {
4161 GstH265NalUnit nalu;
4162 GstH265NalUnit sei_nalu;
4163 GstMapInfo info;
4164 GstMapInfo sei_info;
4165 GstH265ParserResult pres;
4166 guint offset = 0;
4167 GstBuffer *new_buffer = NULL;
4168 GstMemory *new_mem = NULL;
4169
4170 /* all SEI payload types supported by us need to have the identical
4171 * temporal id to that of slice. Parse SEI first and we will
4172 * update it if it's required */
4173 if (!gst_memory_map (sei, &sei_info, GST_MAP_READ)) {
4174 GST_ERROR ("Cannot map sei memory");
4175 return NULL;
4176 }
4177
4178 if (packetized) {
4179 pres = gst_h265_parser_identify_nalu_hevc (parser,
4180 sei_info.data, 0, sei_info.size, nal_prefix_size, &sei_nalu);
4181 } else {
4182 pres = gst_h265_parser_identify_nalu (parser,
4183 sei_info.data, 0, sei_info.size, &sei_nalu);
4184 }
4185 gst_memory_unmap (sei, &sei_info);
4186 if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4187 GST_DEBUG ("Failed to identify sei nal unit, ret: %d", pres);
4188 return NULL;
4189 }
4190
4191 if (!gst_buffer_map (au, &info, GST_MAP_READ)) {
4192 GST_ERROR ("Cannot map au buffer");
4193 return NULL;
4194 }
4195
4196 /* Find the offset of the first slice */
4197 do {
4198 if (packetized) {
4199 pres = gst_h265_parser_identify_nalu_hevc (parser,
4200 info.data, offset, info.size, nal_prefix_size, &nalu);
4201 } else {
4202 pres = gst_h265_parser_identify_nalu (parser,
4203 info.data, offset, info.size, &nalu);
4204 }
4205
4206 if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4207 GST_DEBUG ("Failed to identify nal unit, ret: %d", pres);
4208 gst_buffer_unmap (au, &info);
4209
4210 return NULL;
4211 }
4212
4213 if (nalu.type <= GST_H265_NAL_SLICE_RASL_R
4214 || (nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP
4215 && nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)) {
4216 GST_DEBUG ("Found slice nal type %d at offset %d", nalu.type,
4217 nalu.sc_offset);
4218 break;
4219 }
4220
4221 offset = nalu.offset + nalu.size;
4222 } while (pres == GST_H265_PARSER_OK);
4223 gst_buffer_unmap (au, &info);
4224
4225 /* found the best position now, create new buffer */
4226 new_buffer = gst_buffer_new ();
4227
4228 /* copy all metadata */
4229 if (!gst_buffer_copy_into (new_buffer, au, GST_BUFFER_COPY_METADATA, 0, -1)) {
4230 GST_ERROR ("Failed to copy metadata into new buffer");
4231 gst_clear_buffer (&new_buffer);
4232 goto out;
4233 }
4234
4235 /* copy non-slice nal */
4236 if (nalu.sc_offset > 0) {
4237 if (!gst_buffer_copy_into (new_buffer, au,
4238 GST_BUFFER_COPY_MEMORY, 0, nalu.sc_offset)) {
4239 GST_ERROR ("Failed to copy buffer");
4240 gst_clear_buffer (&new_buffer);
4241 goto out;
4242 }
4243 }
4244
4245 /* check whether we need to update temporal id and layer id.
4246 * If it's not matched to slice nalu, update it.
4247 */
4248 if (sei_nalu.layer_id != nalu.layer_id || sei_nalu.temporal_id_plus1 !=
4249 nalu.temporal_id_plus1) {
4250 guint16 nalu_header;
4251 guint16 layer_id_temporal_id = 0;
4252 new_mem = gst_memory_copy (sei, 0, -1);
4253
4254 if (!gst_memory_map (new_mem, &sei_info, GST_MAP_READWRITE)) {
4255 GST_ERROR ("Failed to map new sei memory");
4256 gst_memory_unref (new_mem);
4257 gst_clear_buffer (&new_buffer);
4258 goto out;
4259 }
4260
4261 nalu_header = GST_READ_UINT16_BE (sei_info.data + sei_nalu.offset);
4262
4263 /* clear bits 7 ~ 15
4264 * NOTE:
4265 * bit 0: forbidden_zero_bit
4266 * bits 1 ~ 6: nalu type */
4267 nalu_header &= 0xfe00;
4268
4269 layer_id_temporal_id = ((nalu.layer_id << 3) & 0x1f8);
4270 layer_id_temporal_id |= (nalu.temporal_id_plus1 & 0x7);
4271
4272 nalu_header |= layer_id_temporal_id;
4273 GST_WRITE_UINT16_BE (sei_info.data + sei_nalu.offset, nalu_header);
4274 gst_memory_unmap (new_mem, &sei_info);
4275 } else {
4276 new_mem = gst_memory_ref (sei);
4277 }
4278
4279 /* insert sei */
4280 gst_buffer_append_memory (new_buffer, new_mem);
4281
4282 /* copy the rest */
4283 if (!gst_buffer_copy_into (new_buffer, au,
4284 GST_BUFFER_COPY_MEMORY, nalu.sc_offset, -1)) {
4285 GST_ERROR ("Failed to copy buffer");
4286 gst_clear_buffer (&new_buffer);
4287 goto out;
4288 }
4289
4290 out:
4291 return new_buffer;
4292 }
4293
4294 /**
4295 * gst_h265_parser_insert_sei:
4296 * @parser: a #GstH265Parser
4297 * @au: (transfer none): a #GstBuffer containing AU data
4298 * @sei: (transfer none): a #GstMemory containing a SEI nal
4299 *
4300 * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4301 * The validation for completeness of @au and @sei is caller's responsibility.
4302 * Both @au and @sei must be byte-stream formatted
4303 *
4304 * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4305 * if cannot figure out proper position to insert a @sei
4306 *
4307 * Since: 1.18
4308 */
4309 GstBuffer *
gst_h265_parser_insert_sei(GstH265Parser * parser,GstBuffer * au,GstMemory * sei)4310 gst_h265_parser_insert_sei (GstH265Parser * parser, GstBuffer * au,
4311 GstMemory * sei)
4312 {
4313 g_return_val_if_fail (parser != NULL, NULL);
4314 g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4315 g_return_val_if_fail (sei != NULL, NULL);
4316
4317 /* the size of start code prefix (3 or 4) is not matter since it will be
4318 * scanned */
4319 return gst_h265_parser_insert_sei_internal (parser, 4, FALSE, au, sei);
4320 }
4321
4322 /**
4323 * gst_h265_parser_insert_sei_hevc:
4324 * @parser: a #GstH265Parser
4325 * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4326 * @au: (transfer none): a #GstBuffer containing AU data
4327 * @sei: (transfer none): a #GstMemory containing a SEI nal
4328 *
4329 * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4330 * The validation for completeness of @au and @sei is caller's responsibility.
4331 * Nal prefix type of both @au and @sei must be packetized, and
4332 * also the size of nal length field must be identical to @nal_length_size
4333 *
4334 * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4335 * if cannot figure out proper position to insert a @sei
4336 *
4337 * Since: 1.18
4338 */
4339 GstBuffer *
gst_h265_parser_insert_sei_hevc(GstH265Parser * parser,guint8 nal_length_size,GstBuffer * au,GstMemory * sei)4340 gst_h265_parser_insert_sei_hevc (GstH265Parser * parser, guint8 nal_length_size,
4341 GstBuffer * au, GstMemory * sei)
4342 {
4343 g_return_val_if_fail (parser != NULL, NULL);
4344 g_return_val_if_fail (nal_length_size > 0 && nal_length_size < 5, NULL);
4345 g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4346 g_return_val_if_fail (sei != NULL, NULL);
4347
4348 return gst_h265_parser_insert_sei_internal (parser, nal_length_size, TRUE,
4349 au, sei);
4350 }
4351
4352 /**
4353 * gst_h265_get_profile_from_sps:
4354 * @sps: a #GstH265SPS
4355 *
4356 * Return the H265 profile from @sps.
4357 *
4358 * Returns: a #GstH265Profile
4359 * Since: 1.20
4360 */
4361 GstH265Profile
gst_h265_get_profile_from_sps(GstH265SPS * sps)4362 gst_h265_get_profile_from_sps (GstH265SPS * sps)
4363 {
4364 GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
4365 GstH265ProfileTierLevel tmp_ptl;
4366 guint i, len = 0;
4367 guint chroma_format_idc, bit_depth_luma, bit_depth_chroma;
4368
4369 g_return_val_if_fail (sps != NULL, GST_H265_PROFILE_INVALID);
4370
4371 tmp_ptl = sps->profile_tier_level;
4372 chroma_format_idc = sps->chroma_format_idc;
4373 bit_depth_luma = sps->bit_depth_luma_minus8 + 8;
4374 bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
4375
4376 gst_h265_profile_tier_level_get_profiles (&sps->profile_tier_level, profiles,
4377 &len);
4378
4379 for (i = 0; i < len && i < G_N_ELEMENTS (profiles); i++) {
4380 switch (profiles[i]) {
4381 case GST_H265_PROFILE_INVALID:
4382 break;
4383 case GST_H265_PROFILE_MAIN:
4384 case GST_H265_PROFILE_MAIN_STILL_PICTURE:
4385 /* A.3.2 or A.3.5 */
4386 if (chroma_format_idc == 1
4387 && bit_depth_luma == 8 && bit_depth_chroma == 8)
4388 return profiles[i];
4389 break;
4390 case GST_H265_PROFILE_MAIN_10:
4391 /* A.3.3 */
4392 if (chroma_format_idc == 1
4393 && bit_depth_luma >= 8 && bit_depth_luma <= 10
4394 && bit_depth_chroma >= 8 && bit_depth_chroma <= 10)
4395 return profiles[i];
4396 break;
4397 default:
4398 return profiles[i];
4399 }
4400 }
4401
4402 /* Invalid profile: */
4403 /* Set the conformance indicators based on chroma_format_idc / bit_depth */
4404 switch (chroma_format_idc) {
4405 case 0:
4406 tmp_ptl.max_monochrome_constraint_flag = 1;
4407 tmp_ptl.max_420chroma_constraint_flag = 1;
4408 tmp_ptl.max_422chroma_constraint_flag = 1;
4409 break;
4410
4411 case 1:
4412 tmp_ptl.max_monochrome_constraint_flag = 0;
4413 tmp_ptl.max_420chroma_constraint_flag = 1;
4414 tmp_ptl.max_422chroma_constraint_flag = 1;
4415 break;
4416
4417 case 2:
4418 tmp_ptl.max_monochrome_constraint_flag = 0;
4419 tmp_ptl.max_420chroma_constraint_flag = 0;
4420 tmp_ptl.max_422chroma_constraint_flag = 1;
4421 break;
4422
4423 case 3:
4424 tmp_ptl.max_monochrome_constraint_flag = 0;
4425 tmp_ptl.max_420chroma_constraint_flag = 0;
4426 tmp_ptl.max_422chroma_constraint_flag = 0;
4427 break;
4428
4429 default:
4430 g_assert_not_reached ();
4431 break;
4432 }
4433
4434 tmp_ptl.max_8bit_constraint_flag = 1;
4435 tmp_ptl.max_10bit_constraint_flag = 1;
4436 tmp_ptl.max_12bit_constraint_flag = 1;
4437 tmp_ptl.max_14bit_constraint_flag = 1;
4438
4439 if (bit_depth_luma > 8 || bit_depth_chroma > 8)
4440 tmp_ptl.max_8bit_constraint_flag = 0;
4441
4442 if (bit_depth_luma > 10 || bit_depth_chroma > 10)
4443 tmp_ptl.max_10bit_constraint_flag = 0;
4444
4445 if (bit_depth_luma > 12 || bit_depth_chroma > 12)
4446 tmp_ptl.max_12bit_constraint_flag = 0;
4447
4448 if (tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
4449 || tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
4450 || tmp_ptl.profile_idc ==
4451 GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION
4452 || tmp_ptl.profile_idc ==
4453 GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION
4454 || tmp_ptl.profile_compatibility_flag[5]
4455 || tmp_ptl.profile_compatibility_flag[9]
4456 || tmp_ptl.profile_compatibility_flag[10]
4457 || tmp_ptl.profile_compatibility_flag[11]) {
4458 if (bit_depth_luma > 14 || bit_depth_chroma > 14)
4459 tmp_ptl.max_14bit_constraint_flag = 0;
4460 } else {
4461 tmp_ptl.max_14bit_constraint_flag = 0;
4462 }
4463
4464 /* first profile of the synthetic ptl */
4465 return gst_h265_profile_tier_level_get_profile (&tmp_ptl);
4466 }
4467