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 READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1674
1675 /* skip reserved_0xffff_16bits */
1676 if (!nal_reader_skip (&nr, 16))
1677 goto error;
1678
1679 if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1680 vps->max_sub_layers_minus1))
1681 goto error;
1682
1683 READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1684
1685 for (i =
1686 (vps->sub_layer_ordering_info_present_flag ? 0 :
1687 vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1688 READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1689 READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1690 vps->max_dec_pic_buffering_minus1[i]);
1691 READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1692 }
1693 /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1694 if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1695 for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1696 vps->max_dec_pic_buffering_minus1[i] =
1697 vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1698 vps->max_num_reorder_pics[i] =
1699 vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1700 vps->max_latency_increase_plus1[i] =
1701 vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1702 }
1703 }
1704
1705 READ_UINT8 (&nr, vps->max_layer_id, 6);
1706 /* shall allow 63 */
1707 CHECK_ALLOWED_MAX (vps->max_layer_id, 63);
1708
1709 READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1710 /* allowed range is 0 to 1023 */
1711 CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 1023);
1712
1713 for (i = 1; i <= vps->num_layer_sets_minus1; i++) {
1714 for (j = 0; j <= vps->max_layer_id; j++) {
1715 /* layer_id_included_flag[i][j] */
1716 /* FIXME: need to parse this when we can support parsing multi-layer info. */
1717 nal_reader_skip (&nr, 1);
1718 }
1719 }
1720
1721 READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1722
1723 if (vps->timing_info_present_flag) {
1724 READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1725 READ_UINT32 (&nr, vps->time_scale, 32);
1726 READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1727
1728 if (vps->poc_proportional_to_timing_flag)
1729 READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1730
1731 READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1732 /* allowed range is
1733 * 0 to vps_num_layer_sets_minus1 + 1 */
1734 CHECK_ALLOWED_MAX (vps->num_hrd_parameters, vps->num_layer_sets_minus1 + 1);
1735
1736 if (vps->num_hrd_parameters) {
1737 READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1738 /* allowed range is
1739 * ( vps_base_layer_internal_flag ? 0 : 1 ) to vps_num_layer_sets_minus1
1740 */
1741 CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, vps->num_layer_sets_minus1);
1742
1743 if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1744 vps->cprms_present_flag, vps->max_sub_layers_minus1))
1745 goto error;
1746 }
1747
1748 /* FIXME: VPS can have multiple hrd parameters, and therefore hrd_params
1749 * should be an array (like Garray). But it also requires new _clear()
1750 * method for free the array in GstH265VPS whenever gst_h265_parse_vps()
1751 * is called. Need to work for multi-layer related parsing supporting
1752 *
1753 * FIXME: Following code is just work around to find correct
1754 * vps_extension position */
1755
1756 /* skip the first parsed one above */
1757 for (i = 1; i < vps->num_hrd_parameters; i++) {
1758 guint16 hrd_layer_set_idx;
1759 guint8 cprms_present_flag;
1760 GstH265HRDParams hrd_params;
1761
1762 READ_UE_MAX (&nr, hrd_layer_set_idx, 1023);
1763 CHECK_ALLOWED_MAX (hrd_layer_set_idx, vps->num_layer_sets_minus1);
1764
1765 /* need parsing if (i > 1) */
1766 READ_UINT8 (&nr, cprms_present_flag, 1);
1767
1768 if (!gst_h265_parse_hrd_parameters (&hrd_params, &nr,
1769 cprms_present_flag, vps->max_sub_layers_minus1))
1770 goto error;
1771 }
1772 }
1773 READ_UINT8 (&nr, vps->vps_extension, 1);
1774 vps->valid = TRUE;
1775
1776 return GST_H265_PARSER_OK;
1777
1778 error:
1779 GST_WARNING ("error parsing \"Video parameter set\"");
1780 vps->valid = FALSE;
1781 return GST_H265_PARSER_ERROR;
1782 }
1783
1784 /**
1785 * gst_h265_parser_parse_sps:
1786 * @parser: a #GstH265Parser
1787 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1788 * @sps: The #GstH265SPS to fill.
1789 * @parse_vui_params: Whether to parse the vui_params or not
1790 *
1791 * Parses @data, and fills the @sps structure.
1792 *
1793 * Returns: a #GstH265ParserResult
1794 */
1795 GstH265ParserResult
gst_h265_parser_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1796 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1797 GstH265SPS * sps, gboolean parse_vui_params)
1798 {
1799 GstH265ParserResult res =
1800 gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1801
1802 if (res == GST_H265_PARSER_OK) {
1803 GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1804
1805 parser->sps[sps->id] = *sps;
1806 parser->last_sps = &parser->sps[sps->id];
1807 }
1808
1809 return res;
1810 }
1811
1812 /**
1813 * gst_h265_parse_sps:
1814 * parser: The #GstH265Parser
1815 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1816 * @sps: The #GstH265SPS to fill.
1817 * @parse_vui_params: Whether to parse the vui_params or not
1818 *
1819 * Parses @data, and fills the @sps structure.
1820 *
1821 * Returns: a #GstH265ParserResult
1822 */
1823 GstH265ParserResult
gst_h265_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1824 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1825 GstH265SPS * sps, gboolean parse_vui_params)
1826 {
1827 NalReader nr;
1828 GstH265VPS *vps;
1829 guint8 vps_id;
1830 guint i;
1831 guint subwc[] = { 1, 2, 2, 1, 1 };
1832 guint subhc[] = { 1, 2, 1, 1, 1 };
1833 GstH265VUIParams *vui = NULL;
1834
1835 GST_DEBUG ("parsing SPS");
1836
1837 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1838 nalu->size - nalu->header_bytes);
1839
1840 memset (sps, 0, sizeof (*sps));
1841
1842 READ_UINT8 (&nr, vps_id, 4);
1843 vps = gst_h265_parser_get_vps (parser, vps_id);
1844 if (!vps) {
1845 GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1846 vps_id);
1847 }
1848 sps->vps = vps;
1849
1850 READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1851 READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1852
1853 if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1854 sps->max_sub_layers_minus1))
1855 goto error;
1856
1857 READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1858
1859 READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1860 if (sps->chroma_format_idc == 3)
1861 READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1862
1863 READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1864 READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1865
1866 READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1867 if (sps->conformance_window_flag) {
1868 READ_UE (&nr, sps->conf_win_left_offset);
1869 READ_UE (&nr, sps->conf_win_right_offset);
1870 READ_UE (&nr, sps->conf_win_top_offset);
1871 READ_UE (&nr, sps->conf_win_bottom_offset);
1872 }
1873
1874 READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1875 READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1876 READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1877
1878 READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1879 for (i =
1880 (sps->sub_layer_ordering_info_present_flag ? 0 :
1881 sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1882 READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1883 READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1884 sps->max_dec_pic_buffering_minus1[i]);
1885 READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1886 }
1887 /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1888 if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1889 for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1890 sps->max_dec_pic_buffering_minus1[i] =
1891 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1892 sps->max_num_reorder_pics[i] =
1893 sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1894 sps->max_latency_increase_plus1[i] =
1895 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1896 }
1897 }
1898
1899 /* The limits are calculted based on the profile_tier_level constraint
1900 * in Annex-A: CtbLog2SizeY = 4 to 6 */
1901 READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1902 READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1903 READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1904 READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1905 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1906 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1907
1908 READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1909 if (sps->scaling_list_enabled_flag) {
1910 READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1911
1912 if (sps->scaling_list_data_present_flag)
1913 if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1914 goto error;
1915 }
1916
1917 READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1918 READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1919 READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1920
1921 if (sps->pcm_enabled_flag) {
1922 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1923 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1924 READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1925 READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1926 READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1927 }
1928
1929 READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1930 for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1931 if (!gst_h265_parser_parse_short_term_ref_pic_sets
1932 (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1933 goto error;
1934
1935 READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1936 if (sps->long_term_ref_pics_present_flag) {
1937 READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1938 for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1939 READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1940 sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1941 READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1942 }
1943 }
1944
1945 READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1946 READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1947 READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1948
1949 if (sps->vui_parameters_present_flag && parse_vui_params) {
1950 if (!gst_h265_parse_vui_parameters (sps, &nr))
1951 goto error;
1952 vui = &sps->vui_params;
1953 }
1954
1955 READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1956
1957 if (sps->sps_extension_flag) {
1958 READ_UINT8 (&nr, sps->sps_range_extension_flag, 1);
1959 READ_UINT8 (&nr, sps->sps_multilayer_extension_flag, 1);
1960 READ_UINT8 (&nr, sps->sps_3d_extension_flag, 1);
1961 READ_UINT8 (&nr, sps->sps_scc_extension_flag, 1);
1962 READ_UINT8 (&nr, sps->sps_extension_4bits, 4);
1963 }
1964
1965 if (sps->sps_range_extension_flag) {
1966 READ_UINT8 (&nr,
1967 sps->sps_extnsion_params.transform_skip_rotation_enabled_flag, 1);
1968 READ_UINT8 (&nr,
1969 sps->sps_extnsion_params.transform_skip_context_enabled_flag, 1);
1970 READ_UINT8 (&nr, sps->sps_extnsion_params.implicit_rdpcm_enabled_flag, 1);
1971 READ_UINT8 (&nr, sps->sps_extnsion_params.explicit_rdpcm_enabled_flag, 1);
1972 READ_UINT8 (&nr,
1973 sps->sps_extnsion_params.extended_precision_processing_flag, 1);
1974 READ_UINT8 (&nr, sps->sps_extnsion_params.intra_smoothing_disabled_flag, 1);
1975 READ_UINT8 (&nr,
1976 sps->sps_extnsion_params.high_precision_offsets_enabled_flag, 1);
1977 READ_UINT8 (&nr,
1978 sps->sps_extnsion_params.persistent_rice_adaptation_enabled_flag, 1);
1979 READ_UINT8 (&nr,
1980 sps->sps_extnsion_params.cabac_bypass_alignment_enabled_flag, 1);
1981 }
1982
1983 if (sps->sps_multilayer_extension_flag) {
1984 GST_WARNING ("do not support multilayer extension, skip all"
1985 " remaining bits");
1986 goto done;
1987 }
1988 if (sps->sps_3d_extension_flag) {
1989 GST_WARNING ("do not support 3d extension, skip all remaining bits");
1990 goto done;
1991 }
1992
1993 if (sps->sps_scc_extension_flag) {
1994 READ_UINT8 (&nr,
1995 sps->sps_scc_extension_params.sps_curr_pic_ref_enabled_flag, 1);
1996 READ_UINT8 (&nr, sps->sps_scc_extension_params.palette_mode_enabled_flag,
1997 1);
1998 if (sps->sps_scc_extension_params.palette_mode_enabled_flag) {
1999 READ_UE_MAX (&nr, sps->sps_scc_extension_params.palette_max_size, 64);
2000 READ_UE_MAX (&nr,
2001 sps->sps_scc_extension_params.delta_palette_max_predictor_size,
2002 128 - sps->sps_scc_extension_params.palette_max_size);
2003
2004 READ_UINT8 (&nr,
2005 sps->sps_scc_extension_params.
2006 sps_palette_predictor_initializers_present_flag, 1);
2007 if (sps->sps_scc_extension_params.
2008 sps_palette_predictor_initializers_present_flag) {
2009 guint comp;
2010 READ_UE_MAX (&nr,
2011 sps->sps_scc_extension_params.
2012 sps_num_palette_predictor_initializer_minus1,
2013 sps->sps_scc_extension_params.palette_max_size +
2014 sps->sps_scc_extension_params.delta_palette_max_predictor_size - 1);
2015
2016 for (comp = 0; comp < (sps->chroma_format_idc == 0 ? 1 : 3); comp++) {
2017 guint num_bits;
2018 guint num =
2019 sps->sps_scc_extension_params.
2020 sps_num_palette_predictor_initializer_minus1 + 1;
2021
2022 num_bits = (comp == 0 ? sps->bit_depth_luma_minus8 + 8 :
2023 sps->bit_depth_chroma_minus8 + 8);
2024 for (i = 0; i < num; i++)
2025 READ_UINT32 (&nr,
2026 sps->sps_scc_extension_params.sps_palette_predictor_initializer
2027 [comp]
2028 [i], num_bits);
2029 }
2030 }
2031 }
2032
2033 READ_UINT8 (&nr,
2034 sps->sps_scc_extension_params.motion_vector_resolution_control_idc, 2);
2035 READ_UINT8 (&nr,
2036 sps->sps_scc_extension_params.intra_boundary_filtering_disabled_flag,
2037 1);
2038 }
2039
2040 done:
2041 /* calculate ChromaArrayType */
2042 if (!sps->separate_colour_plane_flag)
2043 sps->chroma_array_type = sps->chroma_format_idc;
2044
2045 /* Calculate width and height */
2046 sps->width = sps->pic_width_in_luma_samples;
2047 sps->height = sps->pic_height_in_luma_samples;
2048 if (sps->width < 0 || sps->height < 0) {
2049 GST_WARNING ("invalid width/height in SPS");
2050 goto error;
2051 }
2052
2053 if (sps->conformance_window_flag) {
2054 const guint crop_unit_x = subwc[sps->chroma_format_idc];
2055 const guint crop_unit_y = subhc[sps->chroma_format_idc];
2056
2057 sps->crop_rect_width = sps->width -
2058 (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
2059 sps->crop_rect_height = sps->height -
2060 (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
2061 sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
2062 sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
2063
2064 GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
2065 sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
2066 }
2067
2068 sps->fps_num = 0;
2069 sps->fps_den = 1;
2070
2071 if (vui && vui->timing_info_present_flag) {
2072 /* derive framerate for progressive stream if the pic_struct
2073 * syntax element is not present in picture timing SEI messages */
2074 /* Fixme: handle other cases also */
2075 if (parse_vui_params && vui->timing_info_present_flag
2076 && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
2077 sps->fps_num = vui->time_scale;
2078 sps->fps_den = vui->num_units_in_tick;
2079 GST_LOG ("framerate %d/%d in VUI", sps->fps_num, sps->fps_den);
2080 }
2081 } else if (vps && vps->timing_info_present_flag) {
2082 sps->fps_num = vps->time_scale;
2083 sps->fps_den = vps->num_units_in_tick;
2084 GST_LOG ("framerate %d/%d in VPS", sps->fps_num, sps->fps_den);
2085 } else {
2086 GST_LOG ("No VUI, unknown framerate");
2087 }
2088
2089 sps->valid = TRUE;
2090
2091 return GST_H265_PARSER_OK;
2092
2093 error:
2094 GST_WARNING ("error parsing \"Sequence parameter set\"");
2095 sps->valid = FALSE;
2096 return GST_H265_PARSER_ERROR;
2097 }
2098
2099 /**
2100 * gst_h265_parse_pps:
2101 * @parser: a #GstH265Parser
2102 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2103 * @pps: The #GstH265PPS to fill.
2104 *
2105 * Parses @data, and fills the @pps structure.
2106 *
2107 * Returns: a #GstH265ParserResult
2108 */
2109 GstH265ParserResult
gst_h265_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2110 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
2111 GstH265PPS * pps)
2112 {
2113 NalReader nr;
2114 GstH265SPS *sps;
2115 gint sps_id;
2116 gint qp_bd_offset;
2117 guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY, MaxBitDepthY, MaxBitDepthC;
2118 guint8 i;
2119
2120 GST_DEBUG ("parsing PPS");
2121
2122 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2123 nalu->size - nalu->header_bytes);
2124
2125 memset (pps, 0, sizeof (*pps));
2126
2127 READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
2128 READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
2129
2130 sps = gst_h265_parser_get_sps (parser, sps_id);
2131 if (!sps) {
2132 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
2133 sps_id);
2134 return GST_H265_PARSER_BROKEN_LINK;
2135 }
2136 pps->sps = sps;
2137 qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
2138
2139 MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
2140 CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
2141 CtbSizeY = 1 << CtbLog2SizeY;
2142 pps->PicHeightInCtbsY =
2143 ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
2144 pps->PicWidthInCtbsY =
2145 ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
2146
2147 /* set default values for fields that might not be present in the bitstream
2148 and have valid defaults */
2149 pps->uniform_spacing_flag = 1;
2150 pps->loop_filter_across_tiles_enabled_flag = 1;
2151
2152 READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
2153 READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
2154 READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
2155 READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
2156 READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
2157
2158 READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
2159 READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
2160 READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
2161
2162 READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
2163 READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
2164
2165 READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
2166 if (pps->cu_qp_delta_enabled_flag)
2167 READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
2168 sps->log2_diff_max_min_luma_coding_block_size);
2169
2170 READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
2171 READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
2172
2173 READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
2174 READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
2175 READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
2176 READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
2177 READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
2178 READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
2179
2180 if (pps->tiles_enabled_flag) {
2181 READ_UE_ALLOWED (&nr,
2182 pps->num_tile_columns_minus1, 0, pps->PicWidthInCtbsY - 1);
2183 READ_UE_ALLOWED (&nr,
2184 pps->num_tile_rows_minus1, 0, pps->PicHeightInCtbsY - 1);
2185
2186 if (pps->num_tile_columns_minus1 + 1 >
2187 G_N_ELEMENTS (pps->column_width_minus1)) {
2188 GST_WARNING ("Invalid \"num_tile_columns_minus1\" %d",
2189 pps->num_tile_columns_minus1);
2190 goto error;
2191 }
2192
2193 if (pps->num_tile_rows_minus1 + 1 > G_N_ELEMENTS (pps->row_height_minus1)) {
2194 GST_WARNING ("Invalid \"num_tile_rows_minus1\" %d",
2195 pps->num_tile_rows_minus1);
2196 goto error;
2197 }
2198
2199 READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
2200 /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
2201 if (pps->uniform_spacing_flag) {
2202 guint8 num_col = pps->num_tile_columns_minus1 + 1;
2203 guint8 num_row = pps->num_tile_rows_minus1 + 1;
2204 for (i = 0; i < num_col; i++) {
2205 pps->column_width_minus1[i] =
2206 ((i + 1) * pps->PicWidthInCtbsY / num_col
2207 - i * pps->PicWidthInCtbsY / num_col) - 1;
2208 }
2209 for (i = 0; i < num_row; i++) {
2210 pps->row_height_minus1[i] =
2211 ((i + 1) * pps->PicHeightInCtbsY / num_row
2212 - i * pps->PicHeightInCtbsY / num_row) - 1;
2213 }
2214 } else {
2215 pps->column_width_minus1[pps->num_tile_columns_minus1] =
2216 pps->PicWidthInCtbsY - 1;
2217 for (i = 0; i < pps->num_tile_columns_minus1; i++) {
2218 READ_UE (&nr, pps->column_width_minus1[i]);
2219 pps->column_width_minus1[pps->num_tile_columns_minus1] -=
2220 (pps->column_width_minus1[i] + 1);
2221 }
2222
2223 pps->row_height_minus1[pps->num_tile_rows_minus1] =
2224 pps->PicHeightInCtbsY - 1;
2225 for (i = 0; i < pps->num_tile_rows_minus1; i++) {
2226 READ_UE (&nr, pps->row_height_minus1[i]);
2227 pps->row_height_minus1[pps->num_tile_rows_minus1] -=
2228 (pps->row_height_minus1[i] + 1);
2229 }
2230 }
2231 READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
2232 }
2233
2234 READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
2235
2236 READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
2237 if (pps->deblocking_filter_control_present_flag) {
2238 READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
2239
2240 READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
2241 if (!pps->deblocking_filter_disabled_flag) {
2242 READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
2243 READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
2244 }
2245 }
2246
2247 READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
2248 if (pps->scaling_list_data_present_flag)
2249 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
2250 goto error;
2251 if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
2252 && !pps->scaling_list_data_present_flag)
2253 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
2254 goto error;
2255
2256 READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
2257 READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
2258 READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
2259 READ_UINT8 (&nr, pps->pps_extension_flag, 1);
2260
2261 if (pps->pps_extension_flag) {
2262 READ_UINT8 (&nr, pps->pps_range_extension_flag, 1);
2263 READ_UINT8 (&nr, pps->pps_multilayer_extension_flag, 1);
2264 READ_UINT8 (&nr, pps->pps_3d_extension_flag, 1);
2265 READ_UINT8 (&nr, pps->pps_scc_extension_flag, 1);
2266 READ_UINT8 (&nr, pps->pps_extension_4bits, 4);
2267 }
2268
2269 if (pps->pps_range_extension_flag) {
2270 if (pps->transform_skip_enabled_flag)
2271 READ_UE (&nr,
2272 pps->pps_extension_params.log2_max_transform_skip_block_size_minus2);
2273 READ_UINT8 (&nr,
2274 pps->pps_extension_params.cross_component_prediction_enabled_flag, 1);
2275 READ_UINT8 (&nr,
2276 pps->pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
2277 if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag) {
2278 READ_UE_MAX (&nr,
2279 pps->pps_extension_params.diff_cu_chroma_qp_offset_depth,
2280 sps->log2_diff_max_min_luma_coding_block_size);
2281 READ_UE_MAX (&nr,
2282 pps->pps_extension_params.chroma_qp_offset_list_len_minus1, 5);
2283 for (i = 0;
2284 i <= pps->pps_extension_params.chroma_qp_offset_list_len_minus1;
2285 i++) {
2286 READ_SE_ALLOWED (&nr, pps->pps_extension_params.cb_qp_offset_list[i],
2287 -12, 12);
2288 READ_SE_ALLOWED (&nr, pps->pps_extension_params.cr_qp_offset_list[i],
2289 -12, 12);
2290 }
2291 }
2292 MaxBitDepthY =
2293 sps->bit_depth_luma_minus8 > 2 ? sps->bit_depth_luma_minus8 - 2 : 0;
2294 MaxBitDepthC =
2295 sps->bit_depth_chroma_minus8 > 2 ? sps->bit_depth_chroma_minus8 - 2 : 0;
2296 READ_UE_ALLOWED (&nr, pps->pps_extension_params.log2_sao_offset_scale_luma,
2297 0, MaxBitDepthY);
2298 READ_UE_ALLOWED (&nr,
2299 pps->pps_extension_params.log2_sao_offset_scale_chroma, 0,
2300 MaxBitDepthC);
2301 }
2302
2303 if (pps->pps_multilayer_extension_flag) {
2304 GST_WARNING ("do not support multilayer extension, skip all"
2305 " remaining bits");
2306 goto done;
2307 }
2308 if (pps->pps_3d_extension_flag) {
2309 GST_WARNING ("do not support 3d extension, skip all remaining bits");
2310 goto done;
2311 }
2312
2313 if (pps->pps_scc_extension_flag) {
2314 READ_UINT8 (&nr,
2315 pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag, 1);
2316 READ_UINT8 (&nr,
2317 pps->pps_scc_extension_params.
2318 residual_adaptive_colour_transform_enabled_flag, 1);
2319 if (pps->pps_scc_extension_params.
2320 residual_adaptive_colour_transform_enabled_flag) {
2321 READ_UINT8 (&nr,
2322 pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag,
2323 1);
2324 READ_SE_ALLOWED (&nr,
2325 pps->pps_scc_extension_params.pps_act_y_qp_offset_plus5, -7, 17);
2326 READ_SE_ALLOWED (&nr,
2327 pps->pps_scc_extension_params.pps_act_cb_qp_offset_plus5, -7, 17);
2328 READ_SE_ALLOWED (&nr,
2329 pps->pps_scc_extension_params.pps_act_cr_qp_offset_plus3, -9, 15);
2330 }
2331
2332 READ_UINT8 (&nr,
2333 pps->pps_scc_extension_params.
2334 pps_palette_predictor_initializers_present_flag, 1);
2335 if (pps->pps_scc_extension_params.
2336 pps_palette_predictor_initializers_present_flag) {
2337 READ_UE_MAX (&nr,
2338 pps->pps_scc_extension_params.pps_num_palette_predictor_initializer,
2339 sps->sps_scc_extension_params.palette_max_size +
2340 sps->sps_scc_extension_params.delta_palette_max_predictor_size);
2341 if (pps->pps_scc_extension_params.pps_num_palette_predictor_initializer >
2342 0) {
2343 guint comp;
2344
2345 READ_UINT8 (&nr, pps->pps_scc_extension_params.monochrome_palette_flag,
2346 1);
2347 /* It is a requirement of bitstream conformance that the value of
2348 luma_bit_depth_entry_minus8 shall be equal to the value of
2349 bit_depth_luma_minus8 */
2350 READ_UE_ALLOWED (&nr,
2351 pps->pps_scc_extension_params.luma_bit_depth_entry_minus8,
2352 sps->bit_depth_luma_minus8, sps->bit_depth_luma_minus8);
2353 if (!pps->pps_scc_extension_params.monochrome_palette_flag) {
2354 /* It is a requirement of bitstream conformance that the value
2355 of chroma_bit_depth_entry_minus8 shall be equal to the value
2356 of bit_depth_chroma_minus8. */
2357 READ_UE_ALLOWED (&nr,
2358 pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8,
2359 sps->bit_depth_chroma_minus8, sps->bit_depth_chroma_minus8);
2360 }
2361
2362 for (comp = 0; comp <
2363 (pps->pps_scc_extension_params.monochrome_palette_flag ? 1 : 3);
2364 comp++) {
2365 guint num_bits;
2366 guint num =
2367 pps->pps_scc_extension_params.
2368 pps_num_palette_predictor_initializer;
2369
2370 num_bits = (comp == 0 ?
2371 pps->pps_scc_extension_params.luma_bit_depth_entry_minus8 + 8 :
2372 pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8 + 8);
2373 for (i = 0; i < num; i++)
2374 READ_UINT32 (&nr,
2375 pps->pps_scc_extension_params.pps_palette_predictor_initializer
2376 [comp][i], num_bits);
2377 }
2378 }
2379 }
2380 }
2381
2382 done:
2383 pps->valid = TRUE;
2384 return GST_H265_PARSER_OK;
2385
2386 error:
2387 GST_WARNING ("error parsing \"Picture parameter set\"");
2388 pps->valid = FALSE;
2389 return GST_H265_PARSER_ERROR;
2390 }
2391
2392 /**
2393 * gst_h265_parser_parse_pps:
2394 * @parser: a #GstH265Parser
2395 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2396 * @pps: The #GstH265PPS to fill.
2397 *
2398 * Parses @data, and fills the @pps structure.
2399 *
2400 * Returns: a #GstH265ParserResult
2401 */
2402 GstH265ParserResult
gst_h265_parser_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2403 gst_h265_parser_parse_pps (GstH265Parser * parser,
2404 GstH265NalUnit * nalu, GstH265PPS * pps)
2405 {
2406 GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
2407 if (res == GST_H265_PARSER_OK) {
2408 GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
2409
2410 parser->pps[pps->id] = *pps;
2411 parser->last_pps = &parser->pps[pps->id];
2412 }
2413
2414 return res;
2415 }
2416
2417 /**
2418 * gst_h265_parser_parse_slice_hdr:
2419 * @parser: a #GstH265Parser
2420 * @nalu: The `GST_H265_NAL_SLICE` #GstH265NalUnit to parse
2421 * @slice: The #GstH265SliceHdr to fill.
2422 *
2423 * Parses @data, and fills the @slice structure.
2424 * The resulting @slice_hdr structure shall be deallocated with
2425 * gst_h265_slice_hdr_free() when it is no longer needed
2426 *
2427 * Returns: a #GstH265ParserResult
2428 */
2429 GstH265ParserResult
gst_h265_parser_parse_slice_hdr(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SliceHdr * slice)2430 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
2431 GstH265NalUnit * nalu, GstH265SliceHdr * slice)
2432 {
2433 NalReader nr;
2434 gint pps_id;
2435 GstH265PPS *pps;
2436 GstH265SPS *sps;
2437 guint i;
2438 GstH265ShortTermRefPicSet *stRPS = NULL;
2439 guint32 UsedByCurrPicLt[16];
2440 guint32 PicSizeInCtbsY;
2441 gint NumPocTotalCurr = 0;
2442
2443 memset (slice, 0, sizeof (*slice));
2444
2445 if (!nalu->size) {
2446 GST_DEBUG ("Invalid Nal Unit");
2447 return GST_H265_PARSER_ERROR;
2448 }
2449
2450 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2451 nalu->size - nalu->header_bytes);
2452
2453 GST_DEBUG ("parsing \"Slice header\", slice type");
2454
2455 READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
2456
2457 if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type))
2458 READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
2459
2460 READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
2461 pps = gst_h265_parser_get_pps (parser, pps_id);
2462 if (!pps) {
2463 GST_WARNING
2464 ("couldn't find associated picture parameter set with id: %d", pps_id);
2465 return GST_H265_PARSER_BROKEN_LINK;
2466 }
2467
2468 slice->pps = pps;
2469 sps = pps->sps;
2470 if (!sps) {
2471 GST_WARNING
2472 ("couldn't find associated sequence parameter set with id: %d",
2473 pps->id);
2474 return GST_H265_PARSER_BROKEN_LINK;
2475 }
2476
2477 PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
2478 /* set default values for fields that might not be present in the bitstream
2479 * and have valid defaults */
2480 slice->pic_output_flag = 1;
2481 slice->collocated_from_l0_flag = 1;
2482 slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
2483 slice->beta_offset_div2 = pps->beta_offset_div2;
2484 slice->tc_offset_div2 = pps->tc_offset_div2;
2485 slice->loop_filter_across_slices_enabled_flag =
2486 pps->loop_filter_across_slices_enabled_flag;
2487
2488 if (!slice->first_slice_segment_in_pic_flag) {
2489 const guint n = ceil_log2 (PicSizeInCtbsY);
2490
2491 if (pps->dependent_slice_segments_enabled_flag)
2492 READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
2493 /* sice_segment_address parsing */
2494 READ_UINT32 (&nr, slice->segment_address, n);
2495 }
2496
2497 if (!slice->dependent_slice_segment_flag) {
2498 for (i = 0; i < pps->num_extra_slice_header_bits; i++)
2499 nal_reader_skip (&nr, 1);
2500 READ_UE_MAX (&nr, slice->type, 63);
2501
2502
2503 if (pps->output_flag_present_flag)
2504 READ_UINT8 (&nr, slice->pic_output_flag, 1);
2505 if (sps->separate_colour_plane_flag == 1)
2506 READ_UINT8 (&nr, slice->colour_plane_id, 2);
2507
2508 if (!GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
2509 READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
2510 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2511
2512 READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
2513 if (!slice->short_term_ref_pic_set_sps_flag) {
2514 guint pos = nal_reader_get_pos (&nr);
2515 if (!gst_h265_parser_parse_short_term_ref_pic_sets
2516 (&slice->short_term_ref_pic_sets, &nr,
2517 sps->num_short_term_ref_pic_sets, sps))
2518 goto error;
2519
2520 slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
2521 } else if (sps->num_short_term_ref_pic_sets > 1) {
2522 const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
2523 READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
2524 CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
2525 sps->num_short_term_ref_pic_sets - 1);
2526 }
2527
2528 if (sps->long_term_ref_pics_present_flag) {
2529 guint32 limit;
2530
2531 if (sps->num_long_term_ref_pics_sps > 0)
2532 READ_UE_MAX (&nr, slice->num_long_term_sps,
2533 sps->num_long_term_ref_pics_sps);
2534
2535 READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2536 limit = slice->num_long_term_sps + slice->num_long_term_pics;
2537 for (i = 0; i < limit; i++) {
2538 if (i < slice->num_long_term_sps) {
2539 if (sps->num_long_term_ref_pics_sps > 1) {
2540 const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2541 READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2542 }
2543 } else {
2544 READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2545 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2546 READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2547 }
2548
2549 /* calculate UsedByCurrPicLt */
2550 if (i < slice->num_long_term_sps)
2551 UsedByCurrPicLt[i] =
2552 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2553 else
2554 UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2555 READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2556 if (slice->delta_poc_msb_present_flag[i])
2557 READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2558 }
2559 }
2560 if (sps->temporal_mvp_enabled_flag)
2561 READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2562 }
2563
2564 if (sps->sample_adaptive_offset_enabled_flag) {
2565 READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2566 if (sps->chroma_array_type)
2567 READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2568 }
2569
2570 if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2571 READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2572
2573 if (slice->num_ref_idx_active_override_flag) {
2574 READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2575 if (GST_H265_IS_B_SLICE (slice))
2576 READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2577 } else {
2578 /*set default values */
2579 slice->num_ref_idx_l0_active_minus1 =
2580 pps->num_ref_idx_l0_default_active_minus1;
2581 slice->num_ref_idx_l1_active_minus1 =
2582 pps->num_ref_idx_l1_default_active_minus1;
2583 }
2584
2585 /* calculate NumPocTotalCurr */
2586 if (slice->short_term_ref_pic_set_sps_flag)
2587 stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2588 else
2589 stRPS = &slice->short_term_ref_pic_sets;
2590
2591 for (i = 0; i < stRPS->NumNegativePics; i++)
2592 if (stRPS->UsedByCurrPicS0[i])
2593 NumPocTotalCurr++;
2594 for (i = 0; i < stRPS->NumPositivePics; i++)
2595 if (stRPS->UsedByCurrPicS1[i])
2596 NumPocTotalCurr++;
2597 for (i = 0;
2598 i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2599 if (UsedByCurrPicLt[i])
2600 NumPocTotalCurr++;
2601 slice->NumPocTotalCurr = NumPocTotalCurr;
2602
2603 if (pps->lists_modification_present_flag) {
2604 if (NumPocTotalCurr > 1)
2605 if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2606 NumPocTotalCurr))
2607 goto error;
2608 }
2609
2610 if (GST_H265_IS_B_SLICE (slice))
2611 READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2612 if (pps->cabac_init_present_flag)
2613 READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2614 if (slice->temporal_mvp_enabled_flag) {
2615 if (GST_H265_IS_B_SLICE (slice))
2616 READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2617
2618 if ((slice->collocated_from_l0_flag
2619 && slice->num_ref_idx_l0_active_minus1 > 0)
2620 || (!slice->collocated_from_l0_flag
2621 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2622
2623 /*fixme: add optimization */
2624 if ((GST_H265_IS_P_SLICE (slice))
2625 || ((GST_H265_IS_B_SLICE (slice))
2626 && (slice->collocated_from_l0_flag))) {
2627 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2628 slice->num_ref_idx_l0_active_minus1);
2629 } else if ((GST_H265_IS_B_SLICE (slice))
2630 && (!slice->collocated_from_l0_flag)) {
2631 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2632 slice->num_ref_idx_l1_active_minus1);
2633 }
2634 }
2635 }
2636 if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2637 (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2638 if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2639 goto error;
2640 READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2641
2642 if (sps->sps_scc_extension_params.motion_vector_resolution_control_idc
2643 == 2)
2644 READ_UINT8 (&nr, slice->use_integer_mv_flag, 1);
2645 }
2646
2647 READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2648 if (pps->slice_chroma_qp_offsets_present_flag) {
2649 READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2650 READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2651 }
2652
2653 if (pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag) {
2654 READ_SE_ALLOWED (&nr, slice->slice_act_y_qp_offset, -12, 12);
2655 READ_SE_ALLOWED (&nr, slice->slice_act_cb_qp_offset, -12, 12);
2656 READ_SE_ALLOWED (&nr, slice->slice_act_cr_qp_offset, -12, 12);
2657 }
2658
2659 if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag)
2660 READ_UINT8 (&nr, slice->cu_chroma_qp_offset_enabled_flag, 1);
2661
2662 if (pps->deblocking_filter_override_enabled_flag)
2663 READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2664 if (slice->deblocking_filter_override_flag) {
2665 READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2666 if (!slice->deblocking_filter_disabled_flag) {
2667 READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2668 READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2669 }
2670 }
2671
2672 if (pps->loop_filter_across_slices_enabled_flag &&
2673 (slice->sao_luma_flag || slice->sao_chroma_flag ||
2674 !slice->deblocking_filter_disabled_flag))
2675 READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2676 }
2677
2678 if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2679 guint32 offset_max;
2680
2681 if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2682 offset_max = pps->PicHeightInCtbsY - 1;
2683 else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2684 offset_max =
2685 (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2686 1;
2687 else
2688 offset_max =
2689 (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2690
2691 READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2692 if (slice->num_entry_point_offsets > 0) {
2693 READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2694 slice->entry_point_offset_minus1 =
2695 g_new0 (guint32, slice->num_entry_point_offsets);
2696 for (i = 0; i < slice->num_entry_point_offsets; i++)
2697 READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2698 (slice->offset_len_minus1 + 1));
2699 }
2700 }
2701
2702 if (pps->slice_segment_header_extension_present_flag) {
2703 guint16 slice_segment_header_extension_length;
2704 READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2705 for (i = 0; i < slice_segment_header_extension_length; i++)
2706 if (!nal_reader_skip (&nr, 8))
2707 goto error;
2708 }
2709
2710 /* Skip the byte alignment bits */
2711 if (!nal_reader_skip (&nr, 1))
2712 goto error;
2713 while (!nal_reader_is_byte_aligned (&nr)) {
2714 if (!nal_reader_skip (&nr, 1))
2715 goto error;
2716 }
2717
2718 slice->header_size = nal_reader_get_pos (&nr);
2719 slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2720
2721 return GST_H265_PARSER_OK;
2722
2723 error:
2724 GST_WARNING ("error parsing \"Slice header\"");
2725
2726 gst_h265_slice_hdr_free (slice);
2727
2728 return GST_H265_PARSER_ERROR;
2729 }
2730
2731 static gboolean
nal_reader_has_more_data_in_payload(NalReader * nr,guint32 payload_start_pos_bit,guint32 payloadSize)2732 nal_reader_has_more_data_in_payload (NalReader * nr,
2733 guint32 payload_start_pos_bit, guint32 payloadSize)
2734 {
2735 if (nal_reader_is_byte_aligned (nr) &&
2736 (nal_reader_get_pos (nr) >= (payload_start_pos_bit + 8 * payloadSize)))
2737 return FALSE;
2738
2739 return TRUE;
2740 }
2741
2742 static GstH265ParserResult
gst_h265_parser_parse_sei_message(GstH265Parser * parser,guint8 nal_type,NalReader * nr,GstH265SEIMessage * sei)2743 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2744 guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2745 {
2746 guint32 payloadSize;
2747 guint8 payload_type_byte, payload_size_byte;
2748 guint remaining, payload_size;
2749 guint32 payload_start_pos_bit;
2750 GstH265ParserResult res = GST_H265_PARSER_OK;
2751
2752 GST_DEBUG ("parsing \"Sei message\"");
2753
2754 memset (sei, 0, sizeof (*sei));
2755
2756 do {
2757 READ_UINT8 (nr, payload_type_byte, 8);
2758 sei->payloadType += payload_type_byte;
2759 } while (payload_type_byte == 0xff);
2760 payloadSize = 0;
2761 do {
2762 READ_UINT8 (nr, payload_size_byte, 8);
2763 payloadSize += payload_size_byte;
2764 }
2765 while (payload_size_byte == 0xff);
2766
2767 remaining = nal_reader_get_remaining (nr);
2768 payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
2769
2770 payload_start_pos_bit = nal_reader_get_pos (nr);
2771 GST_DEBUG
2772 ("SEI message received: payloadType %u, payloadSize = %u bits",
2773 sei->payloadType, payload_size);
2774
2775 if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2776 switch (sei->payloadType) {
2777 case GST_H265_SEI_BUF_PERIOD:
2778 /* size not set; might depend on emulation_prevention_three_byte */
2779 res = gst_h265_parser_parse_buffering_period (parser,
2780 &sei->payload.buffering_period, nr);
2781 break;
2782 case GST_H265_SEI_PIC_TIMING:
2783 /* size not set; might depend on emulation_prevention_three_byte */
2784 res = gst_h265_parser_parse_pic_timing (parser,
2785 &sei->payload.pic_timing, nr);
2786 break;
2787 case GST_H265_SEI_REGISTERED_USER_DATA:
2788 res = gst_h265_parser_parse_registered_user_data (parser,
2789 &sei->payload.registered_user_data, nr, payload_size >> 3);
2790 break;
2791 case GST_H265_SEI_RECOVERY_POINT:
2792 res = gst_h265_parser_parse_recovery_point (parser,
2793 &sei->payload.recovery_point, nr);
2794 break;
2795 case GST_H265_SEI_TIME_CODE:
2796 res = gst_h265_parser_parse_time_code (parser,
2797 &sei->payload.time_code, nr);
2798 break;
2799 case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
2800 res = gst_h265_parser_parse_mastering_display_colour_volume (parser,
2801 &sei->payload.mastering_display_colour_volume, nr);
2802 break;
2803 case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
2804 res = gst_h265_parser_parse_content_light_level_info (parser,
2805 &sei->payload.content_light_level, nr);
2806 break;
2807 default:
2808 /* Just consume payloadSize bytes, which does not account for
2809 emulation prevention bytes */
2810 if (!nal_reader_skip_long (nr, payload_size))
2811 goto error;
2812 res = GST_H265_PARSER_OK;
2813 break;
2814 }
2815 } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2816 switch (sei->payloadType) {
2817 default:
2818 /* Just consume payloadSize bytes, which does not account for
2819 emulation prevention bytes */
2820 if (!nal_reader_skip_long (nr, payload_size))
2821 goto error;
2822 res = GST_H265_PARSER_OK;
2823 break;
2824 }
2825 }
2826
2827 /* Not parsing the reserved_payload_extension, but it shouldn't be
2828 * an issue because of 1: There shall not be any reserved_payload_extension
2829 * present in bitstreams conforming to the specification.2. Even though
2830 * it is present, the size will be less than total PayloadSize since the
2831 * size of reserved_payload_extension is supposed to be
2832 * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2833 * the current implementation will still skip all unnecessary bits correctly.
2834 * In theory, we can have a more optimized implementation by skipping the
2835 * data left in PayLoadSize without out individually checking for each bits,
2836 * since the totoal size will be always less than payloadSize*/
2837 while (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
2838 payloadSize)) {
2839 /* Skip the byte alignment bits */
2840 if (!nal_reader_skip (nr, 1))
2841 goto error;
2842 while (!nal_reader_is_byte_aligned (nr)) {
2843 if (!nal_reader_skip (nr, 1))
2844 goto error;
2845 }
2846 }
2847
2848 return res;
2849
2850 error:
2851 GST_WARNING ("error parsing \"Sei message\"");
2852 return GST_H265_PARSER_ERROR;
2853 }
2854
2855 /**
2856 * gst_h265_slice_hdr_copy:
2857 * @dst_slice: The destination #GstH265SliceHdr to copy into
2858 * @src_slice: The source #GstH265SliceHdr to copy from
2859 *
2860 * Copies @src_slice into @dst_slice
2861 *
2862 * Returns: %TRUE if everything went fine, %FALSE otherwise
2863 */
2864 gboolean
gst_h265_slice_hdr_copy(GstH265SliceHdr * dst_slice,const GstH265SliceHdr * src_slice)2865 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2866 const GstH265SliceHdr * src_slice)
2867 {
2868 guint i;
2869
2870 g_return_val_if_fail (dst_slice != NULL, FALSE);
2871 g_return_val_if_fail (src_slice != NULL, FALSE);
2872
2873 gst_h265_slice_hdr_free (dst_slice);
2874
2875 *dst_slice = *src_slice;
2876
2877 if (dst_slice->num_entry_point_offsets > 0) {
2878 dst_slice->entry_point_offset_minus1 =
2879 g_new0 (guint32, dst_slice->num_entry_point_offsets);
2880 for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2881 dst_slice->entry_point_offset_minus1[i] =
2882 src_slice->entry_point_offset_minus1[i];
2883 }
2884
2885 return TRUE;
2886 }
2887
2888 /**
2889 * gst_h265_slice_hdr_free:
2890 * slice_hdr: The #GstH265SliceHdr to free
2891 *
2892 * Frees @slice_hdr fields.
2893 */
2894 void
gst_h265_slice_hdr_free(GstH265SliceHdr * slice_hdr)2895 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2896 {
2897 g_return_if_fail (slice_hdr != NULL);
2898
2899 if (slice_hdr->num_entry_point_offsets > 0)
2900 g_free (slice_hdr->entry_point_offset_minus1);
2901 slice_hdr->entry_point_offset_minus1 = 0;
2902 }
2903
2904 /**
2905 * gst_h265_sei_copy:
2906 * @dst_sei: The destination #GstH265SEIMessage to copy into
2907 * @src_sei: The source #GstH265SEIMessage to copy from
2908 *
2909 * Copies @src_sei into @dst_sei
2910 *
2911 * Returns: %TRUE if everything went fine, %FALSE otherwise
2912 */
2913 gboolean
gst_h265_sei_copy(GstH265SEIMessage * dst_sei,const GstH265SEIMessage * src_sei)2914 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2915 const GstH265SEIMessage * src_sei)
2916 {
2917 guint i;
2918
2919 g_return_val_if_fail (dst_sei != NULL, FALSE);
2920 g_return_val_if_fail (src_sei != NULL, FALSE);
2921
2922 gst_h265_sei_free (dst_sei);
2923
2924 *dst_sei = *src_sei;
2925
2926 if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2927 GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2928 const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2929
2930 if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2931 dst_pic_timing->num_nalus_in_du_minus1 =
2932 g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2933 dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2934 g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2935
2936 for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2937 dst_pic_timing->num_nalus_in_du_minus1[i] =
2938 src_pic_timing->num_nalus_in_du_minus1[i];
2939 dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2940 src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2941 }
2942 }
2943 } else if (dst_sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2944 GstH265RegisteredUserData *dst_rud = &dst_sei->payload.registered_user_data;
2945 const GstH265RegisteredUserData *src_rud =
2946 &src_sei->payload.registered_user_data;
2947
2948 if (src_rud->size) {
2949 dst_rud->data = g_malloc (src_rud->size);
2950 memcpy ((guint8 *) dst_rud->data, src_rud->data, src_rud->size);
2951 }
2952 }
2953
2954 return TRUE;
2955 }
2956
2957 /**
2958 * gst_h265_sei_free:
2959 * sei: The #GstH265SEIMessage to free
2960 *
2961 * Frees @sei fields.
2962 */
2963 void
gst_h265_sei_free(GstH265SEIMessage * sei)2964 gst_h265_sei_free (GstH265SEIMessage * sei)
2965 {
2966 g_return_if_fail (sei != NULL);
2967
2968 if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2969 GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2970 if (pic_timing->num_decoding_units_minus1 > 0) {
2971 g_free (pic_timing->num_nalus_in_du_minus1);
2972 g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2973 }
2974 pic_timing->num_nalus_in_du_minus1 = 0;
2975 pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2976 } else if (sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2977 GstH265RegisteredUserData *rud = &sei->payload.registered_user_data;
2978 g_free ((guint8 *) rud->data);
2979 rud->data = NULL;
2980 }
2981 }
2982
2983 /**
2984 * gst_h265_parser_parse_sei:
2985 * @nalparser: a #GstH265Parser
2986 * @nalu: The `GST_H265_NAL_*_SEI` #GstH265NalUnit to parse
2987 * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2988 *
2989 * Parses @data, create and fills the @messages array.
2990 *
2991 * Returns: a #GstH265ParserResult
2992 */
2993 GstH265ParserResult
gst_h265_parser_parse_sei(GstH265Parser * nalparser,GstH265NalUnit * nalu,GArray ** messages)2994 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2995 GArray ** messages)
2996 {
2997 NalReader nr;
2998 GstH265SEIMessage sei;
2999 GstH265ParserResult res;
3000
3001 GST_DEBUG ("parsing SEI nal");
3002 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
3003 nalu->size - nalu->header_bytes);
3004 *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
3005 g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
3006
3007 do {
3008 res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
3009 if (res == GST_H265_PARSER_OK)
3010 g_array_append_val (*messages, sei);
3011 else
3012 break;
3013 } while (nal_reader_has_more_data (&nr));
3014
3015 return res;
3016 }
3017
3018 /**
3019 * gst_h265_parser_update_vps:
3020 * @parser: a #GstH265Parser
3021 * @vps: (transfer none): a #GstH265VPS.
3022 *
3023 * Replace internal Video Parameter Set struct corresponding to id of @vps
3024 * with @vps. @nalparser will mark @vps as last parsed vps.
3025 *
3026 * Returns: a #GstH265ParserResult
3027 *
3028 * Since: 1.18
3029 */
3030 GstH265ParserResult
gst_h265_parser_update_vps(GstH265Parser * parser,GstH265VPS * vps)3031 gst_h265_parser_update_vps (GstH265Parser * parser, GstH265VPS * vps)
3032 {
3033 g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3034 g_return_val_if_fail (vps != NULL, GST_H265_PARSER_ERROR);
3035 g_return_val_if_fail (vps->id < GST_H265_MAX_VPS_COUNT,
3036 GST_H265_PARSER_ERROR);
3037
3038 if (!vps->valid) {
3039 GST_WARNING ("Cannot update with invalid VPS");
3040 return GST_H265_PARSER_ERROR;
3041 }
3042
3043 GST_DEBUG ("Updating video parameter set with id: %d", vps->id);
3044
3045 parser->vps[vps->id] = *vps;
3046 parser->last_vps = &parser->vps[vps->id];
3047
3048 return GST_H265_PARSER_OK;
3049 }
3050
3051 /**
3052 * gst_h265_parser_update_sps:
3053 * @parser: a #GstH265Parser
3054 * @sps: (transfer none): a #GstH265SPS.
3055 *
3056 * Replace internal Sequence Parameter Set struct corresponding to id of @sps
3057 * with @sps. @nalparser will mark @sps as last parsed sps.
3058 *
3059 * Returns: a #GstH265ParserResult
3060 *
3061 * Since: 1.18
3062 */
3063 GstH265ParserResult
gst_h265_parser_update_sps(GstH265Parser * parser,GstH265SPS * sps)3064 gst_h265_parser_update_sps (GstH265Parser * parser, GstH265SPS * sps)
3065 {
3066 g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3067 g_return_val_if_fail (sps != NULL, GST_H265_PARSER_ERROR);
3068 g_return_val_if_fail (sps->id < GST_H265_MAX_SPS_COUNT,
3069 GST_H265_PARSER_ERROR);
3070
3071 if (!sps->valid) {
3072 GST_WARNING ("Cannot update with invalid SPS");
3073 return GST_H265_PARSER_ERROR;
3074 }
3075
3076 if (sps->vps) {
3077 GstH265VPS *vps = gst_h265_parser_get_vps (parser, sps->vps->id);
3078 if (!vps || vps != sps->vps) {
3079 GST_WARNING ("Linked VPS is not identical to internal VPS");
3080 return GST_H265_PARSER_BROKEN_LINK;
3081 }
3082 }
3083
3084 GST_DEBUG ("Updating sequence parameter set with id: %d", sps->id);
3085
3086 parser->sps[sps->id] = *sps;
3087 parser->last_sps = &parser->sps[sps->id];
3088
3089 return GST_H265_PARSER_OK;
3090 }
3091
3092 /**
3093 * gst_h265_parser_update_pps:
3094 * @parser: a #GstH265Parser
3095 * @pps: (transfer none): a #GstH265PPS.
3096 *
3097 * Replace internal Sequence Parameter Set struct corresponding to id of @pps
3098 * with @pps. @nalparser will mark @pps as last parsed sps.
3099 *
3100 * Returns: a #GstH265ParserResult
3101 *
3102 * Since: 1.18
3103 */
3104 GstH265ParserResult
gst_h265_parser_update_pps(GstH265Parser * parser,GstH265PPS * pps)3105 gst_h265_parser_update_pps (GstH265Parser * parser, GstH265PPS * pps)
3106 {
3107 GstH265SPS *sps;
3108
3109 g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3110 g_return_val_if_fail (pps != NULL, GST_H265_PARSER_ERROR);
3111 g_return_val_if_fail (pps->id < GST_H265_MAX_PPS_COUNT,
3112 GST_H265_PARSER_ERROR);
3113
3114 if (!pps->valid) {
3115 GST_WARNING ("Cannot update with invalid PPS");
3116 return GST_H265_PARSER_ERROR;
3117 }
3118
3119 if (!pps->sps) {
3120 GST_WARNING ("No linked SPS struct");
3121 return GST_H265_PARSER_BROKEN_LINK;
3122 }
3123
3124 sps = gst_h265_parser_get_sps (parser, pps->sps->id);
3125 if (!sps || sps != pps->sps) {
3126 GST_WARNING ("Linked SPS is not identical to internal SPS");
3127 return GST_H265_PARSER_BROKEN_LINK;
3128 }
3129
3130 GST_DEBUG ("Updating picture parameter set with id: %d", pps->id);
3131
3132 parser->pps[pps->id] = *pps;
3133 parser->last_pps = &parser->pps[pps->id];
3134
3135 return GST_H265_PARSER_OK;
3136 }
3137
3138 /**
3139 * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
3140 * @out_quant: (out): The resulting quantization matrix
3141 * @quant: The source quantization matrix
3142 *
3143 * Converts quantization matrix @quant from raster scan order to
3144 * zigzag scan order and store the resulting factors into @out_quant.
3145 *
3146 * Note: it is an error to pass the same table in both @quant and
3147 * @out_quant arguments.
3148 *
3149 * Since: 1.6
3150 */
3151 void
gst_h265_quant_matrix_4x4_get_zigzag_from_raster(guint8 out_quant[16],const guint8 quant[16])3152 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
3153 const guint8 quant[16])
3154 {
3155 guint i;
3156
3157 g_return_if_fail (out_quant != quant);
3158
3159 for (i = 0; i < 16; i++)
3160 out_quant[i] = quant[zigzag_4x4[i]];
3161 }
3162
3163 /**
3164 * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
3165 * @out_quant: (out): The resulting quantization matrix
3166 * @quant: The source quantization matrix
3167 *
3168 * Converts quantization matrix @quant from zigzag scan order to
3169 * raster scan order and store the resulting factors into @out_quant.
3170 *
3171 * Note: it is an error to pass the same table in both @quant and
3172 * @out_quant arguments.
3173 *
3174 * Since: 1.6
3175 */
3176 void
gst_h265_quant_matrix_4x4_get_raster_from_zigzag(guint8 out_quant[16],const guint8 quant[16])3177 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
3178 const guint8 quant[16])
3179 {
3180 guint i;
3181
3182 g_return_if_fail (out_quant != quant);
3183
3184 for (i = 0; i < 16; i++)
3185 out_quant[zigzag_4x4[i]] = quant[i];
3186 }
3187
3188 /**
3189 * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
3190 * @out_quant: (out): The resulting quantization matrix
3191 * @quant: The source quantization matrix
3192 *
3193 * Converts quantization matrix @quant from raster scan order to
3194 * zigzag scan order and store the resulting factors into @out_quant.
3195 *
3196 * Note: it is an error to pass the same table in both @quant and
3197 * @out_quant arguments.
3198 *
3199 * Since: 1.6
3200 */
3201 void
gst_h265_quant_matrix_8x8_get_zigzag_from_raster(guint8 out_quant[64],const guint8 quant[64])3202 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
3203 const guint8 quant[64])
3204 {
3205 guint i;
3206
3207 g_return_if_fail (out_quant != quant);
3208
3209 for (i = 0; i < 64; i++)
3210 out_quant[i] = quant[zigzag_8x8[i]];
3211 }
3212
3213 /**
3214 * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
3215 * @out_quant: (out): The resulting quantization matrix
3216 * @quant: The source quantization matrix
3217 *
3218 * Converts quantization matrix @quant from zigzag scan order to
3219 * raster scan order and store the resulting factors into @out_quant.
3220 *
3221 * Note: it is an error to pass the same table in both @quant and
3222 * @out_quant arguments.
3223 *
3224 * Since: 1.6
3225 */
3226 void
gst_h265_quant_matrix_8x8_get_raster_from_zigzag(guint8 out_quant[64],const guint8 quant[64])3227 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
3228 const guint8 quant[64])
3229 {
3230 guint i;
3231
3232 g_return_if_fail (out_quant != quant);
3233
3234 for (i = 0; i < 64; i++)
3235 out_quant[zigzag_8x8[i]] = quant[i];
3236 }
3237
3238 /**
3239 * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
3240 * @out_quant: (out): The resulting quantization matrix
3241 * @quant: The source quantization matrix
3242 *
3243 * Converts quantization matrix @quant from raster scan order to
3244 * uprightdiagonal scan order and store the resulting factors
3245 * into @out_quant.
3246 *
3247 * Note: it is an error to pass the same table in both @quant and
3248 * @out_quant arguments.
3249 *
3250 * Since: 1.6
3251 */
3252 void
gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster(guint8 out_quant[16],const guint8 quant[16])3253 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
3254 const guint8 quant[16])
3255 {
3256 guint i;
3257
3258 g_return_if_fail (out_quant != quant);
3259
3260 for (i = 0; i < 16; i++)
3261 out_quant[i] = quant[uprightdiagonal_4x4[i]];
3262 }
3263
3264 /**
3265 * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
3266 * @out_quant: (out): The resulting quantization matrix
3267 * @quant: The source quantization matrix
3268 *
3269 * Converts quantization matrix @quant from uprightdiagonal scan order to
3270 * raster scan order and store the resulting factors into @out_quant.
3271 *
3272 * Note: it is an error to pass the same table in both @quant and
3273 * @out_quant arguments.
3274 *
3275 * Since: 1.6
3276 */
3277 void
gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal(guint8 out_quant[16],const guint8 quant[16])3278 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
3279 const guint8 quant[16])
3280 {
3281 guint i;
3282
3283 g_return_if_fail (out_quant != quant);
3284
3285 for (i = 0; i < 16; i++)
3286 out_quant[uprightdiagonal_4x4[i]] = quant[i];
3287 }
3288
3289 /**
3290 * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
3291 * @out_quant: (out): The resulting quantization matrix
3292 * @quant: The source quantization matrix
3293 *
3294 * Converts quantization matrix @quant from raster scan order to
3295 * uprightdiagonal scan order and store the resulting factors
3296 * into @out_quant.
3297 *
3298 * Note: it is an error to pass the same table in both @quant and
3299 * @out_quant arguments.
3300 *
3301 * Since: 1.6
3302 */
3303 void
gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster(guint8 out_quant[64],const guint8 quant[64])3304 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
3305 const guint8 quant[64])
3306 {
3307 guint i;
3308
3309 g_return_if_fail (out_quant != quant);
3310
3311 for (i = 0; i < 64; i++)
3312 out_quant[i] = quant[uprightdiagonal_8x8[i]];
3313 }
3314
3315 /**
3316 * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
3317 * @out_quant: (out): The resulting quantization matrix
3318 * @quant: The source quantization matrix
3319 *
3320 * Converts quantization matrix @quant from uprightdiagonal scan order to
3321 * raster scan order and store the resulting factors into @out_quant.
3322 *
3323 * Note: it is an error to pass the same table in both @quant and
3324 * @out_quant arguments.
3325 *
3326 * Since: 1.6
3327 */
3328 void
gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal(guint8 out_quant[64],const guint8 quant[64])3329 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
3330 const guint8 quant[64])
3331 {
3332 guint i;
3333
3334 g_return_if_fail (out_quant != quant);
3335
3336 for (i = 0; i < 64; i++)
3337 out_quant[uprightdiagonal_8x8[i]] = quant[i];
3338 }
3339
3340 typedef struct
3341 {
3342 GstH265Profile profile;
3343
3344 guint8 max_14bit_constraint_flag;
3345 guint8 max_12bit_constraint_flag;
3346 guint8 max_10bit_constraint_flag;
3347 guint8 max_8bit_constraint_flag;
3348 guint8 max_422chroma_constraint_flag;
3349 guint8 max_420chroma_constraint_flag;
3350 guint8 max_monochrome_constraint_flag;
3351 guint8 intra_constraint_flag;
3352 guint8 one_picture_only_constraint_flag;
3353 gboolean lower_bit_rate_constraint_flag_set;
3354
3355 /* Tie breaker if more than one profiles are matching */
3356 guint priority;
3357 } H265ExtensionProfile;
3358
3359 typedef struct
3360 {
3361 H265ExtensionProfile *profile;
3362 guint extra_constraints;
3363 } H265ExtensionProfileMatch;
3364
3365 static gint
sort_fre_profile_matches(H265ExtensionProfileMatch * a,H265ExtensionProfileMatch * b)3366 sort_fre_profile_matches (H265ExtensionProfileMatch * a,
3367 H265ExtensionProfileMatch * b)
3368 {
3369 gint d;
3370
3371 d = a->extra_constraints - b->extra_constraints;
3372 if (d)
3373 return d;
3374
3375 return b->profile->priority - a->profile->priority;
3376 }
3377
3378 static GstH265Profile
get_extension_profile(H265ExtensionProfile * profiles,guint num,const GstH265ProfileTierLevel * ptl)3379 get_extension_profile (H265ExtensionProfile * profiles, guint num,
3380 const GstH265ProfileTierLevel * ptl)
3381 {
3382 GstH265Profile result = GST_H265_PROFILE_INVALID;
3383 guint i;
3384 GList *matches = NULL;
3385
3386 for (i = 0; i < num; i++) {
3387 H265ExtensionProfile p = profiles[i];
3388 guint extra_constraints = 0;
3389 H265ExtensionProfileMatch *m;
3390
3391 /* Filter out all the profiles having constraints not satisfied by @ptl.
3392 * Then pick the one having the least extra constraints. This allow us
3393 * to match the closest profile if bitstream contains not standard
3394 * constraints. */
3395 if (p.max_14bit_constraint_flag != ptl->max_14bit_constraint_flag) {
3396 if (p.max_14bit_constraint_flag)
3397 continue;
3398 extra_constraints++;
3399 }
3400
3401 if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
3402 if (p.max_12bit_constraint_flag)
3403 continue;
3404 extra_constraints++;
3405 }
3406
3407 if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
3408 if (p.max_10bit_constraint_flag)
3409 continue;
3410 extra_constraints++;
3411 }
3412
3413 if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
3414 if (p.max_8bit_constraint_flag)
3415 continue;
3416 extra_constraints++;
3417 }
3418
3419 if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
3420 if (p.max_422chroma_constraint_flag)
3421 continue;
3422 extra_constraints++;
3423 }
3424
3425 if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
3426 if (p.max_420chroma_constraint_flag)
3427 continue;
3428 extra_constraints++;
3429 }
3430
3431 if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
3432 if (p.max_monochrome_constraint_flag)
3433 continue;
3434 extra_constraints++;
3435 }
3436
3437 if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
3438 if (p.intra_constraint_flag)
3439 continue;
3440 extra_constraints++;
3441 }
3442
3443 if (p.one_picture_only_constraint_flag !=
3444 ptl->one_picture_only_constraint_flag) {
3445 if (p.one_picture_only_constraint_flag)
3446 continue;
3447 extra_constraints++;
3448 }
3449
3450 if (p.lower_bit_rate_constraint_flag_set
3451 && !ptl->lower_bit_rate_constraint_flag)
3452 continue;
3453
3454 if (extra_constraints == 0) {
3455 result = p.profile;
3456 break;
3457 }
3458
3459 m = g_new0 (H265ExtensionProfileMatch, 1);
3460 m->profile = &profiles[i];
3461 m->extra_constraints = extra_constraints;
3462 matches = g_list_prepend (matches, m);
3463 }
3464
3465 if (result == GST_H265_PROFILE_INVALID && matches) {
3466 H265ExtensionProfileMatch *m;
3467
3468 matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
3469 m = matches->data;
3470 result = m->profile->profile;
3471 GST_INFO ("Fail to find the profile matches all extensions bits,"
3472 " select the closest %s with %d bit diff",
3473 gst_h265_profile_to_string (result), m->extra_constraints);
3474 }
3475
3476 if (matches)
3477 g_list_free_full (matches, g_free);
3478
3479 return result;
3480 }
3481
3482 static GstH265Profile
get_format_range_extension_profile(const GstH265ProfileTierLevel * ptl)3483 get_format_range_extension_profile (const GstH265ProfileTierLevel * ptl)
3484 {
3485 /* Profile idc: GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
3486 See Table A.2 for the definition of those formats */
3487 static H265ExtensionProfile profiles[] = {
3488 {GST_H265_PROFILE_MONOCHROME,
3489 0, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3490 {GST_H265_PROFILE_MONOCHROME_10,
3491 0, 1, 1, 0, 1, 1, 1, 0, 0, TRUE, 1},
3492 {GST_H265_PROFILE_MONOCHROME_12,
3493 0, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3494 {GST_H265_PROFILE_MONOCHROME_16,
3495 0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 3},
3496 {GST_H265_PROFILE_MAIN_12,
3497 0, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 4},
3498 {GST_H265_PROFILE_MAIN_422_10,
3499 0, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 5},
3500 {GST_H265_PROFILE_MAIN_422_12,
3501 0, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 6},
3502 {GST_H265_PROFILE_MAIN_444,
3503 0, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 7},
3504 {GST_H265_PROFILE_MAIN_444_10,
3505 0, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 8},
3506 {GST_H265_PROFILE_MAIN_444_12,
3507 0, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 9},
3508 {GST_H265_PROFILE_MAIN_INTRA,
3509 0, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 10},
3510 {GST_H265_PROFILE_MAIN_10_INTRA,
3511 0, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 11},
3512 {GST_H265_PROFILE_MAIN_12_INTRA,
3513 0, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 12},
3514 {GST_H265_PROFILE_MAIN_422_10_INTRA,
3515 0, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 13},
3516 {GST_H265_PROFILE_MAIN_422_12_INTRA,
3517 0, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 14},
3518 {GST_H265_PROFILE_MAIN_444_INTRA,
3519 0, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 15},
3520 {GST_H265_PROFILE_MAIN_444_10_INTRA,
3521 0, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 16},
3522 {GST_H265_PROFILE_MAIN_444_12_INTRA,
3523 0, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
3524 {GST_H265_PROFILE_MAIN_444_16_INTRA,
3525 0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 18},
3526 {GST_H265_PROFILE_MAIN_444_STILL_PICTURE,
3527 0, 1, 1, 1, 0, 0, 0, 1, 1, FALSE, 19},
3528 {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE,
3529 0, 0, 0, 0, 0, 0, 0, 1, 1, FALSE, 20},
3530 };
3531
3532 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3533 }
3534
3535 static GstH265Profile
get_3d_profile(const GstH265ProfileTierLevel * ptl)3536 get_3d_profile (const GstH265ProfileTierLevel * ptl)
3537 {
3538 /* profile idc: GST_H265_PROFILE_IDC_3D_MAIN */
3539 static H265ExtensionProfile profiles[] = {
3540 {GST_H265_PROFILE_3D_MAIN,
3541 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3542 };
3543
3544 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3545 }
3546
3547 static GstH265Profile
get_multiview_profile(const GstH265ProfileTierLevel * ptl)3548 get_multiview_profile (const GstH265ProfileTierLevel * ptl)
3549 {
3550 static H265ExtensionProfile profiles[] = {
3551 {GST_H265_PROFILE_MULTIVIEW_MAIN,
3552 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3553 };
3554
3555 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3556 }
3557
3558 static GstH265Profile
get_scalable_profile(const GstH265ProfileTierLevel * ptl)3559 get_scalable_profile (const GstH265ProfileTierLevel * ptl)
3560 {
3561 static H265ExtensionProfile profiles[] = {
3562 {GST_H265_PROFILE_SCALABLE_MAIN,
3563 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3564 {GST_H265_PROFILE_SCALABLE_MAIN_10,
3565 0, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3566 };
3567
3568 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3569 }
3570
3571 static GstH265Profile
get_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3572 get_high_throughput_profile (const GstH265ProfileTierLevel * ptl)
3573 {
3574 static H265ExtensionProfile profiles[] = {
3575 {GST_H265_PROFILE_HIGH_THROUGHPUT_444,
3576 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3577 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10,
3578 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3579 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14,
3580 1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3581 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
3582 0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 3},
3583 };
3584
3585 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3586 }
3587
3588 static GstH265Profile
get_screen_content_coding_extensions_profile(const GstH265ProfileTierLevel * ptl)3589 get_screen_content_coding_extensions_profile (const GstH265ProfileTierLevel *
3590 ptl)
3591 {
3592 static H265ExtensionProfile profiles[] = {
3593 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN,
3594 1, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3595 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10,
3596 1, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3597 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
3598 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 2},
3599 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10,
3600 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 3},
3601 };
3602
3603 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3604 }
3605
3606 static GstH265Profile
get_scalable_format_range_extensions_profile(const GstH265ProfileTierLevel * ptl)3607 get_scalable_format_range_extensions_profile (const GstH265ProfileTierLevel *
3608 ptl)
3609 {
3610 static H265ExtensionProfile profiles[] = {
3611 {GST_H265_PROFILE_SCALABLE_MONOCHROME,
3612 1, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3613 {GST_H265_PROFILE_SCALABLE_MONOCHROME_12,
3614 1, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 1},
3615 {GST_H265_PROFILE_SCALABLE_MONOCHROME_16,
3616 0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3617 {GST_H265_PROFILE_SCALABLE_MAIN_444,
3618 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 3},
3619 };
3620
3621 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3622 }
3623
3624 static GstH265Profile
get_screen_content_coding_extensions_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3625 get_screen_content_coding_extensions_high_throughput_profile
3626 (const GstH265ProfileTierLevel * ptl)
3627 {
3628 static H265ExtensionProfile profiles[] = {
3629 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
3630 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3631 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
3632 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3633 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
3634 1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3635 };
3636
3637 return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3638 }
3639
3640 static inline void
append_profile(GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * idx,GstH265Profile profile)3641 append_profile (GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * idx,
3642 GstH265Profile profile)
3643 {
3644 if (profile == GST_H265_PROFILE_INVALID)
3645 return;
3646 profiles[*idx] = profile;
3647 (*idx)++;
3648 }
3649
3650 /* *INDENT-OFF* */
3651 struct h265_profiles_map
3652 {
3653 GstH265ProfileIDC profile_idc;
3654 GstH265Profile (*get_profile) (const GstH265ProfileTierLevel *);
3655 GstH265Profile profile;
3656 };
3657 /* *INDENT-ON* */
3658
3659 static const struct h265_profiles_map profiles_map[] = {
3660 /* keep profile check in asc order */
3661 {GST_H265_PROFILE_IDC_MAIN, NULL, GST_H265_PROFILE_MAIN},
3662 {GST_H265_PROFILE_IDC_MAIN_10, NULL, GST_H265_PROFILE_MAIN_10},
3663 {GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE, NULL,
3664 GST_H265_PROFILE_MAIN_STILL_PICTURE},
3665 {GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3666 get_format_range_extension_profile, GST_H265_PROFILE_INVALID},
3667 {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT, get_high_throughput_profile,
3668 GST_H265_PROFILE_INVALID},
3669 {GST_H265_PROFILE_IDC_MULTIVIEW_MAIN, get_multiview_profile,
3670 GST_H265_PROFILE_INVALID},
3671 {GST_H265_PROFILE_IDC_SCALABLE_MAIN, get_scalable_profile,
3672 GST_H265_PROFILE_INVALID},
3673 {GST_H265_PROFILE_IDC_3D_MAIN, get_3d_profile, GST_H265_PROFILE_INVALID},
3674 {GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3675 get_screen_content_coding_extensions_profile,
3676 GST_H265_PROFILE_INVALID},
3677 {GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3678 get_scalable_format_range_extensions_profile,
3679 GST_H265_PROFILE_INVALID},
3680 {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION,
3681 get_screen_content_coding_extensions_high_throughput_profile,
3682 GST_H265_PROFILE_INVALID},
3683 };
3684
3685 static void
gst_h265_profile_tier_level_get_profiles(const GstH265ProfileTierLevel * ptl,GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * len)3686 gst_h265_profile_tier_level_get_profiles (const GstH265ProfileTierLevel * ptl,
3687 GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * len)
3688 {
3689 guint i = 0, j;
3690
3691 /* First add profile idc */
3692 for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3693 if (ptl->profile_idc == profiles_map[j].profile_idc) {
3694 if (profiles_map[j].get_profile)
3695 append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3696 else
3697 profiles[i++] = profiles_map[j].profile;
3698 break;
3699 }
3700 }
3701
3702 /* Later add compatibility flags */
3703 for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3704 if (i > 0 && ptl->profile_idc == profiles_map[j].profile_idc)
3705 continue;
3706 if (ptl->profile_compatibility_flag[profiles_map[j].profile_idc]) {
3707 if (profiles_map[j].get_profile)
3708 append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3709 else
3710 profiles[i++] = profiles_map[j].profile;
3711 }
3712 }
3713
3714 *len = i;
3715 }
3716
3717 /**
3718 * gst_h265_profile_tier_level_get_profile:
3719 * @ptl: a #GstH265ProfileTierLevel
3720 *
3721 * Return the H265 profile defined in @ptl.
3722 *
3723 * Returns: a #GstH265Profile
3724 * Since: 1.14
3725 */
3726 GstH265Profile
gst_h265_profile_tier_level_get_profile(const GstH265ProfileTierLevel * ptl)3727 gst_h265_profile_tier_level_get_profile (const GstH265ProfileTierLevel * ptl)
3728 {
3729 guint len = 0;
3730 GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
3731
3732 gst_h265_profile_tier_level_get_profiles (ptl, profiles, &len);
3733
3734 if (len > 0)
3735 return profiles[0];
3736
3737 return GST_H265_PROFILE_INVALID;
3738 }
3739
3740 /**
3741 * gst_h265_profile_to_string:
3742 * @profile: a #GstH265Profile
3743 *
3744 * Returns the descriptive name for the #GstH265Profile.
3745 *
3746 * Returns: (nullable): the name for @profile or %NULL on error
3747 *
3748 * Since: 1.18
3749 */
3750 const gchar *
gst_h265_profile_to_string(GstH265Profile profile)3751 gst_h265_profile_to_string (GstH265Profile profile)
3752 {
3753 guint i;
3754
3755 if (profile == GST_H265_PROFILE_INVALID || profile == GST_H265_PROFILE_MAX)
3756 return NULL;
3757
3758 for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3759 if (profile == h265_profiles[i].profile)
3760 return h265_profiles[i].name;
3761 }
3762
3763 return NULL;
3764 }
3765
3766 /**
3767 * gst_h265_profile_from_string:
3768 * @string: the descriptive name for #GstH265Profile
3769 *
3770 * Returns a #GstH265Profile for the @string.
3771 *
3772 * Returns: the #GstH265Profile of @string or %GST_H265_PROFILE_INVALID on error
3773 *
3774 * Since: 1.18
3775 */
3776 GstH265Profile
gst_h265_profile_from_string(const gchar * string)3777 gst_h265_profile_from_string (const gchar * string)
3778 {
3779 guint i;
3780
3781 if (string == NULL)
3782 return GST_H265_PROFILE_INVALID;
3783
3784 for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3785 if (g_strcmp0 (string, h265_profiles[i].name) == 0) {
3786 return h265_profiles[i].profile;
3787 }
3788 }
3789
3790 return GST_H265_PROFILE_INVALID;
3791 }
3792
3793 static gboolean
gst_h265_write_sei_registered_user_data(NalWriter * nw,GstH265RegisteredUserData * rud)3794 gst_h265_write_sei_registered_user_data (NalWriter * nw,
3795 GstH265RegisteredUserData * rud)
3796 {
3797 WRITE_UINT8 (nw, rud->country_code, 8);
3798 if (rud->country_code == 0xff)
3799 WRITE_UINT8 (nw, rud->country_code_extension, 8);
3800
3801 WRITE_BYTES (nw, rud->data, rud->size);
3802
3803 return TRUE;
3804
3805 error:
3806 return FALSE;
3807 }
3808
3809 static gboolean
gst_h265_write_sei_time_code(NalWriter * nw,GstH265TimeCode * tc)3810 gst_h265_write_sei_time_code (NalWriter * nw, GstH265TimeCode * tc)
3811 {
3812 gint i;
3813
3814 WRITE_UINT8 (nw, tc->num_clock_ts, 2);
3815
3816 for (i = 0; i < tc->num_clock_ts; i++) {
3817 WRITE_UINT8 (nw, tc->clock_timestamp_flag[i], 1);
3818 if (tc->clock_timestamp_flag[i]) {
3819 WRITE_UINT8 (nw, tc->units_field_based_flag[i], 1);
3820 WRITE_UINT8 (nw, tc->counting_type[i], 5);
3821 WRITE_UINT8 (nw, tc->full_timestamp_flag[i], 1);
3822 WRITE_UINT8 (nw, tc->discontinuity_flag[i], 1);
3823 WRITE_UINT8 (nw, tc->cnt_dropped_flag[i], 1);
3824 WRITE_UINT16 (nw, tc->n_frames[i], 9);
3825
3826 if (tc->full_timestamp_flag[i]) {
3827 WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3828 WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3829 WRITE_UINT8 (nw, tc->hours_value[i], 5);
3830 } else {
3831 WRITE_UINT8 (nw, tc->seconds_flag[i], 1);
3832 if (tc->seconds_flag[i]) {
3833 WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3834 WRITE_UINT8 (nw, tc->minutes_flag[i], 1);
3835 if (tc->minutes_flag[i]) {
3836 WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3837 WRITE_UINT8 (nw, tc->hours_flag[i], 1);
3838 if (tc->hours_flag[i]) {
3839 WRITE_UINT8 (nw, tc->hours_value[i], 5);
3840 }
3841 }
3842 }
3843 }
3844 }
3845
3846 WRITE_UINT8 (nw, tc->time_offset_length[i], 5);
3847
3848 if (tc->time_offset_length[i] > 0)
3849 WRITE_UINT8 (nw, tc->time_offset_value[i], tc->time_offset_length[i]);
3850 }
3851
3852 return TRUE;
3853
3854 error:
3855 return FALSE;
3856 }
3857
3858 static gboolean
gst_h265_write_sei_mastering_display_colour_volume(NalWriter * nw,GstH265MasteringDisplayColourVolume * mdcv)3859 gst_h265_write_sei_mastering_display_colour_volume (NalWriter * nw,
3860 GstH265MasteringDisplayColourVolume * mdcv)
3861 {
3862 gint i;
3863
3864 for (i = 0; i < 3; i++) {
3865 WRITE_UINT16 (nw, mdcv->display_primaries_x[i], 16);
3866 WRITE_UINT16 (nw, mdcv->display_primaries_y[i], 16);
3867 }
3868
3869 WRITE_UINT16 (nw, mdcv->white_point_x, 16);
3870 WRITE_UINT16 (nw, mdcv->white_point_y, 16);
3871 WRITE_UINT32 (nw, mdcv->max_display_mastering_luminance, 32);
3872 WRITE_UINT32 (nw, mdcv->min_display_mastering_luminance, 32);
3873
3874 return TRUE;
3875
3876 error:
3877 return FALSE;
3878 }
3879
3880 static gboolean
gst_h265_write_sei_content_light_level_info(NalWriter * nw,GstH265ContentLightLevel * cll)3881 gst_h265_write_sei_content_light_level_info (NalWriter * nw,
3882 GstH265ContentLightLevel * cll)
3883 {
3884 WRITE_UINT16 (nw, cll->max_content_light_level, 16);
3885 WRITE_UINT16 (nw, cll->max_pic_average_light_level, 16);
3886
3887 return TRUE;
3888
3889 error:
3890 return FALSE;
3891 }
3892
3893 static GstMemory *
gst_h265_create_sei_memory_internal(guint8 layer_id,guint8 temporal_id_plus1,guint nal_prefix_size,gboolean packetized,GArray * messages)3894 gst_h265_create_sei_memory_internal (guint8 layer_id, guint8 temporal_id_plus1,
3895 guint nal_prefix_size, gboolean packetized, GArray * messages)
3896 {
3897 NalWriter nw;
3898 gint i;
3899 gboolean have_written_data = FALSE;
3900
3901 nal_writer_init (&nw, nal_prefix_size, packetized);
3902
3903 if (messages->len == 0)
3904 goto error;
3905
3906 GST_DEBUG ("Create SEI nal from array, len: %d", messages->len);
3907
3908 /* nal header */
3909 /* forbidden_zero_bit */
3910 WRITE_UINT8 (&nw, 0, 1);
3911 /* nal_unit_type */
3912 WRITE_UINT8 (&nw, GST_H265_NAL_PREFIX_SEI, 6);
3913 /* nuh_layer_id */
3914 WRITE_UINT8 (&nw, layer_id, 6);
3915 /* nuh_temporal_id_plus1 */
3916 WRITE_UINT8 (&nw, temporal_id_plus1, 3);
3917
3918 for (i = 0; i < messages->len; i++) {
3919 GstH265SEIMessage *msg = &g_array_index (messages, GstH265SEIMessage, i);
3920 guint32 payload_size_data = 0;
3921 guint32 payload_size_in_bits = 0;
3922 guint32 payload_type_data = msg->payloadType;
3923 gboolean need_align = FALSE;
3924
3925 switch (payload_type_data) {
3926 case GST_H265_SEI_REGISTERED_USER_DATA:{
3927 GstH265RegisteredUserData *rud = &msg->payload.registered_user_data;
3928
3929 /* itu_t_t35_country_code: 8 bits */
3930 payload_size_data = 1;
3931 if (rud->country_code == 0xff) {
3932 /* itu_t_t35_country_code_extension_byte */
3933 payload_size_data++;
3934 }
3935
3936 payload_size_data += rud->size;
3937 break;
3938 }
3939 case GST_H265_SEI_TIME_CODE:{
3940 gint j;
3941 GstH265TimeCode *tc = &msg->payload.time_code;
3942 /* num_clock_ts: 2 bits */
3943 payload_size_in_bits = 2;
3944 for (j = 0; j < tc->num_clock_ts; j++) {
3945 /* clock_timestamp_flag: 1 bit */
3946 payload_size_in_bits += 1;
3947
3948 if (tc->clock_timestamp_flag[j]) {
3949 /* units_field_based_flag: 1 bit
3950 * counting_type: 5 bits
3951 * full_timestamp_flag: 1 bit
3952 * discontinuity_flag: 1 bit
3953 * cnt_dropped_flag: 1 bit
3954 * n_frames: 9 bit
3955 */
3956 payload_size_in_bits += 18;
3957
3958 if (tc->full_timestamp_flag[j]) {
3959 /* seconds_value: 6 bits
3960 * minutes_value: 6 bits
3961 * hours_value: 5 bits
3962 */
3963 payload_size_in_bits += 17;
3964 } else {
3965 /* seconds_flag: 1 bit */
3966 payload_size_in_bits += 1;
3967
3968 if (tc->seconds_flag[j]) {
3969 /* seconds_value: 6 bits
3970 * minutes_flag: 1 bit
3971 */
3972 payload_size_in_bits += 7;
3973
3974 if (tc->minutes_flag[j]) {
3975 /* minutes_value: 6 bits
3976 * hours_flag: 1 bit
3977 */
3978 payload_size_in_bits += 7;
3979 if (tc->hours_flag[j]) {
3980 /* hours_value: 5 bits */
3981 payload_size_in_bits += 5;
3982 }
3983 }
3984 }
3985 }
3986
3987 /* time_offset_length: 5bits
3988 * time_offset_value: time_offset_length bits
3989 */
3990 payload_size_in_bits += (5 + tc->time_offset_length[j]);
3991 }
3992 }
3993
3994 payload_size_data = payload_size_in_bits >> 3;
3995
3996 if ((payload_size_in_bits & 0x7) != 0) {
3997 GST_INFO ("Bits for Time Code SEI is not byte aligned");
3998 payload_size_data++;
3999 need_align = TRUE;
4000 }
4001 break;
4002 }
4003 case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4004 /* x, y 16 bits per RGB channel
4005 * x, y 16 bits white point
4006 * max, min luminance 32 bits
4007 *
4008 * (2 * 2 * 3) + (2 * 2) + (4 * 2) = 24 bytes
4009 */
4010 payload_size_data = 24;
4011 break;
4012 case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4013 /* maxCLL and maxFALL per 16 bits
4014 *
4015 * 2 * 2 = 4 bytes
4016 */
4017 payload_size_data = 4;
4018 break;
4019 default:
4020 break;
4021 }
4022
4023 if (payload_size_data == 0) {
4024 GST_FIXME ("Unsupported SEI type %d", msg->payloadType);
4025 continue;
4026 }
4027
4028 /* write payload type bytes */
4029 while (payload_type_data >= 0xff) {
4030 WRITE_UINT8 (&nw, 0xff, 8);
4031 payload_type_data -= 0xff;
4032 }
4033 WRITE_UINT8 (&nw, payload_type_data, 8);
4034
4035 /* write payload size bytes */
4036 while (payload_size_data >= 0xff) {
4037 WRITE_UINT8 (&nw, 0xff, 8);
4038 payload_size_data -= 0xff;
4039 }
4040 WRITE_UINT8 (&nw, payload_size_data, 8);
4041
4042 switch (msg->payloadType) {
4043 case GST_H265_SEI_REGISTERED_USER_DATA:
4044 GST_DEBUG ("Writing \"Registered user data\" done");
4045 if (!gst_h265_write_sei_registered_user_data (&nw,
4046 &msg->payload.registered_user_data)) {
4047 GST_WARNING ("Failed to write \"Registered user data\"");
4048 goto error;
4049 }
4050 have_written_data = TRUE;
4051 break;
4052 case GST_H265_SEI_TIME_CODE:
4053 GST_DEBUG ("Wrtiting \"Time code\"");
4054 if (!gst_h265_write_sei_time_code (&nw, &msg->payload.time_code)) {
4055 GST_WARNING ("Failed to write \"Time code\"");
4056 goto error;
4057 }
4058 have_written_data = TRUE;
4059 break;
4060 case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4061 GST_DEBUG ("Wrtiting \"Mastering display colour volume\"");
4062 if (!gst_h265_write_sei_mastering_display_colour_volume (&nw,
4063 &msg->payload.mastering_display_colour_volume)) {
4064 GST_WARNING ("Failed to write \"Mastering display colour volume\"");
4065 goto error;
4066 }
4067 have_written_data = TRUE;
4068 break;
4069 case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4070 GST_DEBUG ("Writing \"Content light level\" done");
4071 if (!gst_h265_write_sei_content_light_level_info (&nw,
4072 &msg->payload.content_light_level)) {
4073 GST_WARNING ("Failed to write \"Content light level\"");
4074 goto error;
4075 }
4076 have_written_data = TRUE;
4077 break;
4078 default:
4079 break;
4080 }
4081
4082 if (need_align && !nal_writer_do_rbsp_trailing_bits (&nw)) {
4083 GST_WARNING ("Cannot insert traling bits");
4084 goto error;
4085 }
4086 }
4087
4088 if (!have_written_data) {
4089 GST_WARNING ("No written sei data");
4090 goto error;
4091 }
4092
4093 if (!nal_writer_do_rbsp_trailing_bits (&nw)) {
4094 GST_WARNING ("Failed to insert rbsp trailing bits");
4095 goto error;
4096 }
4097
4098 return nal_writer_reset_and_get_memory (&nw);
4099
4100 error:
4101 nal_writer_reset (&nw);
4102
4103 return NULL;
4104 }
4105
4106 /**
4107 * gst_h265_create_sei_memory:
4108 * @layer_id: a nal unit layer id
4109 * @temporal_id_plus1: a nal unit temporal identifier
4110 * @start_code_prefix_length: a length of start code prefix, must be 3 or 4
4111 * @messages: (transfer none): a GArray of #GstH265SEIMessage
4112 *
4113 * Creates raw byte-stream format (a.k.a Annex B type) SEI nal unit data
4114 * from @messages
4115 *
4116 * Returns: a #GstMemory containing a PREFIX SEI nal unit
4117 *
4118 * Since: 1.18
4119 */
4120 GstMemory *
gst_h265_create_sei_memory(guint8 layer_id,guint8 temporal_id_plus1,guint8 start_code_prefix_length,GArray * messages)4121 gst_h265_create_sei_memory (guint8 layer_id, guint8 temporal_id_plus1,
4122 guint8 start_code_prefix_length, GArray * messages)
4123 {
4124 g_return_val_if_fail (start_code_prefix_length == 3
4125 || start_code_prefix_length == 4, NULL);
4126 g_return_val_if_fail (messages != NULL, NULL);
4127 g_return_val_if_fail (messages->len > 0, NULL);
4128
4129 return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4130 start_code_prefix_length, FALSE, messages);
4131 }
4132
4133 /**
4134 * gst_h265_create_sei_memory_hevc:
4135 * @layer_id: a nal unit layer id
4136 * @temporal_id_plus1: a nal unit temporal identifier
4137 * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4138 * @messages: (transfer none): a GArray of #GstH265SEIMessage
4139 *
4140 * Creates raw packetized format SEI nal unit data from @messages
4141 *
4142 * Returns: a #GstMemory containing a PREFIX SEI nal unit
4143 *
4144 * Since: 1.18
4145 */
4146 GstMemory *
gst_h265_create_sei_memory_hevc(guint8 layer_id,guint8 temporal_id_plus1,guint8 nal_length_size,GArray * messages)4147 gst_h265_create_sei_memory_hevc (guint8 layer_id, guint8 temporal_id_plus1,
4148 guint8 nal_length_size, GArray * messages)
4149 {
4150 return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4151 nal_length_size, TRUE, messages);
4152 }
4153
4154 static GstBuffer *
gst_h265_parser_insert_sei_internal(GstH265Parser * parser,guint8 nal_prefix_size,gboolean packetized,GstBuffer * au,GstMemory * sei)4155 gst_h265_parser_insert_sei_internal (GstH265Parser * parser,
4156 guint8 nal_prefix_size, gboolean packetized, GstBuffer * au,
4157 GstMemory * sei)
4158 {
4159 GstH265NalUnit nalu;
4160 GstH265NalUnit sei_nalu;
4161 GstMapInfo info;
4162 GstMapInfo sei_info;
4163 GstH265ParserResult pres;
4164 guint offset = 0;
4165 GstBuffer *new_buffer = NULL;
4166 GstMemory *new_mem = NULL;
4167
4168 /* all SEI payload types supported by us need to have the identical
4169 * temporal id to that of slice. Parse SEI first and we will
4170 * update it if it's required */
4171 if (!gst_memory_map (sei, &sei_info, GST_MAP_READ)) {
4172 GST_ERROR ("Cannot map sei memory");
4173 return NULL;
4174 }
4175
4176 if (packetized) {
4177 pres = gst_h265_parser_identify_nalu_hevc (parser,
4178 sei_info.data, 0, sei_info.size, nal_prefix_size, &sei_nalu);
4179 } else {
4180 pres = gst_h265_parser_identify_nalu (parser,
4181 sei_info.data, 0, sei_info.size, &sei_nalu);
4182 }
4183 gst_memory_unmap (sei, &sei_info);
4184 if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4185 GST_DEBUG ("Failed to identify sei nal unit, ret: %d", pres);
4186 return NULL;
4187 }
4188
4189 if (!gst_buffer_map (au, &info, GST_MAP_READ)) {
4190 GST_ERROR ("Cannot map au buffer");
4191 return NULL;
4192 }
4193
4194 /* Find the offset of the first slice */
4195 do {
4196 if (packetized) {
4197 pres = gst_h265_parser_identify_nalu_hevc (parser,
4198 info.data, offset, info.size, nal_prefix_size, &nalu);
4199 } else {
4200 pres = gst_h265_parser_identify_nalu (parser,
4201 info.data, offset, info.size, &nalu);
4202 }
4203
4204 if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4205 GST_DEBUG ("Failed to identify nal unit, ret: %d", pres);
4206 gst_buffer_unmap (au, &info);
4207
4208 return NULL;
4209 }
4210
4211 if (nalu.type <= GST_H265_NAL_SLICE_RASL_R
4212 || (nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP
4213 && nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)) {
4214 GST_DEBUG ("Found slice nal type %d at offset %d", nalu.type,
4215 nalu.sc_offset);
4216 break;
4217 }
4218
4219 offset = nalu.offset + nalu.size;
4220 } while (pres == GST_H265_PARSER_OK);
4221 gst_buffer_unmap (au, &info);
4222
4223 /* found the best position now, create new buffer */
4224 new_buffer = gst_buffer_new ();
4225
4226 /* copy all metadata */
4227 if (!gst_buffer_copy_into (new_buffer, au, GST_BUFFER_COPY_METADATA, 0, -1)) {
4228 GST_ERROR ("Failed to copy metadata into new buffer");
4229 gst_clear_buffer (&new_buffer);
4230 goto out;
4231 }
4232
4233 /* copy non-slice nal */
4234 if (nalu.sc_offset > 0) {
4235 if (!gst_buffer_copy_into (new_buffer, au,
4236 GST_BUFFER_COPY_MEMORY, 0, nalu.sc_offset)) {
4237 GST_ERROR ("Failed to copy buffer");
4238 gst_clear_buffer (&new_buffer);
4239 goto out;
4240 }
4241 }
4242
4243 /* check whether we need to update temporal id and layer id.
4244 * If it's not matched to slice nalu, update it.
4245 */
4246 if (sei_nalu.layer_id != nalu.layer_id || sei_nalu.temporal_id_plus1 !=
4247 nalu.temporal_id_plus1) {
4248 guint16 nalu_header;
4249 guint16 layer_id_temporal_id = 0;
4250 new_mem = gst_memory_copy (sei, 0, -1);
4251
4252 if (!gst_memory_map (new_mem, &sei_info, GST_MAP_READWRITE)) {
4253 GST_ERROR ("Failed to map new sei memory");
4254 gst_memory_unref (new_mem);
4255 gst_clear_buffer (&new_buffer);
4256 goto out;
4257 }
4258
4259 nalu_header = GST_READ_UINT16_BE (sei_info.data + sei_nalu.offset);
4260
4261 /* clear bits 7 ~ 15
4262 * NOTE:
4263 * bit 0: forbidden_zero_bit
4264 * bits 1 ~ 6: nalu type */
4265 nalu_header &= 0xfe00;
4266
4267 layer_id_temporal_id = ((nalu.layer_id << 3) & 0x1f8);
4268 layer_id_temporal_id |= (nalu.temporal_id_plus1 & 0x7);
4269
4270 nalu_header |= layer_id_temporal_id;
4271 GST_WRITE_UINT16_BE (sei_info.data + sei_nalu.offset, nalu_header);
4272 gst_memory_unmap (new_mem, &sei_info);
4273 } else {
4274 new_mem = gst_memory_ref (sei);
4275 }
4276
4277 /* insert sei */
4278 gst_buffer_append_memory (new_buffer, new_mem);
4279
4280 /* copy the rest */
4281 if (!gst_buffer_copy_into (new_buffer, au,
4282 GST_BUFFER_COPY_MEMORY, nalu.sc_offset, -1)) {
4283 GST_ERROR ("Failed to copy buffer");
4284 gst_clear_buffer (&new_buffer);
4285 goto out;
4286 }
4287
4288 out:
4289 return new_buffer;
4290 }
4291
4292 /**
4293 * gst_h265_parser_insert_sei:
4294 * @parser: a #GstH265Parser
4295 * @au: (transfer none): a #GstBuffer containing AU data
4296 * @sei: (transfer none): a #GstMemory containing a SEI nal
4297 *
4298 * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4299 * The validation for completeness of @au and @sei is caller's responsibility.
4300 * Both @au and @sei must be byte-stream formatted
4301 *
4302 * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4303 * if cannot figure out proper position to insert a @sei
4304 *
4305 * Since: 1.18
4306 */
4307 GstBuffer *
gst_h265_parser_insert_sei(GstH265Parser * parser,GstBuffer * au,GstMemory * sei)4308 gst_h265_parser_insert_sei (GstH265Parser * parser, GstBuffer * au,
4309 GstMemory * sei)
4310 {
4311 g_return_val_if_fail (parser != NULL, NULL);
4312 g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4313 g_return_val_if_fail (sei != NULL, NULL);
4314
4315 /* the size of start code prefix (3 or 4) is not matter since it will be
4316 * scanned */
4317 return gst_h265_parser_insert_sei_internal (parser, 4, FALSE, au, sei);
4318 }
4319
4320 /**
4321 * gst_h265_parser_insert_sei_hevc:
4322 * @parser: a #GstH265Parser
4323 * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4324 * @au: (transfer none): a #GstBuffer containing AU data
4325 * @sei: (transfer none): a #GstMemory containing a SEI nal
4326 *
4327 * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4328 * The validation for completeness of @au and @sei is caller's responsibility.
4329 * Nal prefix type of both @au and @sei must be packetized, and
4330 * also the size of nal length field must be identical to @nal_length_size
4331 *
4332 * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4333 * if cannot figure out proper position to insert a @sei
4334 *
4335 * Since: 1.18
4336 */
4337 GstBuffer *
gst_h265_parser_insert_sei_hevc(GstH265Parser * parser,guint8 nal_length_size,GstBuffer * au,GstMemory * sei)4338 gst_h265_parser_insert_sei_hevc (GstH265Parser * parser, guint8 nal_length_size,
4339 GstBuffer * au, GstMemory * sei)
4340 {
4341 g_return_val_if_fail (parser != NULL, NULL);
4342 g_return_val_if_fail (nal_length_size > 0 && nal_length_size < 5, NULL);
4343 g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4344 g_return_val_if_fail (sei != NULL, NULL);
4345
4346 return gst_h265_parser_insert_sei_internal (parser, nal_length_size, TRUE,
4347 au, sei);
4348 }
4349
4350 /**
4351 * gst_h265_get_profile_from_sps:
4352 * @sps: a #GstH265SPS
4353 *
4354 * Return the H265 profile from @sps.
4355 *
4356 * Returns: a #GstH265Profile
4357 * Since: 1.20
4358 */
4359 GstH265Profile
gst_h265_get_profile_from_sps(GstH265SPS * sps)4360 gst_h265_get_profile_from_sps (GstH265SPS * sps)
4361 {
4362 GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
4363 GstH265ProfileTierLevel tmp_ptl;
4364 guint i, len = 0;
4365 guint chroma_format_idc, bit_depth_luma, bit_depth_chroma;
4366
4367 g_return_val_if_fail (sps != NULL, GST_H265_PROFILE_INVALID);
4368
4369 tmp_ptl = sps->profile_tier_level;
4370 chroma_format_idc = sps->chroma_format_idc;
4371 bit_depth_luma = sps->bit_depth_luma_minus8 + 8;
4372 bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
4373
4374 gst_h265_profile_tier_level_get_profiles (&sps->profile_tier_level, profiles,
4375 &len);
4376
4377 for (i = 0; i < len && i < G_N_ELEMENTS (profiles); i++) {
4378 switch (profiles[i]) {
4379 case GST_H265_PROFILE_INVALID:
4380 break;
4381 case GST_H265_PROFILE_MAIN:
4382 case GST_H265_PROFILE_MAIN_STILL_PICTURE:
4383 /* A.3.2 or A.3.5 */
4384 if (chroma_format_idc == 1
4385 && bit_depth_luma == 8 && bit_depth_chroma == 8)
4386 return profiles[i];
4387 break;
4388 case GST_H265_PROFILE_MAIN_10:
4389 /* A.3.3 */
4390 if (chroma_format_idc == 1
4391 && bit_depth_luma >= 8 && bit_depth_luma <= 10
4392 && bit_depth_chroma >= 8 && bit_depth_chroma <= 10)
4393 return profiles[i];
4394 break;
4395 default:
4396 return profiles[i];
4397 }
4398 }
4399
4400 /* Invalid profile: */
4401 /* Set the conformance indicators based on chroma_format_idc / bit_depth */
4402 switch (chroma_format_idc) {
4403 case 0:
4404 tmp_ptl.max_monochrome_constraint_flag = 1;
4405 tmp_ptl.max_420chroma_constraint_flag = 1;
4406 tmp_ptl.max_422chroma_constraint_flag = 1;
4407 break;
4408
4409 case 1:
4410 tmp_ptl.max_monochrome_constraint_flag = 0;
4411 tmp_ptl.max_420chroma_constraint_flag = 1;
4412 tmp_ptl.max_422chroma_constraint_flag = 1;
4413 break;
4414
4415 case 2:
4416 tmp_ptl.max_monochrome_constraint_flag = 0;
4417 tmp_ptl.max_420chroma_constraint_flag = 0;
4418 tmp_ptl.max_422chroma_constraint_flag = 1;
4419 break;
4420
4421 case 3:
4422 tmp_ptl.max_monochrome_constraint_flag = 0;
4423 tmp_ptl.max_420chroma_constraint_flag = 0;
4424 tmp_ptl.max_422chroma_constraint_flag = 0;
4425 break;
4426
4427 default:
4428 g_assert_not_reached ();
4429 break;
4430 }
4431
4432 tmp_ptl.max_8bit_constraint_flag = 1;
4433 tmp_ptl.max_10bit_constraint_flag = 1;
4434 tmp_ptl.max_12bit_constraint_flag = 1;
4435 tmp_ptl.max_14bit_constraint_flag = 1;
4436
4437 if (bit_depth_luma > 8 || bit_depth_chroma > 8)
4438 tmp_ptl.max_8bit_constraint_flag = 0;
4439
4440 if (bit_depth_luma > 10 || bit_depth_chroma > 10)
4441 tmp_ptl.max_10bit_constraint_flag = 0;
4442
4443 if (bit_depth_luma > 12 || bit_depth_chroma > 12)
4444 tmp_ptl.max_12bit_constraint_flag = 0;
4445
4446 if (tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
4447 || tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
4448 || tmp_ptl.profile_idc ==
4449 GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION
4450 || tmp_ptl.profile_idc ==
4451 GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION
4452 || tmp_ptl.profile_compatibility_flag[5]
4453 || tmp_ptl.profile_compatibility_flag[9]
4454 || tmp_ptl.profile_compatibility_flag[10]
4455 || tmp_ptl.profile_compatibility_flag[11]) {
4456 if (bit_depth_luma > 14 || bit_depth_chroma > 14)
4457 tmp_ptl.max_14bit_constraint_flag = 0;
4458 } else {
4459 tmp_ptl.max_14bit_constraint_flag = 0;
4460 }
4461
4462 /* first profile of the synthetic ptl */
4463 return gst_h265_profile_tier_level_get_profile (&tmp_ptl);
4464 }
4465