1 /* Gstreamer H.265 bitstream parser
2 * Copyright (C) 2012 Intel Corporation
3 * Copyright (C) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
5 * Contact: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
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.
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.
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.
24 * SECTION:gsth265parser
25 * @title: GstH265Parser
26 * @short_description: Convenience library for h265 video bitstream parsing.
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:
31 * * gst_h265_parser_identify_nalu() to identify the following nalu in
34 * * gst_h265_parser_identify_nalu_hevc() to identify the nalu in
37 * Then, depending on the #GstH265NalUnitType of the newly parsed #GstH265NalUnit,
38 * you should call the differents functions to parse the structure:
40 * * From #GST_H265_NAL_SLICE_TRAIL_N to #GST_H265_NAL_SLICE_CRA_NUT: gst_h265_parser_parse_slice_hdr()
42 * * `GST_H265_NAL_*_SEI`: gst_h265_parser_parse_sei()
44 * * #GST_H265_NAL_VPS: gst_h265_parser_parse_vps()
46 * * #GST_H265_NAL_SPS: gst_h265_parser_parse_sps()
48 * * #GST_H265_NAL_PPS: #gst_h265_parser_parse_pps()
50 * * Any other: gst_h265_parser_parse_nal()
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.
56 * For more details about the structures, look at the ITU-T H.265
57 * specifications, you can download them from:
59 * * ITU-T H.265: http://www.itu.int/rec/T-REC-H.265
68 #include "gsth265parser.h"
70 #include <gst/base/gstbytereader.h>
71 #include <gst/base/gstbitreader.h>
75 #ifndef GST_DISABLE_GST_DEBUG
76 #define GST_CAT_DEFAULT gst_h265_debug_category_get()
77 static GstDebugCategory *
78 gst_h265_debug_category_get (void)
80 static gsize cat_gonce = 0;
82 if (g_once_init_enter (&cat_gonce)) {
83 GstDebugCategory *cat = NULL;
85 GST_DEBUG_CATEGORY_INIT (cat, "codecparsers_h265", 0, "h265 parse library");
87 g_once_init_leave (&cat_gonce, (gsize) cat);
90 return (GstDebugCategory *) cat_gonce;
92 #endif /* GST_DISABLE_GST_DEBUG */
94 /**** Default scaling_lists according to Table 7-5 and 7-6 *****/
97 static const guint8 default_scaling_list0[16] = {
98 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
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
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,
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
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,
128 static const guint8 zigzag_4x4[16] = {
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
146 static const guint8 uprightdiagonal_4x4[16] = {
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
169 /* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
170 static const PAR aspect_ratios[17] = {
191 #define EXTENDED_SAR 255
194 gst_h265_parser_get_vps (GstH265Parser * parser, guint8 vps_id)
198 vps = &parser->vps[vps_id];
207 gst_h265_parser_get_sps (GstH265Parser * parser, guint8 sps_id)
211 sps = &parser->sps[sps_id];
220 gst_h265_parser_get_pps (GstH265Parser * parser, guint8 pps_id)
224 pps = &parser->pps[pps_id];
233 gst_h265_parse_nalu_header (GstH265NalUnit * nalu)
235 guint8 *data = nalu->data + nalu->offset;
241 gst_bit_reader_init (&br, data, nalu->size - nalu->offset);
243 /* skip the forbidden_zero_bit */
244 gst_bit_reader_skip_unchecked (&br, 1);
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;
254 /****** Parsing functions *****/
257 gst_h265_parse_profile_tier_level (GstH265ProfileTierLevel * ptl,
258 NalReader * nr, guint8 maxNumSubLayersMinus1)
261 GST_DEBUG ("parsing \"ProfileTierLevel parameters\"");
263 READ_UINT8 (nr, ptl->profile_space, 2);
264 READ_UINT8 (nr, ptl->tier_flag, 1);
265 READ_UINT8 (nr, ptl->profile_idc, 5);
267 for (j = 0; j < 32; j++)
268 READ_UINT8 (nr, ptl->profile_compatibility_flag[j], 1);
270 READ_UINT8 (nr, ptl->progressive_source_flag, 1);
271 READ_UINT8 (nr, ptl->interlaced_source_flag, 1);
272 READ_UINT8 (nr, ptl->non_packed_constraint_flag, 1);
273 READ_UINT8 (nr, ptl->frame_only_constraint_flag, 1);
275 READ_UINT8 (nr, ptl->max_12bit_constraint_flag, 1);
276 READ_UINT8 (nr, ptl->max_10bit_constraint_flag, 1);
277 READ_UINT8 (nr, ptl->max_8bit_constraint_flag, 1);
278 READ_UINT8 (nr, ptl->max_422chroma_constraint_flag, 1);
279 READ_UINT8 (nr, ptl->max_420chroma_constraint_flag, 1);
280 READ_UINT8 (nr, ptl->max_monochrome_constraint_flag, 1);
281 READ_UINT8 (nr, ptl->intra_constraint_flag, 1);
282 READ_UINT8 (nr, ptl->one_picture_only_constraint_flag, 1);
283 READ_UINT8 (nr, ptl->lower_bit_rate_constraint_flag, 1);
284 READ_UINT8 (nr, ptl->max_14bit_constraint_flag, 1);
286 /* skip the reserved zero bits */
287 if (!nal_reader_skip (nr, 34))
290 READ_UINT8 (nr, ptl->level_idc, 8);
291 for (j = 0; j < maxNumSubLayersMinus1; j++) {
292 READ_UINT8 (nr, ptl->sub_layer_profile_present_flag[j], 1);
293 READ_UINT8 (nr, ptl->sub_layer_level_present_flag[j], 1);
296 if (maxNumSubLayersMinus1 > 0) {
297 for (i = maxNumSubLayersMinus1; i < 8; i++)
298 if (!nal_reader_skip (nr, 2))
302 for (i = 0; i < maxNumSubLayersMinus1; i++) {
303 if (ptl->sub_layer_profile_present_flag[i]) {
304 READ_UINT8 (nr, ptl->sub_layer_profile_space[i], 2);
305 READ_UINT8 (nr, ptl->sub_layer_tier_flag[i], 1);
306 READ_UINT8 (nr, ptl->sub_layer_profile_idc[i], 5);
308 for (j = 0; j < 32; j++)
309 READ_UINT8 (nr, ptl->sub_layer_profile_compatibility_flag[i][j], 1);
311 READ_UINT8 (nr, ptl->sub_layer_progressive_source_flag[i], 1);
312 READ_UINT8 (nr, ptl->sub_layer_interlaced_source_flag[i], 1);
313 READ_UINT8 (nr, ptl->sub_layer_non_packed_constraint_flag[i], 1);
314 READ_UINT8 (nr, ptl->sub_layer_frame_only_constraint_flag[i], 1);
316 if (!nal_reader_skip (nr, 44))
320 if (ptl->sub_layer_level_present_flag[i])
321 READ_UINT8 (nr, ptl->sub_layer_level_idc[i], 8);
327 GST_WARNING ("error parsing \"ProfileTierLevel Parameters\"");
332 gst_h265_parse_sub_layer_hrd_parameters (GstH265SubLayerHRDParams * sub_hrd,
333 NalReader * nr, guint8 CpbCnt, guint8 sub_pic_hrd_params_present_flag)
337 GST_DEBUG ("parsing \"SubLayer HRD Parameters\"");
339 for (i = 0; i <= CpbCnt; i++) {
340 READ_UE_MAX (nr, sub_hrd->bit_rate_value_minus1[i], G_MAXUINT32 - 1);
341 READ_UE_MAX (nr, sub_hrd->cpb_size_value_minus1[i], G_MAXUINT32 - 1);
343 if (sub_pic_hrd_params_present_flag) {
344 READ_UE_MAX (nr, sub_hrd->cpb_size_du_value_minus1[i], G_MAXUINT32 - 1);
345 READ_UE_MAX (nr, sub_hrd->bit_rate_du_value_minus1[i], G_MAXUINT32 - 1);
348 READ_UINT8 (nr, sub_hrd->cbr_flag[i], 1);
354 GST_WARNING ("error parsing \"SubLayerHRD Parameters \"");
359 gst_h265_parse_hrd_parameters (GstH265HRDParams * hrd, NalReader * nr,
360 guint8 commonInfPresentFlag, guint8 maxNumSubLayersMinus1)
364 GST_DEBUG ("parsing \"HRD Parameters\"");
366 /* set default values for fields that might not be present in the bitstream
367 and have valid defaults */
368 hrd->initial_cpb_removal_delay_length_minus1 = 23;
369 hrd->au_cpb_removal_delay_length_minus1 = 23;
370 hrd->dpb_output_delay_length_minus1 = 23;
372 if (commonInfPresentFlag) {
373 READ_UINT8 (nr, hrd->nal_hrd_parameters_present_flag, 1);
374 READ_UINT8 (nr, hrd->vcl_hrd_parameters_present_flag, 1);
376 if (hrd->nal_hrd_parameters_present_flag
377 || hrd->vcl_hrd_parameters_present_flag) {
379 READ_UINT8 (nr, hrd->sub_pic_hrd_params_present_flag, 1);
381 if (hrd->sub_pic_hrd_params_present_flag) {
382 READ_UINT8 (nr, hrd->tick_divisor_minus2, 8);
383 READ_UINT8 (nr, hrd->du_cpb_removal_delay_increment_length_minus1, 5);
384 READ_UINT8 (nr, hrd->sub_pic_cpb_params_in_pic_timing_sei_flag, 1);
385 READ_UINT8 (nr, hrd->dpb_output_delay_du_length_minus1, 5);
388 READ_UINT8 (nr, hrd->bit_rate_scale, 4);
389 READ_UINT8 (nr, hrd->cpb_size_scale, 4);
391 if (hrd->sub_pic_hrd_params_present_flag)
392 READ_UINT8 (nr, hrd->cpb_size_du_scale, 4);
394 READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
395 READ_UINT8 (nr, hrd->au_cpb_removal_delay_length_minus1, 5);
396 READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
400 for (i = 0; i <= maxNumSubLayersMinus1; i++) {
401 READ_UINT8 (nr, hrd->fixed_pic_rate_general_flag[i], 1);
403 if (!hrd->fixed_pic_rate_general_flag[i]) {
404 READ_UINT8 (nr, hrd->fixed_pic_rate_within_cvs_flag[i], 1);
406 hrd->fixed_pic_rate_within_cvs_flag[i] = 1;
408 if (hrd->fixed_pic_rate_within_cvs_flag[i]) {
409 READ_UE_MAX (nr, hrd->elemental_duration_in_tc_minus1[i], 2047);
411 READ_UINT8 (nr, hrd->low_delay_hrd_flag[i], 1);
413 if (!hrd->low_delay_hrd_flag[i])
414 READ_UE_MAX (nr, hrd->cpb_cnt_minus1[i], 31);
416 if (hrd->nal_hrd_parameters_present_flag)
417 if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
418 [i], nr, hrd->cpb_cnt_minus1[i],
419 hrd->sub_pic_hrd_params_present_flag))
422 if (hrd->vcl_hrd_parameters_present_flag)
423 if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
424 [i], nr, hrd->cpb_cnt_minus1[i],
425 hrd->sub_pic_hrd_params_present_flag))
432 GST_WARNING ("error parsing \"HRD Parameters\"");
437 gst_h265_parse_vui_parameters (GstH265SPS * sps, NalReader * nr)
439 GstH265VUIParams *vui = &sps->vui_params;
441 GST_DEBUG ("parsing \"VUI Parameters\"");
443 /* set default values for fields that might not be present in the bitstream
444 and have valid defaults */
445 vui->video_format = 5;
446 vui->colour_primaries = 2;
447 vui->transfer_characteristics = 2;
448 vui->matrix_coefficients = 2;
449 vui->motion_vectors_over_pic_boundaries_flag = 1;
450 vui->max_bytes_per_pic_denom = 2;
451 vui->max_bits_per_min_cu_denom = 1;
452 vui->log2_max_mv_length_horizontal = 15;
453 vui->log2_max_mv_length_vertical = 15;
455 if (sps && sps->profile_tier_level.progressive_source_flag
456 && sps->profile_tier_level.interlaced_source_flag)
457 vui->frame_field_info_present_flag = 1;
459 READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
460 if (vui->aspect_ratio_info_present_flag) {
461 READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
462 if (vui->aspect_ratio_idc == EXTENDED_SAR) {
463 READ_UINT16 (nr, vui->sar_width, 16);
464 READ_UINT16 (nr, vui->sar_height, 16);
465 vui->par_n = vui->sar_width;
466 vui->par_d = vui->sar_height;
467 } else if (vui->aspect_ratio_idc <= 16) {
468 vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
469 vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
473 READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
474 if (vui->overscan_info_present_flag)
475 READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);
477 READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
478 if (vui->video_signal_type_present_flag) {
480 READ_UINT8 (nr, vui->video_format, 3);
481 READ_UINT8 (nr, vui->video_full_range_flag, 1);
482 READ_UINT8 (nr, vui->colour_description_present_flag, 1);
483 if (vui->colour_description_present_flag) {
484 READ_UINT8 (nr, vui->colour_primaries, 8);
485 READ_UINT8 (nr, vui->transfer_characteristics, 8);
486 READ_UINT8 (nr, vui->matrix_coefficients, 8);
490 READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
491 if (vui->chroma_loc_info_present_flag) {
492 READ_UE_MAX (nr, vui->chroma_sample_loc_type_top_field, 5);
493 READ_UE_MAX (nr, vui->chroma_sample_loc_type_bottom_field, 5);
496 READ_UINT8 (nr, vui->neutral_chroma_indication_flag, 1);
497 READ_UINT8 (nr, vui->field_seq_flag, 1);
498 READ_UINT8 (nr, vui->frame_field_info_present_flag, 1);
500 READ_UINT8 (nr, vui->default_display_window_flag, 1);
501 if (vui->default_display_window_flag) {
502 READ_UE (nr, vui->def_disp_win_left_offset);
503 READ_UE (nr, vui->def_disp_win_right_offset);
504 READ_UE (nr, vui->def_disp_win_top_offset);
505 READ_UE (nr, vui->def_disp_win_bottom_offset);
508 READ_UINT8 (nr, vui->timing_info_present_flag, 1);
509 if (vui->timing_info_present_flag) {
510 READ_UINT32 (nr, vui->num_units_in_tick, 32);
511 if (vui->num_units_in_tick == 0)
512 GST_WARNING ("num_units_in_tick = 0 detected in stream "
513 "(incompliant to H.265 E.2.1).");
515 READ_UINT32 (nr, vui->time_scale, 32);
516 if (vui->time_scale == 0)
517 GST_WARNING ("time_scale = 0 detected in stream "
518 "(incompliant to H.265 E.2.1).");
520 READ_UINT8 (nr, vui->poc_proportional_to_timing_flag, 1);
521 if (vui->poc_proportional_to_timing_flag)
522 READ_UE_MAX (nr, vui->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
524 READ_UINT8 (nr, vui->hrd_parameters_present_flag, 1);
525 if (vui->hrd_parameters_present_flag)
526 if (!gst_h265_parse_hrd_parameters (&vui->hrd_params, nr, 1,
527 sps->max_sub_layers_minus1))
531 READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
532 if (vui->bitstream_restriction_flag) {
533 READ_UINT8 (nr, vui->tiles_fixed_structure_flag, 1);
534 READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
535 READ_UINT8 (nr, vui->restricted_ref_pic_lists_flag, 1);
536 READ_UE_MAX (nr, vui->min_spatial_segmentation_idc, 4096);
537 READ_UE_MAX (nr, vui->max_bytes_per_pic_denom, 16);
538 READ_UE_MAX (nr, vui->max_bits_per_min_cu_denom, 16);
539 READ_UE_MAX (nr, vui->log2_max_mv_length_horizontal, 16);
540 READ_UE_MAX (nr, vui->log2_max_mv_length_vertical, 15);
546 GST_WARNING ("error parsing \"VUI Parameters\"");
551 get_scaling_list_params (GstH265ScalingList * dest_scaling_list,
552 guint8 sizeId, guint8 matrixId, guint8 ** sl, guint8 * size,
553 gint16 ** scaling_list_dc_coef_minus8)
556 case GST_H265_QUANT_MATIX_4X4:
557 *sl = dest_scaling_list->scaling_lists_4x4[matrixId];
561 case GST_H265_QUANT_MATIX_8X8:
562 *sl = dest_scaling_list->scaling_lists_8x8[matrixId];
566 case GST_H265_QUANT_MATIX_16X16:
567 *sl = dest_scaling_list->scaling_lists_16x16[matrixId];
570 if (scaling_list_dc_coef_minus8)
571 *scaling_list_dc_coef_minus8 =
572 dest_scaling_list->scaling_list_dc_coef_minus8_16x16;
574 case GST_H265_QUANT_MATIX_32X32:
575 *sl = dest_scaling_list->scaling_lists_32x32[matrixId];
578 if (scaling_list_dc_coef_minus8)
579 *scaling_list_dc_coef_minus8 =
580 dest_scaling_list->scaling_list_dc_coef_minus8_32x32;
589 get_default_scaling_lists (guint8 ** sl, guint8 sizeId, guint8 matrixId)
592 case GST_H265_QUANT_MATIX_4X4:
593 memcpy (*sl, default_scaling_list0, 16);
596 case GST_H265_QUANT_MATIX_8X8:
597 case GST_H265_QUANT_MATIX_16X16:
599 memcpy (*sl, default_scaling_list1, 64);
601 memcpy (*sl, default_scaling_list2, 64);
604 case GST_H265_QUANT_MATIX_32X32:
606 memcpy (*sl, default_scaling_list1, 64);
608 memcpy (*sl, default_scaling_list2, 64);
619 gst_h265_parser_parse_scaling_lists (NalReader * nr,
620 GstH265ScalingList * dest_scaling_list, gboolean use_default)
624 guint8 scaling_list_pred_mode_flag = 0;
625 guint8 scaling_list_pred_matrix_id_delta = 0;
628 GST_DEBUG ("parsing scaling lists");
630 for (sizeId = 0; sizeId < 4; sizeId++) {
631 for (matrixId = 0; matrixId < ((sizeId == 3) ? 2 : 6); matrixId++) {
632 gint16 *scaling_list_dc_coef_minus8 = NULL;
635 if (!get_scaling_list_params (dest_scaling_list, sizeId, matrixId, &sl,
636 &size, &scaling_list_dc_coef_minus8))
639 /* use_default_scaling_matrices forcefully which means,
640 * sps_scaling_list_enabled_flag=TRUE,
641 * sps_scaling_list_data_present_flag=FALSE,
642 * pps_scaling_list_data_present_falg=FALSE */
644 if (!get_default_scaling_lists (&sl, sizeId, matrixId))
647 /* Inferring the value of scaling_list_dc_coef_minus8 */
649 scaling_list_dc_coef_minus8[matrixId] = 8;
652 READ_UINT8 (nr, scaling_list_pred_mode_flag, 1);
654 if (!scaling_list_pred_mode_flag) {
657 READ_UE_MAX (nr, scaling_list_pred_matrix_id_delta, matrixId);
659 if (!scaling_list_pred_matrix_id_delta) {
660 if (!get_default_scaling_lists (&sl, sizeId, matrixId))
663 /* Inferring the value of scaling_list_dc_coef_minus8 */
665 scaling_list_dc_coef_minus8[matrixId] = 8;
670 refMatrixId = matrixId - scaling_list_pred_matrix_id_delta; /* 7-30 */
672 if (!get_scaling_list_params (dest_scaling_list, sizeId,
673 refMatrixId, &temp_sl, NULL, NULL))
676 for (i = 0; i < size; i++)
677 sl[i] = temp_sl[i]; /* 7-31 */
680 /* Inferring the value of scaling_list_dc_coef_minus8 */
682 scaling_list_dc_coef_minus8[matrixId] =
683 scaling_list_dc_coef_minus8[refMatrixId];
687 gint8 scaling_list_delta_coef;
690 READ_SE_ALLOWED (nr, scaling_list_dc_coef_minus8[matrixId], -7,
692 nextCoef = scaling_list_dc_coef_minus8[matrixId] + 8;
695 for (i = 0; i < size; i++) {
696 READ_SE_ALLOWED (nr, scaling_list_delta_coef, -128, 127);
697 nextCoef = (nextCoef + scaling_list_delta_coef) & 0xff;
708 GST_WARNING ("error parsing scaling lists");
713 gst_h265_parser_parse_short_term_ref_pic_sets (GstH265ShortTermRefPicSet *
714 stRPS, NalReader * nr, guint8 stRpsIdx, GstH265SPS * sps)
716 guint8 num_short_term_ref_pic_sets;
717 guint8 RefRpsIdx = 0;
719 guint8 use_delta_flag[16] = { 0 };
720 guint8 used_by_curr_pic_flag[16] = { 0 };
721 guint32 delta_poc_s0_minus1[16] = { 0 };
722 guint32 delta_poc_s1_minus1[16] = { 0 };
726 GST_DEBUG ("parsing \"ShortTermRefPicSetParameters\"");
728 /* set default values for fields that might not be present in the bitstream
729 and have valid defaults */
730 for (j = 0; j < 16; j++)
731 use_delta_flag[j] = 1;
733 num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
736 READ_UINT8 (nr, stRPS->inter_ref_pic_set_prediction_flag, 1);
738 if (stRPS->inter_ref_pic_set_prediction_flag) {
739 GstH265ShortTermRefPicSet *RefRPS;
741 if (stRpsIdx == num_short_term_ref_pic_sets)
742 READ_UE_MAX (nr, stRPS->delta_idx_minus1, stRpsIdx - 1);
744 READ_UINT8 (nr, stRPS->delta_rps_sign, 1);
745 READ_UE_MAX (nr, stRPS->abs_delta_rps_minus1, 32767);
747 RefRpsIdx = stRpsIdx - stRPS->delta_idx_minus1 - 1; /* 7-45 */
748 deltaRps = (1 - 2 * stRPS->delta_rps_sign) * (stRPS->abs_delta_rps_minus1 + 1); /* 7-46 */
750 RefRPS = &sps->short_term_ref_pic_set[RefRpsIdx];
752 for (j = 0; j <= RefRPS->NumDeltaPocs; j++) {
753 READ_UINT8 (nr, used_by_curr_pic_flag[j], 1);
754 if (!used_by_curr_pic_flag[j])
755 READ_UINT8 (nr, use_delta_flag[j], 1);
758 /* 7-47: calculate NumNegativePics, DeltaPocS0 and UsedByCurrPicS0 */
760 for (j = (RefRPS->NumPositivePics - 1); j >= 0; j--) {
761 dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
762 if (dPoc < 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
763 stRPS->DeltaPocS0[i] = dPoc;
764 stRPS->UsedByCurrPicS0[i++] =
765 used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
768 if (deltaRps < 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
769 stRPS->DeltaPocS0[i] = deltaRps;
770 stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
772 for (j = 0; j < RefRPS->NumNegativePics; j++) {
773 dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
774 if (dPoc < 0 && use_delta_flag[j]) {
775 stRPS->DeltaPocS0[i] = dPoc;
776 stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[j];
779 stRPS->NumNegativePics = i;
781 /* 7-48: calculate NumPositivePics, DeltaPocS1 and UsedByCurrPicS1 */
783 for (j = (RefRPS->NumNegativePics - 1); j >= 0; j--) {
784 dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
785 if (dPoc > 0 && use_delta_flag[j]) {
786 stRPS->DeltaPocS1[i] = dPoc;
787 stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[j];
790 if (deltaRps > 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
791 stRPS->DeltaPocS1[i] = deltaRps;
792 stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
794 for (j = 0; j < RefRPS->NumPositivePics; j++) {
795 dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
796 if (dPoc > 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
797 stRPS->DeltaPocS1[i] = dPoc;
798 stRPS->UsedByCurrPicS1[i++] =
799 used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
802 stRPS->NumPositivePics = i;
806 READ_UE_MAX (nr, stRPS->NumNegativePics,
807 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1]);
810 READ_UE_MAX (nr, stRPS->NumPositivePics,
811 (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] -
812 stRPS->NumNegativePics));
814 for (i = 0; i < stRPS->NumNegativePics; i++) {
815 READ_UE_MAX (nr, delta_poc_s0_minus1[i], 32767);
817 READ_UINT8 (nr, stRPS->UsedByCurrPicS0[i], 1);
821 stRPS->DeltaPocS0[i] = -(delta_poc_s0_minus1[i] + 1);
824 stRPS->DeltaPocS0[i] =
825 stRPS->DeltaPocS0[i - 1] - (delta_poc_s0_minus1[i] + 1);
829 for (j = 0; j < stRPS->NumPositivePics; j++) {
830 READ_UE_MAX (nr, delta_poc_s1_minus1[j], 32767);
833 READ_UINT8 (nr, stRPS->UsedByCurrPicS1[j], 1);
837 stRPS->DeltaPocS1[j] = delta_poc_s1_minus1[j] + 1;
840 stRPS->DeltaPocS1[j] =
841 stRPS->DeltaPocS1[j - 1] + (delta_poc_s1_minus1[j] + 1);
848 stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;
853 GST_WARNING ("error parsing \"ShortTermRefPicSet Parameters\"");
858 gst_h265_slice_parse_ref_pic_list_modification (GstH265SliceHdr * slice,
859 NalReader * nr, gint NumPocTotalCurr)
862 GstH265RefPicListModification *rpl_mod = &slice->ref_pic_list_modification;
863 const guint n = ceil_log2 (NumPocTotalCurr);
865 READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l0, 1);
867 if (rpl_mod->ref_pic_list_modification_flag_l0) {
868 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
869 READ_UINT32 (nr, rpl_mod->list_entry_l0[i], n);
870 CHECK_ALLOWED_MAX (rpl_mod->list_entry_l0[i], (NumPocTotalCurr - 1));
873 if (GST_H265_IS_B_SLICE (slice)) {
874 READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l1, 1);
875 if (rpl_mod->ref_pic_list_modification_flag_l1)
876 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
877 READ_UINT32 (nr, rpl_mod->list_entry_l1[i], n);
878 CHECK_ALLOWED_MAX (rpl_mod->list_entry_l1[i], (NumPocTotalCurr - 1));
885 GST_WARNING ("error parsing \"Prediction weight table\"");
890 gst_h265_slice_parse_pred_weight_table (GstH265SliceHdr * slice, NalReader * nr)
892 GstH265PredWeightTable *p;
894 GstH265PPS *pps = slice->pps;
895 GstH265SPS *sps = pps->sps;
897 GST_DEBUG ("parsing \"Prediction weight table\"");
899 p = &slice->pred_weight_table;
901 READ_UE_MAX (nr, p->luma_log2_weight_denom, 7);
903 if (sps->chroma_format_idc != 0) {
904 READ_SE_ALLOWED (nr, p->delta_chroma_log2_weight_denom,
905 (0 - p->luma_log2_weight_denom), (7 - p->luma_log2_weight_denom));
908 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
909 READ_UINT8 (nr, p->luma_weight_l0_flag[i], 1);
911 if (sps->chroma_format_idc != 0)
912 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
913 READ_UINT8 (nr, p->chroma_weight_l0_flag[i], 1);
915 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
916 if (p->luma_weight_l0_flag[i]) {
917 READ_SE_ALLOWED (nr, p->delta_luma_weight_l0[i], -128, 127);
918 READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
920 if (p->chroma_weight_l0_flag[i])
921 for (j = 0; j < 2; j++) {
922 READ_SE_ALLOWED (nr, p->delta_chroma_weight_l0[i][j], -128, 127);
923 READ_SE_ALLOWED (nr, p->delta_chroma_offset_l0[i][j], -512, 511);
927 if (GST_H265_IS_B_SLICE (slice)) {
928 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
929 READ_UINT8 (nr, p->luma_weight_l1_flag[i], 1);
930 if (sps->chroma_format_idc != 0)
931 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
932 READ_UINT8 (nr, p->chroma_weight_l1_flag[i], 1);
934 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
935 if (p->luma_weight_l1_flag[i]) {
936 READ_SE_ALLOWED (nr, p->delta_luma_weight_l1[i], -128, 127);
937 READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
939 if (p->chroma_weight_l1_flag[i])
940 for (j = 0; j < 2; j++) {
941 READ_SE_ALLOWED (nr, p->delta_chroma_weight_l1[i][j], -128, 127);
942 READ_SE_ALLOWED (nr, p->delta_chroma_offset_l1[i][j], -512, 511);
950 GST_WARNING ("error parsing \"Prediction weight table\"");
954 static GstH265ParserResult
955 gst_h265_parser_parse_buffering_period (GstH265Parser * parser,
956 GstH265BufferingPeriod * per, NalReader * nr)
963 GST_DEBUG ("parsing \"Buffering period\"");
965 READ_UE_MAX (nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
966 sps = gst_h265_parser_get_sps (parser, sps_id);
968 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
970 return GST_H265_PARSER_BROKEN_LINK;
974 if (sps->vui_parameters_present_flag) {
975 GstH265VUIParams *vui = &sps->vui_params;
976 GstH265HRDParams *hrd = &vui->hrd_params;
978 if (!hrd->sub_pic_hrd_params_present_flag)
979 READ_UINT8 (nr, per->irap_cpb_params_present_flag, 1);
981 if (per->irap_cpb_params_present_flag) {
982 READ_UINT8 (nr, per->cpb_delay_offset,
983 (hrd->au_cpb_removal_delay_length_minus1 + 1));
984 READ_UINT8 (nr, per->dpb_delay_offset,
985 (hrd->dpb_output_delay_length_minus1 + 1));
988 n = hrd->initial_cpb_removal_delay_length_minus1 + 1;
990 READ_UINT8 (nr, per->concatenation_flag, 1);
991 READ_UINT8 (nr, per->au_cpb_removal_delay_delta_minus1,
992 (hrd->au_cpb_removal_delay_length_minus1 + 1));
994 if (hrd->nal_hrd_parameters_present_flag) {
995 for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
996 READ_UINT8 (nr, per->nal_initial_cpb_removal_delay[i], n);
997 READ_UINT8 (nr, per->nal_initial_cpb_removal_offset[i], n);
998 if (hrd->sub_pic_hrd_params_present_flag
999 || per->irap_cpb_params_present_flag) {
1000 READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_delay[i], n);
1001 READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_offset[i], n);
1006 if (hrd->vcl_hrd_parameters_present_flag) {
1007 for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
1008 READ_UINT8 (nr, per->vcl_initial_cpb_removal_delay[i], n);
1009 READ_UINT8 (nr, per->vcl_initial_cpb_removal_offset[i], n);
1010 if (hrd->sub_pic_hrd_params_present_flag
1011 || per->irap_cpb_params_present_flag) {
1012 READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_delay[i], n);
1013 READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_offset[i], n);
1019 return GST_H265_PARSER_OK;
1022 GST_WARNING ("error parsing \"Buffering period\"");
1023 return GST_H265_PARSER_ERROR;
1026 static GstH265ParserResult
1027 gst_h265_parser_parse_pic_timing (GstH265Parser * parser,
1028 GstH265PicTiming * tim, NalReader * nr)
1030 GstH265ProfileTierLevel *profile_tier_level;
1033 GST_DEBUG ("parsing \"Picture timing\"");
1034 if (!parser->last_sps || !parser->last_sps->valid) {
1035 GST_WARNING ("didn't get the associated sequence parameter set for the "
1036 "current access unit");
1040 profile_tier_level = &parser->last_sps->profile_tier_level;
1042 /* set default values */
1043 if (!profile_tier_level->progressive_source_flag
1044 && profile_tier_level->interlaced_source_flag)
1045 tim->source_scan_type = 0;
1046 else if (profile_tier_level->progressive_source_flag
1047 && !profile_tier_level->interlaced_source_flag)
1048 tim->source_scan_type = 1;
1050 tim->source_scan_type = 2;
1052 if (parser->last_sps->vui_parameters_present_flag) {
1053 GstH265VUIParams *vui = &parser->last_sps->vui_params;
1055 if (vui->frame_field_info_present_flag) {
1056 READ_UINT8 (nr, tim->pic_struct, 4);
1057 READ_UINT8 (nr, tim->source_scan_type, 2);
1058 READ_UINT8 (nr, tim->duplicate_flag, 1);
1060 /* set default values */
1061 tim->pic_struct = 0;
1064 if (vui->hrd_parameters_present_flag) {
1065 GstH265HRDParams *hrd = &vui->hrd_params;
1067 READ_UINT8 (nr, tim->au_cpb_removal_delay_minus1,
1068 (hrd->au_cpb_removal_delay_length_minus1 + 1));
1069 READ_UINT8 (nr, tim->pic_dpb_output_delay,
1070 (hrd->dpb_output_delay_length_minus1 + 1));
1072 if (hrd->sub_pic_hrd_params_present_flag)
1073 READ_UINT8 (nr, tim->pic_dpb_output_du_delay,
1074 (hrd->dpb_output_delay_du_length_minus1 + 1));
1076 if (hrd->sub_pic_hrd_params_present_flag
1077 && hrd->sub_pic_cpb_params_in_pic_timing_sei_flag) {
1078 READ_UE (nr, tim->num_decoding_units_minus1);
1080 READ_UINT8 (nr, tim->du_common_cpb_removal_delay_flag, 1);
1081 if (tim->du_common_cpb_removal_delay_flag)
1082 READ_UINT8 (nr, tim->du_common_cpb_removal_delay_increment_minus1,
1083 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1085 tim->num_nalus_in_du_minus1 =
1086 g_new0 (guint32, (tim->num_decoding_units_minus1 + 1));
1087 tim->du_cpb_removal_delay_increment_minus1 =
1088 g_new0 (guint8, (tim->num_decoding_units_minus1 + 1));
1090 for (i = 0; i <= (tim->num_decoding_units_minus1 + 1); i++) {
1091 READ_UE (nr, tim->num_nalus_in_du_minus1[i]);
1093 if (!tim->du_common_cpb_removal_delay_flag
1094 && (i < tim->num_decoding_units_minus1))
1095 READ_UINT8 (nr, tim->du_cpb_removal_delay_increment_minus1[i],
1096 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1101 return GST_H265_PARSER_OK;
1104 GST_WARNING ("error parsing \"Picture timing\"");
1105 return GST_H265_PARSER_ERROR;
1108 static GstH265ParserResult
1109 gst_h265_parser_parse_recovery_point (GstH265Parser * parser,
1110 GstH265RecoveryPoint * rp, NalReader * nr)
1112 GstH265SPS *const sps = parser->last_sps;
1113 gint32 max_pic_order_cnt_lsb;
1115 GST_DEBUG ("parsing \"Recovery point\"");
1116 if (!sps || !sps->valid) {
1117 GST_WARNING ("didn't get the associated sequence parameter set for the "
1118 "current access unit");
1122 max_pic_order_cnt_lsb = pow (2, (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
1123 READ_SE_ALLOWED (nr, rp->recovery_poc_cnt, -max_pic_order_cnt_lsb / 2,
1124 max_pic_order_cnt_lsb - 1);
1125 READ_UINT8 (nr, rp->exact_match_flag, 1);
1126 READ_UINT8 (nr, rp->broken_link_flag, 1);
1128 return GST_H265_PARSER_OK;
1131 GST_WARNING ("error parsing \"Recovery point\"");
1132 return GST_H265_PARSER_ERROR;
1136 static GstH265ParserResult
1137 gst_h265_parser_parse_registered_user_data (GstH265Parser * parser,
1138 GstH265RegisteredUserData * rud, NalReader * nr, guint payload_size)
1140 guint8 *data = NULL;
1146 if (payload_size < 2)
1147 return GST_H265_PARSER_ERROR;
1149 READ_UINT8 (nr, rud->country_code, 8);
1152 if (rud->country_code == 0xFF) {
1153 READ_UINT8 (nr, rud->country_code_extension, 8);
1156 rud->country_code_extension = 0;
1159 if (payload_size < 8)
1160 return GST_H265_PARSER_ERROR;
1162 data = g_malloc (payload_size);
1163 for (i = 0; i < payload_size / 8; ++i) {
1164 READ_UINT8 (nr, data[i], 8);
1167 GST_MEMDUMP ("SEI user data", data, payload_size / 8);
1170 rud->size = payload_size;
1171 return GST_H265_PARSER_OK;
1175 GST_WARNING ("error parsing \"Registered User Data\"");
1177 return GST_H265_PARSER_ERROR;
1182 static GstH265ParserResult
1183 gst_h265_parser_parse_time_code (GstH265Parser * parser,
1184 GstH265TimeCode * tc, NalReader * nr)
1188 GST_DEBUG ("parsing \"Time code\"");
1190 READ_UINT8 (nr, tc->num_clock_ts, 2);
1192 for (i = 0; i < tc->num_clock_ts; i++) {
1193 READ_UINT8 (nr, tc->clock_timestamp_flag[i], 1);
1194 if (tc->clock_timestamp_flag[i]) {
1195 READ_UINT8 (nr, tc->units_field_based_flag[i], 1);
1196 READ_UINT8 (nr, tc->counting_type[i], 5);
1197 READ_UINT8 (nr, tc->full_timestamp_flag[i], 1);
1198 READ_UINT8 (nr, tc->discontinuity_flag[i], 1);
1199 READ_UINT8 (nr, tc->cnt_dropped_flag[i], 1);
1200 READ_UINT16 (nr, tc->n_frames[i], 9);
1202 if (tc->full_timestamp_flag[i]) {
1203 tc->seconds_flag[i] = TRUE;
1204 READ_UINT8 (nr, tc->seconds_value[i], 6);
1206 tc->minutes_flag[i] = TRUE;
1207 READ_UINT8 (nr, tc->minutes_value[i], 6);
1209 tc->hours_flag[i] = TRUE;
1210 READ_UINT8 (nr, tc->hours_value[i], 5);
1212 READ_UINT8 (nr, tc->seconds_flag[i], 1);
1213 if (tc->seconds_flag[i]) {
1214 READ_UINT8 (nr, tc->seconds_value[i], 6);
1215 READ_UINT8 (nr, tc->minutes_flag[i], 1);
1216 if (tc->minutes_flag[i]) {
1217 READ_UINT8 (nr, tc->minutes_value[i], 6);
1218 READ_UINT8 (nr, tc->hours_flag[i], 1);
1219 if (tc->hours_flag[i]) {
1220 READ_UINT8 (nr, tc->hours_value[i], 5);
1227 READ_UINT8 (nr, tc->time_offset_length[i], 5);
1229 if (tc->time_offset_length[i] > 0)
1230 READ_UINT32 (nr, tc->time_offset_value[i], tc->time_offset_length[i]);
1233 return GST_H265_PARSER_OK;
1236 GST_WARNING ("error parsing \"Time code\"");
1237 return GST_H265_PARSER_ERROR;
1240 static GstH265ParserResult
1241 gst_h265_parser_parse_mastering_display_colour_volume (GstH265Parser * parser,
1242 GstH265MasteringDisplayColourVolume * mdcv, NalReader * nr)
1246 GST_DEBUG ("parsing \"Mastering display colour volume\"");
1248 for (i = 0; i < 3; i++) {
1249 READ_UINT16 (nr, mdcv->display_primaries_x[i], 16);
1250 READ_UINT16 (nr, mdcv->display_primaries_y[i], 16);
1253 READ_UINT16 (nr, mdcv->white_point_x, 16);
1254 READ_UINT16 (nr, mdcv->white_point_y, 16);
1255 READ_UINT32 (nr, mdcv->max_display_mastering_luminance, 32);
1256 READ_UINT32 (nr, mdcv->min_display_mastering_luminance, 32);
1258 return GST_H265_PARSER_OK;
1261 GST_WARNING ("error parsing \"Mastering display colour volume\"");
1262 return GST_H265_PARSER_ERROR;
1265 static GstH265ParserResult
1266 gst_h265_parser_parse_content_light_level_info (GstH265Parser * parser,
1267 GstH265ContentLightLevel * cll, NalReader * nr)
1269 GST_DEBUG ("parsing \"Content light level\"");
1271 READ_UINT16 (nr, cll->max_content_light_level, 16);
1272 READ_UINT16 (nr, cll->max_pic_average_light_level, 16);
1274 return GST_H265_PARSER_OK;
1277 GST_WARNING ("error parsing \"Content light level\"");
1278 return GST_H265_PARSER_ERROR;
1281 /******** API *************/
1284 * gst_h265_parser_new:
1286 * Creates a new #GstH265Parser. It should be freed with
1287 * gst_h265_parser_free after use.
1289 * Returns: a new #GstH265Parser
1292 gst_h265_parser_new (void)
1294 GstH265Parser *parser;
1296 parser = g_slice_new0 (GstH265Parser);
1302 * gst_h265_parser_free:
1303 * @parser: the #GstH265Parser to free
1305 * Frees @parser and sets it to %NULL
1308 gst_h265_parser_free (GstH265Parser * parser)
1310 g_slice_free (GstH265Parser, parser);
1315 * gst_h265_parser_identify_nalu_unchecked:
1316 * @parser: a #GstH265Parser
1317 * @data: The data to parse
1318 * @offset: the offset from which to parse @data
1319 * @size: the size of @data
1320 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1322 * Parses @data and fills @nalu from the next nalu data from @data.
1324 * This differs from @gst_h265_parser_identify_nalu in that it doesn't
1325 * check whether the packet is complete or not.
1327 * Note: Only use this function if you already know the provided @data
1328 * is a complete NALU, else use @gst_h265_parser_identify_nalu.
1330 * Returns: a #GstH265ParserResult
1333 gst_h265_parser_identify_nalu_unchecked (GstH265Parser * parser,
1334 const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1338 memset (nalu, 0, sizeof (*nalu));
1340 if (size < offset + 4) {
1341 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1342 ", offset %u", size, offset);
1343 return GST_H265_PARSER_ERROR;
1346 off1 = scan_for_start_codes (data + offset, size - offset);
1349 GST_DEBUG ("No start code prefix in this buffer");
1350 return GST_H265_PARSER_NO_NAL;
1353 if (offset + off1 == size - 1) {
1354 GST_DEBUG ("Missing data to identify nal unit");
1356 return GST_H265_PARSER_ERROR;
1359 nalu->sc_offset = offset + off1;
1361 /* sc might have 2 or 3 0-bytes */
1362 if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
1365 nalu->offset = offset + off1 + 3;
1366 nalu->data = (guint8 *) data;
1367 nalu->size = size - nalu->offset;
1369 if (!gst_h265_parse_nalu_header (nalu)) {
1370 GST_WARNING ("error parsing \"NAL unit header\"");
1372 return GST_H265_PARSER_BROKEN_DATA;
1377 if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB) {
1378 GST_DEBUG ("end-of-seq or end-of-stream nal found");
1380 return GST_H265_PARSER_OK;
1383 return GST_H265_PARSER_OK;
1387 * gst_h265_parser_identify_nalu:
1388 * @parser: a #GstH265Parser
1389 * @data: The data to parse
1390 * @offset: the offset from which to parse @data
1391 * @size: the size of @data
1392 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1394 * Parses @data and fills @nalu from the next nalu data from @data
1396 * Returns: a #GstH265ParserResult
1399 gst_h265_parser_identify_nalu (GstH265Parser * parser,
1400 const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1402 GstH265ParserResult res;
1406 gst_h265_parser_identify_nalu_unchecked (parser, data, offset, size,
1409 if (res != GST_H265_PARSER_OK)
1412 /* The two NALs are exactly 2 bytes size and are placed at the end of an AU,
1413 * there is no need to wait for the following */
1414 if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB)
1417 off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1419 GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1421 return GST_H265_PARSER_NO_NAL_END;
1424 /* Mini performance improvement:
1425 * We could have a way to store how many 0s were skipped to avoid
1426 * parsing them again on the next NAL */
1427 while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1432 return GST_H265_PARSER_BROKEN_DATA;
1434 GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1441 * gst_h265_parser_identify_nalu_hevc:
1442 * @parser: a #GstH265Parser
1443 * @data: The data to parse, must be the beging of the Nal unit
1444 * @offset: the offset from which to parse @data
1445 * @size: the size of @data
1446 * @nal_length_size: the size in bytes of the HEVC nal length prefix.
1447 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1449 * Parses @data and sets @nalu.
1451 * Returns: a #GstH265ParserResult
1454 gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
1455 const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1456 GstH265NalUnit * nalu)
1460 memset (nalu, 0, sizeof (*nalu));
1462 if (size < offset + nal_length_size) {
1463 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1464 ", offset %u", size, offset);
1465 return GST_H265_PARSER_ERROR;
1468 size = size - offset;
1469 gst_bit_reader_init (&br, data + offset, size);
1471 nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1472 nal_length_size * 8);
1473 nalu->sc_offset = offset;
1474 nalu->offset = offset + nal_length_size;
1476 if (size < nalu->size + nal_length_size) {
1479 return GST_H265_PARSER_NO_NAL_END;
1482 nalu->data = (guint8 *) data;
1484 if (!gst_h265_parse_nalu_header (nalu)) {
1485 GST_WARNING ("error parsing \"NAL unit header\"");
1487 return GST_H265_PARSER_BROKEN_DATA;
1491 return GST_H265_PARSER_BROKEN_DATA;
1495 return GST_H265_PARSER_OK;
1499 * gst_h265_parser_parse_nal:
1500 * @parser: a #GstH265Parser
1501 * @nalu: The #GstH265NalUnit to parse
1503 * This function should be called in the case one doesn't need to
1504 * parse a specific structure. It is necessary to do so to make
1505 * sure @parser is up to date.
1507 * Returns: a #GstH265ParserResult
1510 gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
1516 switch (nalu->type) {
1517 case GST_H265_NAL_VPS:
1518 return gst_h265_parser_parse_vps (parser, nalu, &vps);
1520 case GST_H265_NAL_SPS:
1521 return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
1523 case GST_H265_NAL_PPS:
1524 return gst_h265_parser_parse_pps (parser, nalu, &pps);
1527 return GST_H265_PARSER_OK;
1531 * gst_h265_parser_parse_vps:
1532 * @parser: a #GstH265Parser
1533 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1534 * @vps: The #GstH265VPS to fill.
1536 * Parses @data, and fills the @vps structure.
1538 * Returns: a #GstH265ParserResult
1541 gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
1544 GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);
1546 if (res == GST_H265_PARSER_OK) {
1547 GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);
1549 parser->vps[vps->id] = *vps;
1550 parser->last_vps = &parser->vps[vps->id];
1557 * gst_h265_parse_vps:
1558 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1559 * @sps: The #GstH265VPS to fill.
1561 * Parses @data, and fills the @vps structure.
1563 * Returns: a #GstH265ParserResult
1566 gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
1571 GST_DEBUG ("parsing VPS");
1573 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1574 nalu->size - nalu->header_bytes);
1576 memset (vps, 0, sizeof (*vps));
1578 vps->cprms_present_flag = 1;
1580 READ_UINT8 (&nr, vps->id, 4);
1582 READ_UINT8 (&nr, vps->base_layer_internal_flag, 1);
1583 READ_UINT8 (&nr, vps->base_layer_available_flag, 1);
1585 READ_UINT8 (&nr, vps->max_layers_minus1, 6);
1586 READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
1587 READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1589 /* skip reserved_0xffff_16bits */
1590 if (!nal_reader_skip (&nr, 16))
1593 if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1594 vps->max_sub_layers_minus1))
1597 READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1600 (vps->sub_layer_ordering_info_present_flag ? 0 :
1601 vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1602 READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1603 READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1604 vps->max_dec_pic_buffering_minus1[i]);
1605 READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1607 /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1608 if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1609 for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1610 vps->max_dec_pic_buffering_minus1[i] =
1611 vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1612 vps->max_num_reorder_pics[i] =
1613 vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1614 vps->max_latency_increase_plus1[i] =
1615 vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1619 READ_UINT8 (&nr, vps->max_layer_id, 6);
1620 /* shall allow 63 */
1621 CHECK_ALLOWED_MAX (vps->max_layer_id, 63);
1623 READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1624 /* allowed range is 0 to 1023 */
1625 CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 1023);
1627 for (i = 1; i <= vps->num_layer_sets_minus1; i++) {
1628 for (j = 0; j <= vps->max_layer_id; j++) {
1629 /* layer_id_included_flag[i][j] */
1630 /* FIXME: need to parse this when we can support parsing multi-layer info. */
1631 nal_reader_skip (&nr, 1);
1635 READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1637 if (vps->timing_info_present_flag) {
1638 READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1639 READ_UINT32 (&nr, vps->time_scale, 32);
1640 READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1642 if (vps->poc_proportional_to_timing_flag)
1643 READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1645 READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1647 * 0 to vps_num_layer_sets_minus1 + 1 */
1648 CHECK_ALLOWED_MAX (vps->num_hrd_parameters, vps->num_layer_sets_minus1 + 1);
1650 if (vps->num_hrd_parameters) {
1651 READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1653 * ( vps_base_layer_internal_flag ? 0 : 1 ) to vps_num_layer_sets_minus1
1655 CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, vps->num_layer_sets_minus1);
1657 if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1658 vps->cprms_present_flag, vps->max_sub_layers_minus1))
1662 /* FIXME: VPS can have multiple hrd parameters, and therefore hrd_params
1663 * should be an array (like Garray). But it also requires new _clear()
1664 * method for free the array in GstH265VPS whenever gst_h265_parse_vps()
1665 * is called. Need to work for multi-layer related parsing supporting
1667 * FIXME: Following code is just work around to find correct
1668 * vps_extension position */
1670 /* skip the first parsed one above */
1671 for (i = 1; i < vps->num_hrd_parameters; i++) {
1672 guint16 hrd_layer_set_idx;
1673 guint8 cprms_present_flag;
1674 GstH265HRDParams hrd_params;
1676 READ_UE_MAX (&nr, hrd_layer_set_idx, 1023);
1677 CHECK_ALLOWED_MAX (hrd_layer_set_idx, vps->num_layer_sets_minus1);
1679 /* need parsing if (i > 1) */
1680 READ_UINT8 (&nr, cprms_present_flag, 1);
1682 if (!gst_h265_parse_hrd_parameters (&hrd_params, &nr,
1683 cprms_present_flag, vps->max_sub_layers_minus1))
1687 READ_UINT8 (&nr, vps->vps_extension, 1);
1690 return GST_H265_PARSER_OK;
1693 GST_WARNING ("error parsing \"Video parameter set\"");
1695 return GST_H265_PARSER_ERROR;
1699 * gst_h265_parser_parse_sps:
1700 * @parser: a #GstH265Parser
1701 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1702 * @sps: The #GstH265SPS to fill.
1703 * @parse_vui_params: Whether to parse the vui_params or not
1705 * Parses @data, and fills the @sps structure.
1707 * Returns: a #GstH265ParserResult
1710 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1711 GstH265SPS * sps, gboolean parse_vui_params)
1713 GstH265ParserResult res =
1714 gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1716 if (res == GST_H265_PARSER_OK) {
1717 GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1719 parser->sps[sps->id] = *sps;
1720 parser->last_sps = &parser->sps[sps->id];
1727 * gst_h265_parse_sps:
1728 * parser: The #GstH265Parser
1729 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1730 * @sps: The #GstH265SPS to fill.
1731 * @parse_vui_params: Whether to parse the vui_params or not
1733 * Parses @data, and fills the @sps structure.
1735 * Returns: a #GstH265ParserResult
1738 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1739 GstH265SPS * sps, gboolean parse_vui_params)
1745 guint subwc[] = { 1, 2, 2, 1, 1 };
1746 guint subhc[] = { 1, 2, 1, 1, 1 };
1747 GstH265VUIParams *vui = NULL;
1749 GST_DEBUG ("parsing SPS");
1751 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1752 nalu->size - nalu->header_bytes);
1754 memset (sps, 0, sizeof (*sps));
1756 READ_UINT8 (&nr, vps_id, 4);
1757 vps = gst_h265_parser_get_vps (parser, vps_id);
1759 GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1764 READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1765 READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1767 if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1768 sps->max_sub_layers_minus1))
1771 READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1773 READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1774 if (sps->chroma_format_idc == 3)
1775 READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1777 READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1778 READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1780 READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1781 if (sps->conformance_window_flag) {
1782 READ_UE (&nr, sps->conf_win_left_offset);
1783 READ_UE (&nr, sps->conf_win_right_offset);
1784 READ_UE (&nr, sps->conf_win_top_offset);
1785 READ_UE (&nr, sps->conf_win_bottom_offset);
1788 READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1789 READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1790 READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1792 READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1794 (sps->sub_layer_ordering_info_present_flag ? 0 :
1795 sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1796 READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1797 READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1798 sps->max_dec_pic_buffering_minus1[i]);
1799 READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1801 /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1802 if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1803 for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1804 sps->max_dec_pic_buffering_minus1[i] =
1805 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1806 sps->max_num_reorder_pics[i] =
1807 sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1808 sps->max_latency_increase_plus1[i] =
1809 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1813 /* The limits are calculted based on the profile_tier_level constraint
1814 * in Annex-A: CtbLog2SizeY = 4 to 6 */
1815 READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1816 READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1817 READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1818 READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1819 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1820 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1822 READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1823 if (sps->scaling_list_enabled_flag) {
1824 READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1826 if (sps->scaling_list_data_present_flag)
1827 if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1831 READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1832 READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1833 READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1835 if (sps->pcm_enabled_flag) {
1836 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1837 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1838 READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1839 READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1840 READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1843 READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1844 for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1845 if (!gst_h265_parser_parse_short_term_ref_pic_sets
1846 (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1849 READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1850 if (sps->long_term_ref_pics_present_flag) {
1851 READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1852 for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1853 READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1854 sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1855 READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1859 READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1860 READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1861 READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1863 if (sps->vui_parameters_present_flag && parse_vui_params) {
1864 if (!gst_h265_parse_vui_parameters (sps, &nr))
1866 vui = &sps->vui_params;
1869 READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1871 if (sps->sps_extension_flag) {
1872 READ_UINT8 (&nr, sps->sps_range_extension_flag, 1);
1873 READ_UINT8 (&nr, sps->sps_multilayer_extension_flag, 1);
1874 READ_UINT8 (&nr, sps->sps_3d_extension_flag, 1);
1875 READ_UINT8 (&nr, sps->sps_extension_5bits, 5);
1878 if (sps->sps_range_extension_flag) {
1880 sps->sps_extnsion_params.transform_skip_rotation_enabled_flag, 1);
1882 sps->sps_extnsion_params.transform_skip_context_enabled_flag, 1);
1883 READ_UINT8 (&nr, sps->sps_extnsion_params.implicit_rdpcm_enabled_flag, 1);
1884 READ_UINT8 (&nr, sps->sps_extnsion_params.explicit_rdpcm_enabled_flag, 1);
1886 sps->sps_extnsion_params.extended_precision_processing_flag, 1);
1887 READ_UINT8 (&nr, sps->sps_extnsion_params.intra_smoothing_disabled_flag, 1);
1889 sps->sps_extnsion_params.high_precision_offsets_enabled_flag, 1);
1891 sps->sps_extnsion_params.persistent_rice_adaptation_enabled_flag, 1);
1893 sps->sps_extnsion_params.cabac_bypass_alignment_enabled_flag, 1);
1896 /* calculate ChromaArrayType */
1897 if (!sps->separate_colour_plane_flag)
1898 sps->chroma_array_type = sps->chroma_format_idc;
1900 /* Calculate width and height */
1901 sps->width = sps->pic_width_in_luma_samples;
1902 sps->height = sps->pic_height_in_luma_samples;
1903 if (sps->width < 0 || sps->height < 0) {
1904 GST_WARNING ("invalid width/height in SPS");
1908 if (sps->conformance_window_flag) {
1909 const guint crop_unit_x = subwc[sps->chroma_format_idc];
1910 const guint crop_unit_y = subhc[sps->chroma_format_idc];
1912 sps->crop_rect_width = sps->width -
1913 (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
1914 sps->crop_rect_height = sps->height -
1915 (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
1916 sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
1917 sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
1919 GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
1920 sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
1926 if (vui && vui->timing_info_present_flag) {
1927 /* derive framerate for progressive stream if the pic_struct
1928 * syntax element is not present in picture timing SEI messages */
1929 /* Fixme: handle other cases also */
1930 if (parse_vui_params && vui->timing_info_present_flag
1931 && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
1932 sps->fps_num = vui->time_scale;
1933 sps->fps_den = vui->num_units_in_tick;
1934 GST_LOG ("framerate %d/%d in VUI", sps->fps_num, sps->fps_den);
1936 } else if (vps && vps->timing_info_present_flag) {
1937 sps->fps_num = vps->time_scale;
1938 sps->fps_den = vps->num_units_in_tick;
1939 GST_LOG ("framerate %d/%d in VPS", sps->fps_num, sps->fps_den);
1941 GST_LOG ("No VUI, unknown framerate");
1946 return GST_H265_PARSER_OK;
1949 GST_WARNING ("error parsing \"Sequence parameter set\"");
1951 return GST_H265_PARSER_ERROR;
1955 * gst_h265_parse_pps:
1956 * @parser: a #GstH265Parser
1957 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1958 * @pps: The #GstH265PPS to fill.
1960 * Parses @data, and fills the @pps structure.
1962 * Returns: a #GstH265ParserResult
1965 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
1972 guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY, MaxBitDepthY, MaxBitDepthC;
1975 GST_DEBUG ("parsing PPS");
1977 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1978 nalu->size - nalu->header_bytes);
1980 memset (pps, 0, sizeof (*pps));
1982 READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
1983 READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
1985 sps = gst_h265_parser_get_sps (parser, sps_id);
1987 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
1989 return GST_H265_PARSER_BROKEN_LINK;
1992 qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
1994 MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
1995 CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
1996 CtbSizeY = 1 << CtbLog2SizeY;
1997 pps->PicHeightInCtbsY =
1998 ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
1999 pps->PicWidthInCtbsY =
2000 ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
2002 /* set default values for fields that might not be present in the bitstream
2003 and have valid defaults */
2004 pps->uniform_spacing_flag = 1;
2005 pps->loop_filter_across_tiles_enabled_flag = 1;
2007 READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
2008 READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
2009 READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
2010 READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
2011 READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
2013 READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
2014 READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
2015 READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
2017 READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
2018 READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
2020 READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
2021 if (pps->cu_qp_delta_enabled_flag)
2022 READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
2023 sps->log2_diff_max_min_luma_coding_block_size);
2025 READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
2026 READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
2028 READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
2029 READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
2030 READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
2031 READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
2032 READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
2033 READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
2035 if (pps->tiles_enabled_flag) {
2036 READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 0, 19);
2037 READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 0, 21);
2039 READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
2040 /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
2041 if (pps->uniform_spacing_flag) {
2042 guint8 num_col = pps->num_tile_columns_minus1 + 1;
2043 guint8 num_row = pps->num_tile_rows_minus1 + 1;
2044 for (i = 0; i < num_col; i++) {
2045 pps->column_width_minus1[i] =
2046 ((i + 1) * pps->PicWidthInCtbsY / num_col
2047 - i * pps->PicWidthInCtbsY / num_col) - 1;
2049 for (i = 0; i < num_row; i++) {
2050 pps->row_height_minus1[i] =
2051 ((i + 1) * pps->PicHeightInCtbsY / num_row
2052 - i * pps->PicHeightInCtbsY / num_row) - 1;
2055 pps->column_width_minus1[pps->num_tile_columns_minus1] =
2056 pps->PicWidthInCtbsY - 1;
2057 for (i = 0; i < pps->num_tile_columns_minus1; i++) {
2058 READ_UE (&nr, pps->column_width_minus1[i]);
2059 pps->column_width_minus1[pps->num_tile_columns_minus1] -=
2060 (pps->column_width_minus1[i] + 1);
2063 pps->row_height_minus1[pps->num_tile_rows_minus1] =
2064 pps->PicHeightInCtbsY - 1;
2065 for (i = 0; i < pps->num_tile_rows_minus1; i++) {
2066 READ_UE (&nr, pps->row_height_minus1[i]);
2067 pps->row_height_minus1[pps->num_tile_rows_minus1] -=
2068 (pps->row_height_minus1[i] + 1);
2071 READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
2074 READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
2076 READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
2077 if (pps->deblocking_filter_control_present_flag) {
2078 READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
2080 READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
2081 if (!pps->deblocking_filter_disabled_flag) {
2082 READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
2083 READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
2087 READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
2088 if (pps->scaling_list_data_present_flag)
2089 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
2091 if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
2092 && !pps->scaling_list_data_present_flag)
2093 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
2096 READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
2097 READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
2098 READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
2099 READ_UINT8 (&nr, pps->pps_extension_flag, 1);
2101 if (pps->pps_extension_flag) {
2102 READ_UINT8 (&nr, pps->pps_range_extension_flag, 1);
2103 READ_UINT8 (&nr, pps->pps_multilayer_extension_flag, 1);
2104 READ_UINT8 (&nr, pps->pps_3d_extension_flag, 1);
2105 READ_UINT8 (&nr, pps->pps_extension_5bits, 5);
2108 if (pps->pps_range_extension_flag) {
2109 if (pps->transform_skip_enabled_flag)
2111 pps->pps_extension_params.log2_max_transform_skip_block_size_minus2);
2113 pps->pps_extension_params.cross_component_prediction_enabled_flag, 1);
2115 pps->pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
2116 if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag) {
2118 pps->pps_extension_params.diff_cu_chroma_qp_offset_depth,
2119 sps->log2_diff_max_min_luma_coding_block_size);
2121 pps->pps_extension_params.chroma_qp_offset_list_len_minus1, 5);
2123 i <= pps->pps_extension_params.chroma_qp_offset_list_len_minus1;
2125 READ_SE_ALLOWED (&nr, pps->pps_extension_params.cb_qp_offset_list[i],
2127 READ_SE_ALLOWED (&nr, pps->pps_extension_params.cr_qp_offset_list[i],
2132 sps->bit_depth_luma_minus8 > 2 ? sps->bit_depth_luma_minus8 - 2 : 0;
2134 sps->bit_depth_chroma_minus8 > 2 ? sps->bit_depth_chroma_minus8 - 2 : 0;
2135 READ_UE_ALLOWED (&nr, pps->pps_extension_params.log2_sao_offset_scale_luma,
2137 READ_UE_ALLOWED (&nr,
2138 pps->pps_extension_params.log2_sao_offset_scale_chroma, 0,
2142 return GST_H265_PARSER_OK;
2145 GST_WARNING ("error parsing \"Picture parameter set\"");
2147 return GST_H265_PARSER_ERROR;
2151 * gst_h265_parser_parse_pps:
2152 * @parser: a #GstH265Parser
2153 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2154 * @pps: The #GstH265PPS to fill.
2156 * Parses @data, and fills the @pps structure.
2158 * Returns: a #GstH265ParserResult
2161 gst_h265_parser_parse_pps (GstH265Parser * parser,
2162 GstH265NalUnit * nalu, GstH265PPS * pps)
2164 GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
2165 if (res == GST_H265_PARSER_OK) {
2166 GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
2168 parser->pps[pps->id] = *pps;
2169 parser->last_pps = &parser->pps[pps->id];
2176 * gst_h265_parser_parse_slice_hdr:
2177 * @parser: a #GstH265Parser
2178 * @nalu: The `GST_H265_NAL_SLICE` #GstH265NalUnit to parse
2179 * @slice: The #GstH265SliceHdr to fill.
2181 * Parses @data, and fills the @slice structure.
2182 * The resulting @slice_hdr structure shall be deallocated with
2183 * gst_h265_slice_hdr_free() when it is no longer needed
2185 * Returns: a #GstH265ParserResult
2188 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
2189 GstH265NalUnit * nalu, GstH265SliceHdr * slice)
2196 GstH265ShortTermRefPicSet *stRPS = NULL;
2197 guint32 UsedByCurrPicLt[16];
2198 guint32 PicSizeInCtbsY;
2199 gint NumPocTotalCurr = 0;
2201 memset (slice, 0, sizeof (*slice));
2204 GST_DEBUG ("Invalid Nal Unit");
2205 return GST_H265_PARSER_ERROR;
2208 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2209 nalu->size - nalu->header_bytes);
2211 GST_DEBUG ("parsing \"Slice header\", slice type");
2213 READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
2215 if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP
2216 && nalu->type <= RESERVED_IRAP_NAL_TYPE_MAX)
2217 READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
2219 READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
2220 pps = gst_h265_parser_get_pps (parser, pps_id);
2223 ("couldn't find associated picture parameter set with id: %d", pps_id);
2224 return GST_H265_PARSER_BROKEN_LINK;
2231 ("couldn't find associated sequence parameter set with id: %d",
2233 return GST_H265_PARSER_BROKEN_LINK;
2236 PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
2237 /* set default values for fields that might not be present in the bitstream
2238 * and have valid defaults */
2239 slice->pic_output_flag = 1;
2240 slice->collocated_from_l0_flag = 1;
2241 slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
2242 slice->beta_offset_div2 = pps->beta_offset_div2;
2243 slice->tc_offset_div2 = pps->tc_offset_div2;
2244 slice->loop_filter_across_slices_enabled_flag =
2245 pps->loop_filter_across_slices_enabled_flag;
2247 if (!slice->first_slice_segment_in_pic_flag) {
2248 const guint n = ceil_log2 (PicSizeInCtbsY);
2250 if (pps->dependent_slice_segments_enabled_flag)
2251 READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
2252 /* sice_segment_address parsing */
2253 READ_UINT32 (&nr, slice->segment_address, n);
2256 if (!slice->dependent_slice_segment_flag) {
2257 for (i = 0; i < pps->num_extra_slice_header_bits; i++)
2258 nal_reader_skip (&nr, 1);
2259 READ_UE_MAX (&nr, slice->type, 63);
2262 if (pps->output_flag_present_flag)
2263 READ_UINT8 (&nr, slice->pic_output_flag, 1);
2264 if (sps->separate_colour_plane_flag == 1)
2265 READ_UINT8 (&nr, slice->colour_plane_id, 2);
2267 if ((nalu->type != GST_H265_NAL_SLICE_IDR_W_RADL)
2268 && (nalu->type != GST_H265_NAL_SLICE_IDR_N_LP)) {
2269 READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
2270 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2272 READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
2273 if (!slice->short_term_ref_pic_set_sps_flag) {
2274 guint pos = nal_reader_get_pos (&nr);
2275 if (!gst_h265_parser_parse_short_term_ref_pic_sets
2276 (&slice->short_term_ref_pic_sets, &nr,
2277 sps->num_short_term_ref_pic_sets, sps))
2280 slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
2281 } else if (sps->num_short_term_ref_pic_sets > 1) {
2282 const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
2283 READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
2284 CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
2285 sps->num_short_term_ref_pic_sets - 1);
2288 if (sps->long_term_ref_pics_present_flag) {
2291 if (sps->num_long_term_ref_pics_sps > 0)
2292 READ_UE_MAX (&nr, slice->num_long_term_sps,
2293 sps->num_long_term_ref_pics_sps);
2295 READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2296 limit = slice->num_long_term_sps + slice->num_long_term_pics;
2297 for (i = 0; i < limit; i++) {
2298 if (i < slice->num_long_term_sps) {
2299 if (sps->num_long_term_ref_pics_sps > 1) {
2300 const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2301 READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2304 READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2305 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2306 READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2309 /* calculate UsedByCurrPicLt */
2310 if (i < slice->num_long_term_sps)
2311 UsedByCurrPicLt[i] =
2312 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2314 UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2315 READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2316 if (slice->delta_poc_msb_present_flag[i])
2317 READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2320 if (sps->temporal_mvp_enabled_flag)
2321 READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2324 if (sps->sample_adaptive_offset_enabled_flag) {
2325 READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2326 READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2329 if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2330 READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2332 if (slice->num_ref_idx_active_override_flag) {
2333 READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2334 if (GST_H265_IS_B_SLICE (slice))
2335 READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2337 /*set default values */
2338 slice->num_ref_idx_l0_active_minus1 =
2339 pps->num_ref_idx_l0_default_active_minus1;
2340 slice->num_ref_idx_l1_active_minus1 =
2341 pps->num_ref_idx_l1_default_active_minus1;
2344 /* calculate NumPocTotalCurr */
2345 if (slice->short_term_ref_pic_set_sps_flag)
2346 stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2348 stRPS = &slice->short_term_ref_pic_sets;
2350 for (i = 0; i < stRPS->NumNegativePics; i++)
2351 if (stRPS->UsedByCurrPicS0[i])
2353 for (i = 0; i < stRPS->NumPositivePics; i++)
2354 if (stRPS->UsedByCurrPicS1[i])
2357 i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2358 if (UsedByCurrPicLt[i])
2360 slice->NumPocTotalCurr = NumPocTotalCurr;
2362 if (pps->lists_modification_present_flag) {
2363 if (NumPocTotalCurr > 1)
2364 if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2369 if (GST_H265_IS_B_SLICE (slice))
2370 READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2371 if (pps->cabac_init_present_flag)
2372 READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2373 if (slice->temporal_mvp_enabled_flag) {
2374 if (GST_H265_IS_B_SLICE (slice))
2375 READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2377 if ((slice->collocated_from_l0_flag
2378 && slice->num_ref_idx_l0_active_minus1 > 0)
2379 || (!slice->collocated_from_l0_flag
2380 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2382 /*fixme: add optimization */
2383 if ((GST_H265_IS_P_SLICE (slice))
2384 || ((GST_H265_IS_B_SLICE (slice))
2385 && (slice->collocated_from_l0_flag))) {
2386 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2387 slice->num_ref_idx_l0_active_minus1);
2388 } else if ((GST_H265_IS_B_SLICE (slice))
2389 && (!slice->collocated_from_l0_flag)) {
2390 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2391 slice->num_ref_idx_l1_active_minus1);
2395 if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2396 (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2397 if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2399 READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2402 READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2403 if (pps->slice_chroma_qp_offsets_present_flag) {
2404 READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2405 READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2408 if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag)
2409 READ_UINT8 (&nr, slice->cu_chroma_qp_offset_enabled_flag, 1);
2411 if (pps->deblocking_filter_override_enabled_flag)
2412 READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2413 if (slice->deblocking_filter_override_flag) {
2414 READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2415 if (!slice->deblocking_filter_disabled_flag) {
2416 READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2417 READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2421 if (pps->loop_filter_across_slices_enabled_flag &&
2422 (slice->sao_luma_flag || slice->sao_chroma_flag ||
2423 !slice->deblocking_filter_disabled_flag))
2424 READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2427 if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2430 if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2431 offset_max = pps->PicHeightInCtbsY - 1;
2432 else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2434 (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2438 (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2440 READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2441 if (slice->num_entry_point_offsets > 0) {
2442 READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2443 slice->entry_point_offset_minus1 =
2444 g_new0 (guint32, slice->num_entry_point_offsets);
2445 for (i = 0; i < slice->num_entry_point_offsets; i++)
2446 READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2447 (slice->offset_len_minus1 + 1));
2451 if (pps->slice_segment_header_extension_present_flag) {
2452 guint16 slice_segment_header_extension_length;
2453 READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2454 for (i = 0; i < slice_segment_header_extension_length; i++)
2455 if (!nal_reader_skip (&nr, 8))
2459 /* Skip the byte alignment bits */
2460 if (!nal_reader_skip (&nr, 1))
2462 while (!nal_reader_is_byte_aligned (&nr)) {
2463 if (!nal_reader_skip (&nr, 1))
2467 slice->header_size = nal_reader_get_pos (&nr);
2468 slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2470 return GST_H265_PARSER_OK;
2473 GST_WARNING ("error parsing \"Slice header\"");
2475 gst_h265_slice_hdr_free (slice);
2477 return GST_H265_PARSER_ERROR;
2480 static GstH265ParserResult
2481 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2482 guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2484 guint32 payloadSizeBytes;
2485 guint8 payload_type_byte, payload_size_byte;
2486 guint32 remaining, payload_size_bits, next;
2487 GstH265ParserResult res = GST_H265_PARSER_OK;
2489 GST_DEBUG ("parsing \"SEI message\" %u bits available",
2490 nal_reader_get_remaining (nr));
2492 memset (sei, 0, sizeof (*sei));
2495 READ_UINT8 (nr, payload_type_byte, 8);
2496 sei->payloadType += payload_type_byte;
2497 } while (payload_type_byte == 0xff);
2498 payloadSizeBytes = 0;
2500 READ_UINT8 (nr, payload_size_byte, 8);
2501 payloadSizeBytes += payload_size_byte;
2503 while (payload_size_byte == 0xff);
2505 remaining = nal_reader_get_remaining (nr);
2507 payloadSizeBytes * 8 < remaining ? payloadSizeBytes * 8 : remaining;
2508 next = nal_reader_get_pos (nr) + payload_size_bits;
2511 ("SEI message received: payloadType %u, payloadSize = %u bits",
2512 sei->payloadType, payload_size_bits);
2514 if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2515 switch (sei->payloadType) {
2516 case GST_H265_SEI_BUF_PERIOD:
2517 /* size not set; might depend on emulation_prevention_three_byte */
2518 res = gst_h265_parser_parse_buffering_period (parser,
2519 &sei->payload.buffering_period, nr);
2521 case GST_H265_SEI_PIC_TIMING:
2522 /* size not set; might depend on emulation_prevention_three_byte */
2523 res = gst_h265_parser_parse_pic_timing (parser,
2524 &sei->payload.pic_timing, nr);
2526 case GST_H265_SEI_REGISTERED_USER_DATA:
2527 res = gst_h265_parser_parse_registered_user_data (parser,
2528 &sei->payload.registered_user_data, nr, payloadSizeBytes);
2530 case GST_H265_SEI_RECOVERY_POINT:
2531 res = gst_h265_parser_parse_recovery_point (parser,
2532 &sei->payload.recovery_point, nr);
2534 case GST_H265_SEI_TIME_CODE:
2535 res = gst_h265_parser_parse_time_code (parser,
2536 &sei->payload.time_code, nr);
2538 case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
2539 res = gst_h265_parser_parse_mastering_display_colour_volume (parser,
2540 &sei->payload.mastering_display_colour_volume, nr);
2542 case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
2543 res = gst_h265_parser_parse_content_light_level_info (parser,
2544 &sei->payload.content_light_level, nr);
2547 /* Just consume payloadSize bytes, which does not account for
2548 emulation prevention bytes */
2549 if (!nal_reader_skip_long (nr, payload_size_bits))
2551 res = GST_H265_PARSER_OK;
2554 } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2555 switch (sei->payloadType) {
2557 /* Just consume payloadSize bytes, which does not account for
2558 emulation prevention bytes */
2559 if (!nal_reader_skip_long (nr, payload_size_bits))
2561 res = GST_H265_PARSER_OK;
2566 /* Not parsing the reserved_payload_extension, but it shouldn't be
2567 * an issue because of 1: There shall not be any reserved_payload_extension
2568 * present in bitstreams conforming to the specification.2. Even though
2569 * it is present, the size will be less than total PayloadSize since the
2570 * size of reserved_payload_extension is supposed to be
2571 * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2572 * the current implementation will still skip all unnecessary bits correctly. */
2574 /* Always make sure all the advertised SEI bits
2575 * were consumed during parsing. This is sufficient to skip to the next
2576 * byte aligned position after the SEI payload because we start
2577 * at a byte-aligned position and calculate the 'next' position as a
2578 * multiple of 8 bits, and this correctly skips any three-byte emulation
2579 * bytes encountered without getting confused. */
2580 if (next > nal_reader_get_pos (nr)) {
2581 GST_LOG ("Skipping %u unused SEI bits", next - nal_reader_get_pos (nr));
2582 if (!nal_reader_skip_long (nr, next - nal_reader_get_pos (nr)))
2589 GST_WARNING ("error parsing \"Sei message\"");
2590 return GST_H265_PARSER_ERROR;
2594 * gst_h265_slice_hdr_copy:
2595 * @dst_slice: The destination #GstH265SliceHdr to copy into
2596 * @src_slice: The source #GstH265SliceHdr to copy from
2598 * Copies @src_slice into @dst_slice
2600 * Returns: %TRUE if everything went fine, %FALSE otherwise
2603 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2604 const GstH265SliceHdr * src_slice)
2608 g_return_val_if_fail (dst_slice != NULL, FALSE);
2609 g_return_val_if_fail (src_slice != NULL, FALSE);
2611 gst_h265_slice_hdr_free (dst_slice);
2613 *dst_slice = *src_slice;
2615 if (dst_slice->num_entry_point_offsets > 0) {
2616 dst_slice->entry_point_offset_minus1 =
2617 g_new0 (guint32, dst_slice->num_entry_point_offsets);
2618 for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2619 dst_slice->entry_point_offset_minus1[i] =
2620 src_slice->entry_point_offset_minus1[i];
2627 * gst_h265_slice_hdr_free:
2628 * slice_hdr: The #GstH265SliceHdr to free
2630 * Frees @slice_hdr fields.
2633 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2635 g_return_if_fail (slice_hdr != NULL);
2637 if (slice_hdr->num_entry_point_offsets > 0)
2638 g_free (slice_hdr->entry_point_offset_minus1);
2639 slice_hdr->entry_point_offset_minus1 = 0;
2643 * gst_h265_sei_copy:
2644 * @dst_sei: The destination #GstH265SEIMessage to copy into
2645 * @src_sei: The source #GstH265SEIMessage to copy from
2647 * Copies @src_sei into @dst_sei
2649 * Returns: %TRUE if everything went fine, %FALSE otherwise
2652 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2653 const GstH265SEIMessage * src_sei)
2657 g_return_val_if_fail (dst_sei != NULL, FALSE);
2658 g_return_val_if_fail (src_sei != NULL, FALSE);
2660 gst_h265_sei_free (dst_sei);
2662 *dst_sei = *src_sei;
2664 if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2665 GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2666 const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2668 if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2669 dst_pic_timing->num_nalus_in_du_minus1 =
2670 g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2671 dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2672 g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2674 for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2675 dst_pic_timing->num_nalus_in_du_minus1[i] =
2676 src_pic_timing->num_nalus_in_du_minus1[i];
2677 dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2678 src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2687 * gst_h265_sei_free:
2688 * sei: The #GstH265SEIMessage to free
2690 * Frees @sei fields.
2693 gst_h265_sei_free (GstH265SEIMessage * sei)
2695 g_return_if_fail (sei != NULL);
2697 if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2698 GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2699 if (pic_timing->num_decoding_units_minus1 > 0) {
2700 g_free (pic_timing->num_nalus_in_du_minus1);
2701 g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2703 pic_timing->num_nalus_in_du_minus1 = 0;
2704 pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2709 * gst_h265_parser_parse_sei:
2710 * @nalparser: a #GstH265Parser
2711 * @nalu: The `GST_H265_NAL_*_SEI` #GstH265NalUnit to parse
2712 * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2714 * Parses @data, create and fills the @messages array.
2716 * Returns: a #GstH265ParserResult
2719 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2723 GstH265SEIMessage sei;
2724 GstH265ParserResult res;
2726 GST_DEBUG ("parsing SEI nal");
2727 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2728 nalu->size - nalu->header_bytes);
2729 *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
2730 g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
2733 res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
2734 if (res == GST_H265_PARSER_OK)
2735 g_array_append_val (*messages, sei);
2738 } while (nal_reader_has_more_data (&nr));
2745 * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
2746 * @out_quant: (out): The resulting quantization matrix
2747 * @quant: The source quantization matrix
2749 * Converts quantization matrix @quant from raster scan order to
2750 * zigzag scan order and store the resulting factors into @out_quant.
2752 * Note: it is an error to pass the same table in both @quant and
2753 * @out_quant arguments.
2758 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
2759 const guint8 quant[16])
2763 g_return_if_fail (out_quant != quant);
2765 for (i = 0; i < 16; i++)
2766 out_quant[i] = quant[zigzag_4x4[i]];
2770 * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
2771 * @out_quant: (out): The resulting quantization matrix
2772 * @quant: The source quantization matrix
2774 * Converts quantization matrix @quant from zigzag scan order to
2775 * raster scan order and store the resulting factors into @out_quant.
2777 * Note: it is an error to pass the same table in both @quant and
2778 * @out_quant arguments.
2783 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
2784 const guint8 quant[16])
2788 g_return_if_fail (out_quant != quant);
2790 for (i = 0; i < 16; i++)
2791 out_quant[zigzag_4x4[i]] = quant[i];
2795 * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
2796 * @out_quant: (out): The resulting quantization matrix
2797 * @quant: The source quantization matrix
2799 * Converts quantization matrix @quant from raster scan order to
2800 * zigzag scan order and store the resulting factors into @out_quant.
2802 * Note: it is an error to pass the same table in both @quant and
2803 * @out_quant arguments.
2808 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
2809 const guint8 quant[64])
2813 g_return_if_fail (out_quant != quant);
2815 for (i = 0; i < 64; i++)
2816 out_quant[i] = quant[zigzag_8x8[i]];
2820 * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
2821 * @out_quant: (out): The resulting quantization matrix
2822 * @quant: The source quantization matrix
2824 * Converts quantization matrix @quant from zigzag scan order to
2825 * raster scan order and store the resulting factors into @out_quant.
2827 * Note: it is an error to pass the same table in both @quant and
2828 * @out_quant arguments.
2833 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
2834 const guint8 quant[64])
2838 g_return_if_fail (out_quant != quant);
2840 for (i = 0; i < 64; i++)
2841 out_quant[zigzag_8x8[i]] = quant[i];
2845 * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
2846 * @out_quant: (out): The resulting quantization matrix
2847 * @quant: The source quantization matrix
2849 * Converts quantization matrix @quant from raster scan order to
2850 * uprightdiagonal scan order and store the resulting factors
2853 * Note: it is an error to pass the same table in both @quant and
2854 * @out_quant arguments.
2859 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
2860 const guint8 quant[16])
2864 g_return_if_fail (out_quant != quant);
2866 for (i = 0; i < 16; i++)
2867 out_quant[i] = quant[uprightdiagonal_4x4[i]];
2871 * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
2872 * @out_quant: (out): The resulting quantization matrix
2873 * @quant: The source quantization matrix
2875 * Converts quantization matrix @quant from uprightdiagonal scan order to
2876 * raster scan order and store the resulting factors into @out_quant.
2878 * Note: it is an error to pass the same table in both @quant and
2879 * @out_quant arguments.
2884 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
2885 const guint8 quant[16])
2889 g_return_if_fail (out_quant != quant);
2891 for (i = 0; i < 16; i++)
2892 out_quant[uprightdiagonal_4x4[i]] = quant[i];
2896 * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
2897 * @out_quant: (out): The resulting quantization matrix
2898 * @quant: The source quantization matrix
2900 * Converts quantization matrix @quant from raster scan order to
2901 * uprightdiagonal scan order and store the resulting factors
2904 * Note: it is an error to pass the same table in both @quant and
2905 * @out_quant arguments.
2910 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
2911 const guint8 quant[64])
2915 g_return_if_fail (out_quant != quant);
2917 for (i = 0; i < 64; i++)
2918 out_quant[i] = quant[uprightdiagonal_8x8[i]];
2922 * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
2923 * @out_quant: (out): The resulting quantization matrix
2924 * @quant: The source quantization matrix
2926 * Converts quantization matrix @quant from uprightdiagonal scan order to
2927 * raster scan order and store the resulting factors into @out_quant.
2929 * Note: it is an error to pass the same table in both @quant and
2930 * @out_quant arguments.
2935 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
2936 const guint8 quant[64])
2940 g_return_if_fail (out_quant != quant);
2942 for (i = 0; i < 64; i++)
2943 out_quant[uprightdiagonal_8x8[i]] = quant[i];
2948 GstH265Profile profile;
2949 GstH265ProfileIDC profile_idc;
2951 guint8 max_14bit_constraint_flag;
2952 guint8 max_12bit_constraint_flag;
2953 guint8 max_10bit_constraint_flag;
2954 guint8 max_8bit_constraint_flag;
2955 guint8 max_422chroma_constraint_flag;
2956 guint8 max_420chroma_constraint_flag;
2957 guint8 max_monochrome_constraint_flag;
2958 guint8 intra_constraint_flag;
2959 guint8 one_picture_only_constraint_flag;
2960 gboolean lower_bit_rate_constraint_flag_set;
2962 /* Tie breaker if more than one profiles are matching */
2964 } FormatRangeExtensionProfile;
2968 FormatRangeExtensionProfile *profile;
2969 guint extra_constraints;
2970 } FormatRangeExtensionProfileMatch;
2973 sort_fre_profile_matches (FormatRangeExtensionProfileMatch * a,
2974 FormatRangeExtensionProfileMatch * b)
2978 d = a->extra_constraints - b->extra_constraints;
2982 return b->profile->priority - a->profile->priority;
2985 static GstH265Profile
2986 get_format_range_extension_profile (GstH265ProfileTierLevel * ptl)
2988 /* See Table A.2 for the definition of those formats */
2989 FormatRangeExtensionProfile profiles[] = {
2990 {GST_H265_PROFILE_MONOCHROME, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
2991 0, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
2992 {GST_H265_PROFILE_MONOCHROME_10,
2993 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
2994 0, 1, 1, 0, 1, 1, 1, 0, 0, TRUE, 1},
2995 {GST_H265_PROFILE_MONOCHROME_12,
2996 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
2997 0, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
2998 {GST_H265_PROFILE_MONOCHROME_16,
2999 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3000 0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 3},
3001 {GST_H265_PROFILE_MAIN_12, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3002 0, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 4},
3003 {GST_H265_PROFILE_MAIN_422_10, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3004 0, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 5},
3005 {GST_H265_PROFILE_MAIN_422_12, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3006 0, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 6},
3007 {GST_H265_PROFILE_MAIN_444, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3008 0, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 7},
3009 {GST_H265_PROFILE_MAIN_444_10, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3010 0, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 8},
3011 {GST_H265_PROFILE_MAIN_444_12, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3012 0, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 9},
3013 {GST_H265_PROFILE_MAIN_INTRA, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3014 0, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 10},
3015 {GST_H265_PROFILE_MAIN_10_INTRA,
3016 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3017 0, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 11},
3018 {GST_H265_PROFILE_MAIN_12_INTRA,
3019 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3020 0, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 12},
3021 {GST_H265_PROFILE_MAIN_422_10_INTRA,
3022 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3023 0, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 13},
3024 {GST_H265_PROFILE_MAIN_422_12_INTRA,
3025 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3026 0, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 14},
3027 {GST_H265_PROFILE_MAIN_444_INTRA,
3028 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3029 0, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 15},
3030 {GST_H265_PROFILE_MAIN_444_10_INTRA,
3031 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3032 0, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 16},
3033 {GST_H265_PROFILE_MAIN_444_12_INTRA,
3034 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3035 0, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
3036 {GST_H265_PROFILE_MAIN_444_16_INTRA,
3037 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3038 0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 18},
3039 {GST_H265_PROFILE_MAIN_444_STILL_PICTURE,
3040 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3041 0, 1, 1, 1, 0, 0, 0, 1, 1, FALSE, 19},
3042 {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE,
3043 GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3044 0, 0, 0, 0, 0, 0, 0, 1, 1, FALSE, 20},
3046 /* High Througput */
3047 {GST_H265_PROFILE_HIGH_THROUGHPUT_444, GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3048 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 21},
3049 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10,
3050 GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3051 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 22},
3052 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14,
3053 GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3054 1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 23},
3055 {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
3056 GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3057 0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 24},
3059 /* Screen content coding */
3060 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN,
3061 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3062 1, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 25},
3063 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10,
3064 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3065 1, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 26},
3066 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
3067 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3068 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 27},
3069 {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10,
3070 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3071 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 28},
3072 /* identical to screen-extended-main-444 */
3073 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
3074 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3075 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 29},
3076 /* identical to screen-extended-main-444-10 */
3077 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
3078 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3079 1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 30},
3080 {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
3081 GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3082 1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 31},
3084 /* Multiview Main */
3085 {GST_H265_PROFILE_MULTIVIEW_MAIN, GST_H265_PROFILE_IDC_MULTIVIEW_MAIN,
3086 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 32},
3089 {GST_H265_PROFILE_SCALABLE_MAIN, GST_H265_PROFILE_IDC_SCALABLE_MAIN,
3090 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 33},
3091 {GST_H265_PROFILE_SCALABLE_MAIN_10, GST_H265_PROFILE_IDC_SCALABLE_MAIN,
3092 0, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 34},
3094 /* Scalable format range extensions */
3095 {GST_H265_PROFILE_SCALABLE_MONOCHROME,
3096 GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3097 1, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 35},
3098 {GST_H265_PROFILE_SCALABLE_MONOCHROME_12,
3099 GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3100 1, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 36},
3101 {GST_H265_PROFILE_SCALABLE_MONOCHROME_16,
3102 GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3103 0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 37},
3104 {GST_H265_PROFILE_SCALABLE_MAIN_444,
3105 GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3106 1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 38},
3109 {GST_H265_PROFILE_3D_MAIN, GST_H265_PROFILE_IDC_3D_MAIN,
3110 0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 39},
3112 GstH265Profile result = GST_H265_PROFILE_INVALID;
3114 GList *matches = NULL;
3116 for (i = 0; i < G_N_ELEMENTS (profiles); i++) {
3117 FormatRangeExtensionProfile p = profiles[i];
3118 guint extra_constraints = 0;
3119 FormatRangeExtensionProfileMatch *m;
3121 /* Filter out all the profiles having constraints not satisfied by @ptl.
3122 * Then pick the one having the least extra constraints. This allow us
3123 * to match the closet profile if bitstream contains not standard
3125 if (p.max_14bit_constraint_flag != ptl->max_14bit_constraint_flag) {
3126 if (p.max_14bit_constraint_flag)
3128 extra_constraints++;
3131 if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
3132 if (p.max_12bit_constraint_flag)
3134 extra_constraints++;
3137 if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
3138 if (p.max_10bit_constraint_flag)
3140 extra_constraints++;
3143 if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
3144 if (p.max_8bit_constraint_flag)
3146 extra_constraints++;
3149 if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
3150 if (p.max_422chroma_constraint_flag)
3152 extra_constraints++;
3155 if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
3156 if (p.max_420chroma_constraint_flag)
3158 extra_constraints++;
3161 if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
3162 if (p.max_monochrome_constraint_flag)
3164 extra_constraints++;
3167 if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
3168 if (p.intra_constraint_flag)
3170 extra_constraints++;
3173 if (p.one_picture_only_constraint_flag !=
3174 ptl->one_picture_only_constraint_flag) {
3175 if (p.one_picture_only_constraint_flag)
3177 extra_constraints++;
3180 if (p.lower_bit_rate_constraint_flag_set
3181 && !ptl->lower_bit_rate_constraint_flag)
3184 if (extra_constraints == 0 &&
3185 (p.profile_idc == ptl->profile_idc
3186 || ptl->profile_compatibility_flag[ptl->profile_idc])) {
3191 m = g_new0 (FormatRangeExtensionProfileMatch, 1);
3192 m->profile = &profiles[i];
3193 m->extra_constraints = extra_constraints;
3194 matches = g_list_prepend (matches, m);
3197 if (result == GST_H265_PROFILE_INVALID && matches) {
3198 FormatRangeExtensionProfileMatch *m;
3200 matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
3202 result = m->profile->profile;
3206 g_list_free_full (matches, g_free);
3212 * gst_h265_profile_tier_level_get_profile:
3213 * @ptl: a #GstH265ProfileTierLevel
3215 * Return the H265 profile defined in @ptl.
3217 * Returns: a #GstH265Profile
3221 gst_h265_profile_tier_level_get_profile (GstH265ProfileTierLevel * ptl)
3223 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN
3224 || ptl->profile_compatibility_flag[1])
3225 return GST_H265_PROFILE_MAIN;
3227 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_10
3228 || ptl->profile_compatibility_flag[2])
3229 return GST_H265_PROFILE_MAIN_10;
3231 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE
3232 || ptl->profile_compatibility_flag[3])
3233 return GST_H265_PROFILE_MAIN_STILL_PICTURE;
3235 return get_format_range_extension_profile (ptl);