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 GST_DEBUG_CATEGORY_STATIC (h265_parser_debug);
76 #define GST_CAT_DEFAULT h265_parser_debug
78 static gboolean initialized = FALSE;
79 #define INITIALIZE_DEBUG_CATEGORY \
81 GST_DEBUG_CATEGORY_INIT (h265_parser_debug, "codecparsers_h265", 0, \
82 "h265 parser library"); \
86 /**** Default scaling_lists according to Table 7-5 and 7-6 *****/
89 static const guint8 default_scaling_list0[16] = {
90 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
94 /* Combined the values in Table 7-6 to make the calculation easier
95 * Default scaling list of 8x8 and 16x16 matrices for matrixId = 0, 1 and 2
96 * Default scaling list of 32x32 matrix for matrixId = 0
98 static const guint8 default_scaling_list1[64] = {
99 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16,
100 17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20,
101 21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24,
102 25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31,
103 29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70,
107 /* Combined the values in Table 7-6 to make the calculation easier
108 * Default scaling list of 8x8 and 16x16 matrices for matrixId = 3, 4 and 5
109 * Default scaling list of 32x32 matrix for matrixId = 1
111 static const guint8 default_scaling_list2[64] = {
112 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
113 17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20,
114 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24,
115 25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28,
116 28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54,
120 static const guint8 zigzag_4x4[16] = {
127 static const guint8 zigzag_8x8[64] = {
128 0, 1, 8, 16, 9, 2, 3, 10,
129 17, 24, 32, 25, 18, 11, 4, 5,
130 12, 19, 26, 33, 40, 48, 41, 34,
131 27, 20, 13, 6, 7, 14, 21, 28,
132 35, 42, 49, 56, 57, 50, 43, 36,
133 29, 22, 15, 23, 30, 37, 44, 51,
134 58, 59, 52, 45, 38, 31, 39, 46,
135 53, 60, 61, 54, 47, 55, 62, 63
138 static const guint8 uprightdiagonal_4x4[16] = {
145 static const guint8 uprightdiagonal_8x8[64] = {
146 0, 8, 1, 16, 9, 2, 24, 17,
147 10, 3, 32, 25, 18, 11, 4, 40,
148 33, 26, 19, 12, 5, 48, 41, 34,
149 27, 20, 13, 6, 56, 49, 42, 35,
150 28, 21, 14, 7, 57, 50, 43, 36,
151 29, 22, 15, 58, 51, 44, 37, 30,
152 23, 59, 52, 45, 38, 31, 60, 53,
153 46, 39, 61, 54, 47, 62, 55, 63
161 /* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
162 static const PAR aspect_ratios[17] = {
183 #define EXTENDED_SAR 255
186 gst_h265_parser_get_vps (GstH265Parser * parser, guint8 vps_id)
190 vps = &parser->vps[vps_id];
199 gst_h265_parser_get_sps (GstH265Parser * parser, guint8 sps_id)
203 sps = &parser->sps[sps_id];
212 gst_h265_parser_get_pps (GstH265Parser * parser, guint8 pps_id)
216 pps = &parser->pps[pps_id];
225 gst_h265_parse_nalu_header (GstH265NalUnit * nalu)
227 guint8 *data = nalu->data + nalu->offset;
233 gst_bit_reader_init (&br, data, nalu->size - nalu->offset);
235 /* skip the forbidden_zero_bit */
236 gst_bit_reader_skip_unchecked (&br, 1);
238 nalu->type = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
239 nalu->layer_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
240 nalu->temporal_id_plus1 = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
241 nalu->header_bytes = 2;
246 /****** Parsing functions *****/
249 gst_h265_parse_profile_tier_level (GstH265ProfileTierLevel * ptl,
250 NalReader * nr, guint8 maxNumSubLayersMinus1)
253 GST_DEBUG ("parsing \"ProfileTierLevel parameters\"");
255 READ_UINT8 (nr, ptl->profile_space, 2);
256 READ_UINT8 (nr, ptl->tier_flag, 1);
257 READ_UINT8 (nr, ptl->profile_idc, 5);
259 for (j = 0; j < 32; j++)
260 READ_UINT8 (nr, ptl->profile_compatibility_flag[j], 1);
262 READ_UINT8 (nr, ptl->progressive_source_flag, 1);
263 READ_UINT8 (nr, ptl->interlaced_source_flag, 1);
264 READ_UINT8 (nr, ptl->non_packed_constraint_flag, 1);
265 READ_UINT8 (nr, ptl->frame_only_constraint_flag, 1);
267 READ_UINT8 (nr, ptl->max_12bit_constraint_flag, 1);
268 READ_UINT8 (nr, ptl->max_10bit_constraint_flag, 1);
269 READ_UINT8 (nr, ptl->max_8bit_constraint_flag, 1);
270 READ_UINT8 (nr, ptl->max_422chroma_constraint_flag, 1);
271 READ_UINT8 (nr, ptl->max_420chroma_constraint_flag, 1);
272 READ_UINT8 (nr, ptl->max_monochrome_constraint_flag, 1);
273 READ_UINT8 (nr, ptl->intra_constraint_flag, 1);
274 READ_UINT8 (nr, ptl->one_picture_only_constraint_flag, 1);
275 READ_UINT8 (nr, ptl->lower_bit_rate_constraint_flag, 1);
276 READ_UINT8 (nr, ptl->max_14bit_constraint_flag, 1);
278 /* skip the reserved zero bits */
279 if (!nal_reader_skip (nr, 34))
282 READ_UINT8 (nr, ptl->level_idc, 8);
283 for (j = 0; j < maxNumSubLayersMinus1; j++) {
284 READ_UINT8 (nr, ptl->sub_layer_profile_present_flag[j], 1);
285 READ_UINT8 (nr, ptl->sub_layer_level_present_flag[j], 1);
288 if (maxNumSubLayersMinus1 > 0) {
289 for (i = maxNumSubLayersMinus1; i < 8; i++)
290 if (!nal_reader_skip (nr, 2))
294 for (i = 0; i < maxNumSubLayersMinus1; i++) {
295 if (ptl->sub_layer_profile_present_flag[i]) {
296 READ_UINT8 (nr, ptl->sub_layer_profile_space[i], 2);
297 READ_UINT8 (nr, ptl->sub_layer_tier_flag[i], 1);
298 READ_UINT8 (nr, ptl->sub_layer_profile_idc[i], 5);
300 for (j = 0; j < 32; j++)
301 READ_UINT8 (nr, ptl->sub_layer_profile_compatibility_flag[i][j], 1);
303 READ_UINT8 (nr, ptl->sub_layer_progressive_source_flag[i], 1);
304 READ_UINT8 (nr, ptl->sub_layer_interlaced_source_flag[i], 1);
305 READ_UINT8 (nr, ptl->sub_layer_non_packed_constraint_flag[i], 1);
306 READ_UINT8 (nr, ptl->sub_layer_frame_only_constraint_flag[i], 1);
308 if (!nal_reader_skip (nr, 44))
312 if (ptl->sub_layer_level_present_flag[i])
313 READ_UINT8 (nr, ptl->sub_layer_level_idc[i], 8);
319 GST_WARNING ("error parsing \"ProfileTierLevel Parameters\"");
324 gst_h265_parse_sub_layer_hrd_parameters (GstH265SubLayerHRDParams * sub_hrd,
325 NalReader * nr, guint8 CpbCnt, guint8 sub_pic_hrd_params_present_flag)
329 GST_DEBUG ("parsing \"SubLayer HRD Parameters\"");
331 for (i = 0; i <= CpbCnt; i++) {
332 READ_UE_MAX (nr, sub_hrd->bit_rate_value_minus1[i], G_MAXUINT32 - 1);
333 READ_UE_MAX (nr, sub_hrd->cpb_size_value_minus1[i], G_MAXUINT32 - 1);
335 if (sub_pic_hrd_params_present_flag) {
336 READ_UE_MAX (nr, sub_hrd->cpb_size_du_value_minus1[i], G_MAXUINT32 - 1);
337 READ_UE_MAX (nr, sub_hrd->bit_rate_du_value_minus1[i], G_MAXUINT32 - 1);
340 READ_UINT8 (nr, sub_hrd->cbr_flag[i], 1);
346 GST_WARNING ("error parsing \"SubLayerHRD Parameters \"");
351 gst_h265_parse_hrd_parameters (GstH265HRDParams * hrd, NalReader * nr,
352 guint8 commonInfPresentFlag, guint8 maxNumSubLayersMinus1)
356 GST_DEBUG ("parsing \"HRD Parameters\"");
358 /* set default values for fields that might not be present in the bitstream
359 and have valid defaults */
360 hrd->initial_cpb_removal_delay_length_minus1 = 23;
361 hrd->au_cpb_removal_delay_length_minus1 = 23;
362 hrd->dpb_output_delay_length_minus1 = 23;
364 if (commonInfPresentFlag) {
365 READ_UINT8 (nr, hrd->nal_hrd_parameters_present_flag, 1);
366 READ_UINT8 (nr, hrd->vcl_hrd_parameters_present_flag, 1);
368 if (hrd->nal_hrd_parameters_present_flag
369 || hrd->vcl_hrd_parameters_present_flag) {
371 READ_UINT8 (nr, hrd->sub_pic_hrd_params_present_flag, 1);
373 if (hrd->sub_pic_hrd_params_present_flag) {
374 READ_UINT8 (nr, hrd->tick_divisor_minus2, 8);
375 READ_UINT8 (nr, hrd->du_cpb_removal_delay_increment_length_minus1, 5);
376 READ_UINT8 (nr, hrd->sub_pic_cpb_params_in_pic_timing_sei_flag, 1);
377 READ_UINT8 (nr, hrd->dpb_output_delay_du_length_minus1, 5);
380 READ_UINT8 (nr, hrd->bit_rate_scale, 4);
381 READ_UINT8 (nr, hrd->cpb_size_scale, 4);
383 if (hrd->sub_pic_hrd_params_present_flag)
384 READ_UINT8 (nr, hrd->cpb_size_du_scale, 4);
386 READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
387 READ_UINT8 (nr, hrd->au_cpb_removal_delay_length_minus1, 5);
388 READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
392 for (i = 0; i <= maxNumSubLayersMinus1; i++) {
393 READ_UINT8 (nr, hrd->fixed_pic_rate_general_flag[i], 1);
395 if (!hrd->fixed_pic_rate_general_flag[i]) {
396 READ_UINT8 (nr, hrd->fixed_pic_rate_within_cvs_flag[i], 1);
398 hrd->fixed_pic_rate_within_cvs_flag[i] = 1;
400 if (hrd->fixed_pic_rate_within_cvs_flag[i]) {
401 READ_UE_MAX (nr, hrd->elemental_duration_in_tc_minus1[i], 2047);
403 READ_UINT8 (nr, hrd->low_delay_hrd_flag[i], 1);
405 if (!hrd->low_delay_hrd_flag[i])
406 READ_UE_MAX (nr, hrd->cpb_cnt_minus1[i], 31);
408 if (hrd->nal_hrd_parameters_present_flag)
409 if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
410 [i], nr, hrd->cpb_cnt_minus1[i],
411 hrd->sub_pic_hrd_params_present_flag))
414 if (hrd->vcl_hrd_parameters_present_flag)
415 if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
416 [i], nr, hrd->cpb_cnt_minus1[i],
417 hrd->sub_pic_hrd_params_present_flag))
424 GST_WARNING ("error parsing \"HRD Parameters\"");
429 gst_h265_parse_vui_parameters (GstH265SPS * sps, NalReader * nr)
431 GstH265VUIParams *vui = &sps->vui_params;
433 GST_DEBUG ("parsing \"VUI Parameters\"");
435 /* set default values for fields that might not be present in the bitstream
436 and have valid defaults */
437 vui->video_format = 5;
438 vui->colour_primaries = 2;
439 vui->transfer_characteristics = 2;
440 vui->matrix_coefficients = 2;
441 vui->motion_vectors_over_pic_boundaries_flag = 1;
442 vui->max_bytes_per_pic_denom = 2;
443 vui->max_bits_per_min_cu_denom = 1;
444 vui->log2_max_mv_length_horizontal = 15;
445 vui->log2_max_mv_length_vertical = 15;
447 if (sps && sps->profile_tier_level.progressive_source_flag
448 && sps->profile_tier_level.interlaced_source_flag)
449 vui->frame_field_info_present_flag = 1;
451 READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
452 if (vui->aspect_ratio_info_present_flag) {
453 READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
454 if (vui->aspect_ratio_idc == EXTENDED_SAR) {
455 READ_UINT16 (nr, vui->sar_width, 16);
456 READ_UINT16 (nr, vui->sar_height, 16);
457 vui->par_n = vui->sar_width;
458 vui->par_d = vui->sar_height;
459 } else if (vui->aspect_ratio_idc <= 16) {
460 vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
461 vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
465 READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
466 if (vui->overscan_info_present_flag)
467 READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);
469 READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
470 if (vui->video_signal_type_present_flag) {
472 READ_UINT8 (nr, vui->video_format, 3);
473 READ_UINT8 (nr, vui->video_full_range_flag, 1);
474 READ_UINT8 (nr, vui->colour_description_present_flag, 1);
475 if (vui->colour_description_present_flag) {
476 READ_UINT8 (nr, vui->colour_primaries, 8);
477 READ_UINT8 (nr, vui->transfer_characteristics, 8);
478 READ_UINT8 (nr, vui->matrix_coefficients, 8);
482 READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
483 if (vui->chroma_loc_info_present_flag) {
484 READ_UE_MAX (nr, vui->chroma_sample_loc_type_top_field, 5);
485 READ_UE_MAX (nr, vui->chroma_sample_loc_type_bottom_field, 5);
488 READ_UINT8 (nr, vui->neutral_chroma_indication_flag, 1);
489 READ_UINT8 (nr, vui->field_seq_flag, 1);
490 READ_UINT8 (nr, vui->frame_field_info_present_flag, 1);
492 READ_UINT8 (nr, vui->default_display_window_flag, 1);
493 if (vui->default_display_window_flag) {
494 READ_UE (nr, vui->def_disp_win_left_offset);
495 READ_UE (nr, vui->def_disp_win_right_offset);
496 READ_UE (nr, vui->def_disp_win_top_offset);
497 READ_UE (nr, vui->def_disp_win_bottom_offset);
500 READ_UINT8 (nr, vui->timing_info_present_flag, 1);
501 if (vui->timing_info_present_flag) {
502 READ_UINT32 (nr, vui->num_units_in_tick, 32);
503 if (vui->num_units_in_tick == 0)
504 GST_WARNING ("num_units_in_tick = 0 detected in stream "
505 "(incompliant to H.265 E.2.1).");
507 READ_UINT32 (nr, vui->time_scale, 32);
508 if (vui->time_scale == 0)
509 GST_WARNING ("time_scale = 0 detected in stream "
510 "(incompliant to H.265 E.2.1).");
512 READ_UINT8 (nr, vui->poc_proportional_to_timing_flag, 1);
513 if (vui->poc_proportional_to_timing_flag)
514 READ_UE_MAX (nr, vui->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
516 READ_UINT8 (nr, vui->hrd_parameters_present_flag, 1);
517 if (vui->hrd_parameters_present_flag)
518 if (!gst_h265_parse_hrd_parameters (&vui->hrd_params, nr, 1,
519 sps->max_sub_layers_minus1))
523 READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
524 if (vui->bitstream_restriction_flag) {
525 READ_UINT8 (nr, vui->tiles_fixed_structure_flag, 1);
526 READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
527 READ_UINT8 (nr, vui->restricted_ref_pic_lists_flag, 1);
528 READ_UE_MAX (nr, vui->min_spatial_segmentation_idc, 4096);
529 READ_UE_MAX (nr, vui->max_bytes_per_pic_denom, 16);
530 READ_UE_MAX (nr, vui->max_bits_per_min_cu_denom, 16);
531 READ_UE_MAX (nr, vui->log2_max_mv_length_horizontal, 16);
532 READ_UE_MAX (nr, vui->log2_max_mv_length_vertical, 15);
538 GST_WARNING ("error parsing \"VUI Parameters\"");
543 get_scaling_list_params (GstH265ScalingList * dest_scaling_list,
544 guint8 sizeId, guint8 matrixId, guint8 ** sl, guint8 * size,
545 gint16 ** scaling_list_dc_coef_minus8)
548 case GST_H265_QUANT_MATIX_4X4:
549 *sl = dest_scaling_list->scaling_lists_4x4[matrixId];
553 case GST_H265_QUANT_MATIX_8X8:
554 *sl = dest_scaling_list->scaling_lists_8x8[matrixId];
558 case GST_H265_QUANT_MATIX_16X16:
559 *sl = dest_scaling_list->scaling_lists_16x16[matrixId];
562 if (scaling_list_dc_coef_minus8)
563 *scaling_list_dc_coef_minus8 =
564 dest_scaling_list->scaling_list_dc_coef_minus8_16x16;
566 case GST_H265_QUANT_MATIX_32X32:
567 *sl = dest_scaling_list->scaling_lists_32x32[matrixId];
570 if (scaling_list_dc_coef_minus8)
571 *scaling_list_dc_coef_minus8 =
572 dest_scaling_list->scaling_list_dc_coef_minus8_32x32;
581 get_default_scaling_lists (guint8 ** sl, guint8 sizeId, guint8 matrixId)
584 case GST_H265_QUANT_MATIX_4X4:
585 memcpy (*sl, default_scaling_list0, 16);
588 case GST_H265_QUANT_MATIX_8X8:
589 case GST_H265_QUANT_MATIX_16X16:
591 memcpy (*sl, default_scaling_list1, 64);
593 memcpy (*sl, default_scaling_list2, 64);
596 case GST_H265_QUANT_MATIX_32X32:
598 memcpy (*sl, default_scaling_list1, 64);
600 memcpy (*sl, default_scaling_list2, 64);
611 gst_h265_parser_parse_scaling_lists (NalReader * nr,
612 GstH265ScalingList * dest_scaling_list, gboolean use_default)
616 guint8 scaling_list_pred_mode_flag = 0;
617 guint8 scaling_list_pred_matrix_id_delta = 0;
620 GST_DEBUG ("parsing scaling lists");
622 for (sizeId = 0; sizeId < 4; sizeId++) {
623 for (matrixId = 0; matrixId < ((sizeId == 3) ? 2 : 6); matrixId++) {
624 gint16 *scaling_list_dc_coef_minus8 = NULL;
627 if (!get_scaling_list_params (dest_scaling_list, sizeId, matrixId, &sl,
628 &size, &scaling_list_dc_coef_minus8))
631 /* use_default_scaling_matrices forcefully which means,
632 * sps_scaling_list_enabled_flag=TRUE,
633 * sps_scaling_list_data_present_flag=FALSE,
634 * pps_scaling_list_data_present_falg=FALSE */
636 if (!get_default_scaling_lists (&sl, sizeId, matrixId))
639 /* Inferring the value of scaling_list_dc_coef_minus8 */
641 scaling_list_dc_coef_minus8[matrixId] = 8;
644 READ_UINT8 (nr, scaling_list_pred_mode_flag, 1);
646 if (!scaling_list_pred_mode_flag) {
649 READ_UE_MAX (nr, scaling_list_pred_matrix_id_delta, matrixId);
651 if (!scaling_list_pred_matrix_id_delta) {
652 if (!get_default_scaling_lists (&sl, sizeId, matrixId))
655 /* Inferring the value of scaling_list_dc_coef_minus8 */
657 scaling_list_dc_coef_minus8[matrixId] = 8;
662 refMatrixId = matrixId - scaling_list_pred_matrix_id_delta; /* 7-30 */
664 if (!get_scaling_list_params (dest_scaling_list, sizeId,
665 refMatrixId, &temp_sl, NULL, NULL))
668 for (i = 0; i < size; i++)
669 sl[i] = temp_sl[i]; /* 7-31 */
672 /* Inferring the value of scaling_list_dc_coef_minus8 */
674 scaling_list_dc_coef_minus8[matrixId] =
675 scaling_list_dc_coef_minus8[refMatrixId];
679 gint8 scaling_list_delta_coef;
682 READ_SE_ALLOWED (nr, scaling_list_dc_coef_minus8[matrixId], -7,
684 nextCoef = scaling_list_dc_coef_minus8[matrixId] + 8;
687 for (i = 0; i < size; i++) {
688 READ_SE_ALLOWED (nr, scaling_list_delta_coef, -128, 127);
689 nextCoef = (nextCoef + scaling_list_delta_coef) & 0xff;
700 GST_WARNING ("error parsing scaling lists");
705 gst_h265_parser_parse_short_term_ref_pic_sets (GstH265ShortTermRefPicSet *
706 stRPS, NalReader * nr, guint8 stRpsIdx, GstH265SPS * sps)
708 guint8 num_short_term_ref_pic_sets;
709 guint8 RefRpsIdx = 0;
711 guint8 use_delta_flag[16] = { 0 };
712 guint8 used_by_curr_pic_flag[16] = { 0 };
713 guint32 delta_poc_s0_minus1[16] = { 0 };
714 guint32 delta_poc_s1_minus1[16] = { 0 };
718 GST_DEBUG ("parsing \"ShortTermRefPicSetParameters\"");
720 /* set default values for fields that might not be present in the bitstream
721 and have valid defaults */
722 for (j = 0; j < 16; j++)
723 use_delta_flag[j] = 1;
725 num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
728 READ_UINT8 (nr, stRPS->inter_ref_pic_set_prediction_flag, 1);
730 if (stRPS->inter_ref_pic_set_prediction_flag) {
731 GstH265ShortTermRefPicSet *RefRPS;
733 if (stRpsIdx == num_short_term_ref_pic_sets)
734 READ_UE_MAX (nr, stRPS->delta_idx_minus1, stRpsIdx - 1);
736 READ_UINT8 (nr, stRPS->delta_rps_sign, 1);
737 READ_UE_MAX (nr, stRPS->abs_delta_rps_minus1, 32767);
739 RefRpsIdx = stRpsIdx - stRPS->delta_idx_minus1 - 1; /* 7-45 */
740 deltaRps = (1 - 2 * stRPS->delta_rps_sign) * (stRPS->abs_delta_rps_minus1 + 1); /* 7-46 */
742 RefRPS = &sps->short_term_ref_pic_set[RefRpsIdx];
744 for (j = 0; j <= RefRPS->NumDeltaPocs; j++) {
745 READ_UINT8 (nr, used_by_curr_pic_flag[j], 1);
746 if (!used_by_curr_pic_flag[j])
747 READ_UINT8 (nr, use_delta_flag[j], 1);
750 /* 7-47: calcuate NumNegativePics, DeltaPocS0 and UsedByCurrPicS0 */
752 for (j = (RefRPS->NumPositivePics - 1); j >= 0; j--) {
753 dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
754 if (dPoc < 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
755 stRPS->DeltaPocS0[i] = dPoc;
756 stRPS->UsedByCurrPicS0[i++] =
757 used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
760 if (deltaRps < 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
761 stRPS->DeltaPocS0[i] = deltaRps;
762 stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
764 for (j = 0; j < RefRPS->NumNegativePics; j++) {
765 dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
766 if (dPoc < 0 && use_delta_flag[j]) {
767 stRPS->DeltaPocS0[i] = dPoc;
768 stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[j];
771 stRPS->NumNegativePics = i;
773 /* 7-48: calcuate NumPositivePics, DeltaPocS1 and UsedByCurrPicS1 */
775 for (j = (RefRPS->NumNegativePics - 1); j >= 0; j--) {
776 dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
777 if (dPoc > 0 && use_delta_flag[j]) {
778 stRPS->DeltaPocS1[i] = dPoc;
779 stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[j];
782 if (deltaRps > 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
783 stRPS->DeltaPocS1[i] = deltaRps;
784 stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
786 for (j = 0; j < RefRPS->NumPositivePics; j++) {
787 dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
788 if (dPoc > 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
789 stRPS->DeltaPocS1[i] = dPoc;
790 stRPS->UsedByCurrPicS1[i++] =
791 used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
794 stRPS->NumPositivePics = i;
798 READ_UE_MAX (nr, stRPS->NumNegativePics,
799 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1]);
802 READ_UE_MAX (nr, stRPS->NumPositivePics,
803 (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] -
804 stRPS->NumNegativePics));
806 for (i = 0; i < stRPS->NumNegativePics; i++) {
807 READ_UE_MAX (nr, delta_poc_s0_minus1[i], 32767);
809 READ_UINT8 (nr, stRPS->UsedByCurrPicS0[i], 1);
813 stRPS->DeltaPocS0[i] = -(delta_poc_s0_minus1[i] + 1);
816 stRPS->DeltaPocS0[i] =
817 stRPS->DeltaPocS0[i - 1] - (delta_poc_s0_minus1[i] + 1);
821 for (j = 0; j < stRPS->NumPositivePics; j++) {
822 READ_UE_MAX (nr, delta_poc_s1_minus1[j], 32767);
825 READ_UINT8 (nr, stRPS->UsedByCurrPicS1[j], 1);
829 stRPS->DeltaPocS1[j] = delta_poc_s1_minus1[j] + 1;
832 stRPS->DeltaPocS1[j] =
833 stRPS->DeltaPocS1[j - 1] + (delta_poc_s1_minus1[j] + 1);
840 stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;
845 GST_WARNING ("error parsing \"ShortTermRefPicSet Parameters\"");
850 gst_h265_slice_parse_ref_pic_list_modification (GstH265SliceHdr * slice,
851 NalReader * nr, gint NumPocTotalCurr)
854 GstH265RefPicListModification *rpl_mod = &slice->ref_pic_list_modification;
855 const guint n = ceil_log2 (NumPocTotalCurr);
857 READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l0, 1);
859 if (rpl_mod->ref_pic_list_modification_flag_l0) {
860 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
861 READ_UINT32 (nr, rpl_mod->list_entry_l0[i], n);
862 CHECK_ALLOWED_MAX (rpl_mod->list_entry_l0[i], (NumPocTotalCurr - 1));
865 if (GST_H265_IS_B_SLICE (slice)) {
866 READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l1, 1);
867 if (rpl_mod->ref_pic_list_modification_flag_l1)
868 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
869 READ_UINT32 (nr, rpl_mod->list_entry_l1[i], n);
870 CHECK_ALLOWED_MAX (rpl_mod->list_entry_l1[i], (NumPocTotalCurr - 1));
877 GST_WARNING ("error parsing \"Prediction weight table\"");
882 gst_h265_slice_parse_pred_weight_table (GstH265SliceHdr * slice, NalReader * nr)
884 GstH265PredWeightTable *p;
886 GstH265PPS *pps = slice->pps;
887 GstH265SPS *sps = pps->sps;
889 GST_DEBUG ("parsing \"Prediction weight table\"");
891 p = &slice->pred_weight_table;
893 READ_UE_MAX (nr, p->luma_log2_weight_denom, 7);
895 if (sps->chroma_format_idc != 0) {
896 READ_SE_ALLOWED (nr, p->delta_chroma_log2_weight_denom,
897 (0 - p->luma_log2_weight_denom), (7 - p->luma_log2_weight_denom));
900 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
901 READ_UINT8 (nr, p->luma_weight_l0_flag[i], 1);
903 if (sps->chroma_format_idc != 0)
904 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
905 READ_UINT8 (nr, p->chroma_weight_l0_flag[i], 1);
907 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
908 if (p->luma_weight_l0_flag[i]) {
909 READ_SE_ALLOWED (nr, p->delta_luma_weight_l0[i], -128, 127);
910 READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
912 if (p->chroma_weight_l0_flag[i])
913 for (j = 0; j < 2; j++) {
914 READ_SE_ALLOWED (nr, p->delta_chroma_weight_l0[i][j], -128, 127);
915 READ_SE_ALLOWED (nr, p->delta_chroma_offset_l0[i][j], -512, 511);
919 if (GST_H265_IS_B_SLICE (slice)) {
920 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
921 READ_UINT8 (nr, p->luma_weight_l1_flag[i], 1);
922 if (sps->chroma_format_idc != 0)
923 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
924 READ_UINT8 (nr, p->chroma_weight_l1_flag[i], 1);
926 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
927 if (p->luma_weight_l1_flag[i]) {
928 READ_SE_ALLOWED (nr, p->delta_luma_weight_l1[i], -128, 127);
929 READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
931 if (p->chroma_weight_l1_flag[i])
932 for (j = 0; j < 2; j++) {
933 READ_SE_ALLOWED (nr, p->delta_chroma_weight_l1[i][j], -128, 127);
934 READ_SE_ALLOWED (nr, p->delta_chroma_offset_l1[i][j], -512, 511);
942 GST_WARNING ("error parsing \"Prediction weight table\"");
946 static GstH265ParserResult
947 gst_h265_parser_parse_buffering_period (GstH265Parser * parser,
948 GstH265BufferingPeriod * per, NalReader * nr)
955 GST_DEBUG ("parsing \"Buffering period\"");
957 READ_UE_MAX (nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
958 sps = gst_h265_parser_get_sps (parser, sps_id);
960 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
962 return GST_H265_PARSER_BROKEN_LINK;
966 if (sps->vui_parameters_present_flag) {
967 GstH265VUIParams *vui = &sps->vui_params;
968 GstH265HRDParams *hrd = &vui->hrd_params;
970 if (!hrd->sub_pic_hrd_params_present_flag)
971 READ_UINT8 (nr, per->irap_cpb_params_present_flag, 1);
973 if (per->irap_cpb_params_present_flag) {
974 READ_UINT8 (nr, per->cpb_delay_offset,
975 (hrd->au_cpb_removal_delay_length_minus1 + 1));
976 READ_UINT8 (nr, per->dpb_delay_offset,
977 (hrd->dpb_output_delay_length_minus1 + 1));
980 n = hrd->initial_cpb_removal_delay_length_minus1 + 1;
982 READ_UINT8 (nr, per->concatenation_flag, 1);
983 READ_UINT8 (nr, per->au_cpb_removal_delay_delta_minus1,
984 (hrd->au_cpb_removal_delay_length_minus1 + 1));
986 if (hrd->nal_hrd_parameters_present_flag) {
987 for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
988 READ_UINT8 (nr, per->nal_initial_cpb_removal_delay[i], n);
989 READ_UINT8 (nr, per->nal_initial_cpb_removal_offset[i], n);
990 if (hrd->sub_pic_hrd_params_present_flag
991 || per->irap_cpb_params_present_flag) {
992 READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_delay[i], n);
993 READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_offset[i], n);
998 if (hrd->vcl_hrd_parameters_present_flag) {
999 for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
1000 READ_UINT8 (nr, per->vcl_initial_cpb_removal_delay[i], n);
1001 READ_UINT8 (nr, per->vcl_initial_cpb_removal_offset[i], n);
1002 if (hrd->sub_pic_hrd_params_present_flag
1003 || per->irap_cpb_params_present_flag) {
1004 READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_delay[i], n);
1005 READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_offset[i], n);
1011 return GST_H265_PARSER_OK;
1014 GST_WARNING ("error parsing \"Buffering period\"");
1015 return GST_H265_PARSER_ERROR;
1018 static GstH265ParserResult
1019 gst_h265_parser_parse_pic_timing (GstH265Parser * parser,
1020 GstH265PicTiming * tim, NalReader * nr)
1022 GstH265ProfileTierLevel *profile_tier_level;
1025 GST_DEBUG ("parsing \"Picture timing\"");
1026 if (!parser->last_sps || !parser->last_sps->valid) {
1027 GST_WARNING ("didn't get the associated sequence paramater set for the "
1028 "current access unit");
1032 profile_tier_level = &parser->last_sps->profile_tier_level;
1034 /* set default values */
1035 if (!profile_tier_level->progressive_source_flag
1036 && profile_tier_level->interlaced_source_flag)
1037 tim->source_scan_type = 0;
1038 else if (profile_tier_level->progressive_source_flag
1039 && !profile_tier_level->interlaced_source_flag)
1040 tim->source_scan_type = 1;
1042 tim->source_scan_type = 2;
1044 if (parser->last_sps->vui_parameters_present_flag) {
1045 GstH265VUIParams *vui = &parser->last_sps->vui_params;
1047 if (vui->frame_field_info_present_flag) {
1048 READ_UINT8 (nr, tim->pic_struct, 4);
1049 READ_UINT8 (nr, tim->source_scan_type, 2);
1050 READ_UINT8 (nr, tim->duplicate_flag, 1);
1052 /* set default values */
1053 tim->pic_struct = 0;
1056 if (vui->hrd_parameters_present_flag) {
1057 GstH265HRDParams *hrd = &vui->hrd_params;
1059 READ_UINT8 (nr, tim->au_cpb_removal_delay_minus1,
1060 (hrd->au_cpb_removal_delay_length_minus1 + 1));
1061 READ_UINT8 (nr, tim->pic_dpb_output_delay,
1062 (hrd->dpb_output_delay_length_minus1 + 1));
1064 if (hrd->sub_pic_hrd_params_present_flag)
1065 READ_UINT8 (nr, tim->pic_dpb_output_du_delay,
1066 (hrd->dpb_output_delay_du_length_minus1 + 1));
1068 if (hrd->sub_pic_hrd_params_present_flag
1069 && hrd->sub_pic_cpb_params_in_pic_timing_sei_flag) {
1070 READ_UE (nr, tim->num_decoding_units_minus1);
1072 READ_UINT8 (nr, tim->du_common_cpb_removal_delay_flag, 1);
1073 if (tim->du_common_cpb_removal_delay_flag)
1074 READ_UINT8 (nr, tim->du_common_cpb_removal_delay_increment_minus1,
1075 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1077 tim->num_nalus_in_du_minus1 =
1078 g_new0 (guint32, (tim->num_decoding_units_minus1 + 1));
1079 tim->du_cpb_removal_delay_increment_minus1 =
1080 g_new0 (guint8, (tim->num_decoding_units_minus1 + 1));
1082 for (i = 0; i <= (tim->num_decoding_units_minus1 + 1); i++) {
1083 READ_UE (nr, tim->num_nalus_in_du_minus1[i]);
1085 if (!tim->du_common_cpb_removal_delay_flag
1086 && (i < tim->num_decoding_units_minus1))
1087 READ_UINT8 (nr, tim->du_cpb_removal_delay_increment_minus1[i],
1088 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1093 return GST_H265_PARSER_OK;
1096 GST_WARNING ("error parsing \"Picture timing\"");
1097 return GST_H265_PARSER_ERROR;
1100 /******** API *************/
1103 * gst_h265_parser_new:
1105 * Creates a new #GstH265Parser. It should be freed with
1106 * gst_h265_parser_free after use.
1108 * Returns: a new #GstH265Parser
1111 gst_h265_parser_new (void)
1113 GstH265Parser *parser;
1115 parser = g_slice_new0 (GstH265Parser);
1116 INITIALIZE_DEBUG_CATEGORY;
1122 * gst_h265_parser_free:
1123 * @parser: the #GstH265Parser to free
1125 * Frees @parser and sets it to %NULL
1128 gst_h265_parser_free (GstH265Parser * parser)
1130 g_slice_free (GstH265Parser, parser);
1135 * gst_h265_parser_identify_nalu_unchecked:
1136 * @parser: a #GstH265Parser
1137 * @data: The data to parse
1138 * @offset: the offset from which to parse @data
1139 * @size: the size of @data
1140 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1142 * Parses @data and fills @nalu from the next nalu data from @data.
1144 * This differs from @gst_h265_parser_identify_nalu in that it doesn't
1145 * check whether the packet is complete or not.
1147 * Note: Only use this function if you already know the provided @data
1148 * is a complete NALU, else use @gst_h265_parser_identify_nalu.
1150 * Returns: a #GstH265ParserResult
1153 gst_h265_parser_identify_nalu_unchecked (GstH265Parser * parser,
1154 const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1158 memset (nalu, 0, sizeof (*nalu));
1160 if (size < offset + 4) {
1161 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1162 ", offset %u", size, offset);
1163 return GST_H265_PARSER_ERROR;
1166 off1 = scan_for_start_codes (data + offset, size - offset);
1169 GST_DEBUG ("No start code prefix in this buffer");
1170 return GST_H265_PARSER_NO_NAL;
1173 if (offset + off1 == size - 1) {
1174 GST_DEBUG ("Missing data to identify nal unit");
1176 return GST_H265_PARSER_ERROR;
1179 nalu->sc_offset = offset + off1;
1181 /* sc might have 2 or 3 0-bytes */
1182 if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
1185 nalu->offset = offset + off1 + 3;
1186 nalu->data = (guint8 *) data;
1187 nalu->size = size - nalu->offset;
1189 if (!gst_h265_parse_nalu_header (nalu)) {
1190 GST_WARNING ("error parsing \"NAL unit header\"");
1192 return GST_H265_PARSER_BROKEN_DATA;
1197 if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB) {
1198 GST_DEBUG ("end-of-seq or end-of-stream nal found");
1200 return GST_H265_PARSER_OK;
1203 return GST_H265_PARSER_OK;
1207 * gst_h265_parser_identify_nalu:
1208 * @parser: a #GstH265Parser
1209 * @data: The data to parse
1210 * @offset: the offset from which to parse @data
1211 * @size: the size of @data
1212 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1214 * Parses @data and fills @nalu from the next nalu data from @data
1216 * Returns: a #GstH265ParserResult
1219 gst_h265_parser_identify_nalu (GstH265Parser * parser,
1220 const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1222 GstH265ParserResult res;
1226 gst_h265_parser_identify_nalu_unchecked (parser, data, offset, size,
1229 if (res != GST_H265_PARSER_OK)
1232 /* The two NALs are exactly 2 bytes size and are placed at the end of an AU,
1233 * there is no need to wait for the following */
1234 if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB)
1237 off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1239 GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1241 return GST_H265_PARSER_NO_NAL_END;
1244 /* Mini performance improvement:
1245 * We could have a way to store how many 0s were skipped to avoid
1246 * parsing them again on the next NAL */
1247 while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1252 return GST_H265_PARSER_BROKEN_DATA;
1254 GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1261 * gst_h265_parser_identify_nalu_hevc:
1262 * @parser: a #GstH265Parser
1263 * @data: The data to parse, must be the beging of the Nal unit
1264 * @offset: the offset from which to parse @data
1265 * @size: the size of @data
1266 * @nal_length_size: the size in bytes of the HEVC nal length prefix.
1267 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1269 * Parses @data and sets @nalu.
1271 * Returns: a #GstH265ParserResult
1274 gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
1275 const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1276 GstH265NalUnit * nalu)
1280 memset (nalu, 0, sizeof (*nalu));
1282 if (size < offset + nal_length_size) {
1283 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1284 ", offset %u", size, offset);
1285 return GST_H265_PARSER_ERROR;
1288 size = size - offset;
1289 gst_bit_reader_init (&br, data + offset, size);
1291 nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1292 nal_length_size * 8);
1293 nalu->sc_offset = offset;
1294 nalu->offset = offset + nal_length_size;
1296 if (size < nalu->size + nal_length_size) {
1299 return GST_H265_PARSER_NO_NAL_END;
1302 nalu->data = (guint8 *) data;
1304 if (!gst_h265_parse_nalu_header (nalu)) {
1305 GST_WARNING ("error parsing \"NAL unit header\"");
1307 return GST_H265_PARSER_BROKEN_DATA;
1311 return GST_H265_PARSER_BROKEN_DATA;
1315 return GST_H265_PARSER_OK;
1319 * gst_h265_parser_parse_nal:
1320 * @parser: a #GstH265Parser
1321 * @nalu: The #GstH265NalUnit to parse
1323 * This function should be called in the case one doesn't need to
1324 * parse a specific structure. It is necessary to do so to make
1325 * sure @parser is up to date.
1327 * Returns: a #GstH265ParserResult
1330 gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
1336 switch (nalu->type) {
1337 case GST_H265_NAL_VPS:
1338 return gst_h265_parser_parse_vps (parser, nalu, &vps);
1340 case GST_H265_NAL_SPS:
1341 return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
1343 case GST_H265_NAL_PPS:
1344 return gst_h265_parser_parse_pps (parser, nalu, &pps);
1347 return GST_H265_PARSER_OK;
1351 * gst_h265_parser_parse_vps:
1352 * @parser: a #GstH265Parser
1353 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1354 * @vps: The #GstH265VPS to fill.
1356 * Parses @data, and fills the @vps structure.
1358 * Returns: a #GstH265ParserResult
1361 gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
1364 GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);
1366 if (res == GST_H265_PARSER_OK) {
1367 GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);
1369 parser->vps[vps->id] = *vps;
1370 parser->last_vps = &parser->vps[vps->id];
1377 * gst_h265_parse_vps:
1378 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1379 * @sps: The #GstH265VPS to fill.
1381 * Parses @data, and fills the @vps structure.
1383 * Returns: a #GstH265ParserResult
1386 gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
1391 INITIALIZE_DEBUG_CATEGORY;
1392 GST_DEBUG ("parsing VPS");
1394 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1395 nalu->size - nalu->header_bytes);
1397 memset (vps, 0, sizeof (*vps));
1399 vps->cprms_present_flag = 1;
1401 READ_UINT8 (&nr, vps->id, 4);
1403 /* skip reserved_three_2bits */
1404 if (!nal_reader_skip (&nr, 2))
1407 READ_UINT8 (&nr, vps->max_layers_minus1, 6);
1408 READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
1409 READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1411 /* skip reserved_0xffff_16bits */
1412 if (!nal_reader_skip (&nr, 16))
1415 if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1416 vps->max_sub_layers_minus1))
1419 READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1422 (vps->sub_layer_ordering_info_present_flag ? 0 :
1423 vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1424 READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1425 READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1426 vps->max_dec_pic_buffering_minus1[i]);
1427 READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1429 /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1430 if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1431 for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1432 vps->max_dec_pic_buffering_minus1[i] =
1433 vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1434 vps->max_num_reorder_pics[i] =
1435 vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1436 vps->max_latency_increase_plus1[i] =
1437 vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1441 READ_UINT8 (&nr, vps->max_layer_id, 6);
1442 CHECK_ALLOWED_MAX (vps->max_layer_id, 0);
1444 READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1445 CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 0);
1447 for (i = 1; i <= vps->num_layer_sets_minus1; i++)
1448 for (j = 0; j <= vps->max_layer_id; j++)
1449 nal_reader_skip (&nr, 1);
1451 READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1453 if (vps->timing_info_present_flag) {
1454 READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1455 READ_UINT32 (&nr, vps->time_scale, 32);
1456 READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1458 if (vps->poc_proportional_to_timing_flag)
1459 READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1461 READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1462 CHECK_ALLOWED_MAX (vps->num_hrd_parameters, 1);
1464 if (vps->num_hrd_parameters) {
1465 READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1466 CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, 0);
1468 if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1469 vps->cprms_present_flag, vps->max_sub_layers_minus1))
1473 READ_UINT8 (&nr, vps->vps_extension, 1);
1476 return GST_H265_PARSER_OK;
1479 GST_WARNING ("error parsing \"Video parameter set\"");
1481 return GST_H265_PARSER_ERROR;
1485 * gst_h265_parser_parse_sps:
1486 * @parser: a #GstH265Parser
1487 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1488 * @sps: The #GstH265SPS to fill.
1489 * @parse_vui_params: Whether to parse the vui_params or not
1491 * Parses @data, and fills the @sps structure.
1493 * Returns: a #GstH265ParserResult
1496 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1497 GstH265SPS * sps, gboolean parse_vui_params)
1499 GstH265ParserResult res =
1500 gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1502 if (res == GST_H265_PARSER_OK) {
1503 GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1505 parser->sps[sps->id] = *sps;
1506 parser->last_sps = &parser->sps[sps->id];
1513 * gst_h265_parse_sps:
1514 * parser: The #GstH265Parser
1515 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1516 * @sps: The #GstH265SPS to fill.
1517 * @parse_vui_params: Whether to parse the vui_params or not
1519 * Parses @data, and fills the @sps structure.
1521 * Returns: a #GstH265ParserResult
1524 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1525 GstH265SPS * sps, gboolean parse_vui_params)
1531 guint subwc[] = { 1, 2, 2, 1, 1 };
1532 guint subhc[] = { 1, 2, 1, 1, 1 };
1533 GstH265VUIParams *vui = NULL;
1535 INITIALIZE_DEBUG_CATEGORY;
1536 GST_DEBUG ("parsing SPS");
1538 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1539 nalu->size - nalu->header_bytes);
1541 memset (sps, 0, sizeof (*sps));
1543 READ_UINT8 (&nr, vps_id, 4);
1544 vps = gst_h265_parser_get_vps (parser, vps_id);
1546 GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1551 READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1552 READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1554 if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1555 sps->max_sub_layers_minus1))
1558 READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1560 READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1561 if (sps->chroma_format_idc == 3)
1562 READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1564 READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1565 READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1567 READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1568 if (sps->conformance_window_flag) {
1569 READ_UE (&nr, sps->conf_win_left_offset);
1570 READ_UE (&nr, sps->conf_win_right_offset);
1571 READ_UE (&nr, sps->conf_win_top_offset);
1572 READ_UE (&nr, sps->conf_win_bottom_offset);
1575 READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1576 READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1577 READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1579 READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1581 (sps->sub_layer_ordering_info_present_flag ? 0 :
1582 sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1583 READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1584 READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1585 sps->max_dec_pic_buffering_minus1[i]);
1586 READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1588 /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1589 if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1590 for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1591 sps->max_dec_pic_buffering_minus1[i] =
1592 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1593 sps->max_num_reorder_pics[i] =
1594 sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1595 sps->max_latency_increase_plus1[i] =
1596 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1600 /* The limits are calculted based on the profile_tier_level constraint
1601 * in Annex-A: CtbLog2SizeY = 4 to 6 */
1602 READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1603 READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1604 READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1605 READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1606 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1607 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1609 READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1610 if (sps->scaling_list_enabled_flag) {
1611 READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1613 if (sps->scaling_list_data_present_flag)
1614 if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1618 READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1619 READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1620 READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1622 if (sps->pcm_enabled_flag) {
1623 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1624 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1625 READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1626 READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1627 READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1630 READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1631 for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1632 if (!gst_h265_parser_parse_short_term_ref_pic_sets
1633 (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1636 READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1637 if (sps->long_term_ref_pics_present_flag) {
1638 READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1639 for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1640 READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1641 sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1642 READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1646 READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1647 READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1648 READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1650 if (sps->vui_parameters_present_flag && parse_vui_params) {
1651 if (!gst_h265_parse_vui_parameters (sps, &nr))
1653 vui = &sps->vui_params;
1656 READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1658 /* calculate ChromaArrayType */
1659 if (!sps->separate_colour_plane_flag)
1660 sps->chroma_array_type = sps->chroma_format_idc;
1662 /* Calculate width and height */
1663 sps->width = sps->pic_width_in_luma_samples;
1664 sps->height = sps->pic_height_in_luma_samples;
1665 if (sps->width < 0 || sps->height < 0) {
1666 GST_WARNING ("invalid width/height in SPS");
1670 if (sps->conformance_window_flag) {
1671 const guint crop_unit_x = subwc[sps->chroma_format_idc];
1672 const guint crop_unit_y = subhc[sps->chroma_format_idc];
1674 sps->crop_rect_width = sps->width -
1675 (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
1676 sps->crop_rect_height = sps->height -
1677 (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
1678 sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
1679 sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
1681 GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
1682 sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
1688 if (vui && vui->timing_info_present_flag) {
1689 /* derive framerate for progressive stream if the pic_struct
1690 * syntax element is not present in picture timing SEI messages */
1691 /* Fixme: handle other cases also */
1692 if (parse_vui_params && vui->timing_info_present_flag
1693 && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
1694 sps->fps_num = vui->time_scale;
1695 sps->fps_den = vui->num_units_in_tick;
1696 GST_LOG ("framerate %d/%d", sps->fps_num, sps->fps_den);
1699 GST_LOG ("No VUI, unknown framerate");
1704 return GST_H265_PARSER_OK;
1707 GST_WARNING ("error parsing \"Sequence parameter set\"");
1709 return GST_H265_PARSER_ERROR;
1713 * gst_h265_parse_pps:
1714 * @parser: a #GstH265Parser
1715 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1716 * @pps: The #GstH265PPS to fill.
1718 * Parses @data, and fills the @pps structure.
1720 * Returns: a #GstH265ParserResult
1723 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
1730 guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY;
1733 INITIALIZE_DEBUG_CATEGORY;
1734 GST_DEBUG ("parsing PPS");
1736 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1737 nalu->size - nalu->header_bytes);
1739 memset (pps, 0, sizeof (*pps));
1741 READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
1742 READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
1744 sps = gst_h265_parser_get_sps (parser, sps_id);
1746 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
1748 return GST_H265_PARSER_BROKEN_LINK;
1751 qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
1753 MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
1754 CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
1755 CtbSizeY = 1 << CtbLog2SizeY;
1756 pps->PicHeightInCtbsY =
1757 ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
1758 pps->PicWidthInCtbsY =
1759 ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
1761 /* set default values for fields that might not be present in the bitstream
1762 and have valid defaults */
1763 pps->uniform_spacing_flag = 1;
1764 pps->loop_filter_across_tiles_enabled_flag = 1;
1766 READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
1767 READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
1768 READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
1769 READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
1770 READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
1772 READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
1773 READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
1774 READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
1776 READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
1777 READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
1779 READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
1780 if (pps->cu_qp_delta_enabled_flag)
1781 READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
1782 sps->log2_diff_max_min_luma_coding_block_size);
1784 READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
1785 READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
1787 READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
1788 READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
1789 READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
1790 READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
1791 READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
1792 READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
1794 if (pps->tiles_enabled_flag) {
1795 READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 0, 19);
1796 READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 0, 21);
1798 READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
1799 /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
1800 if (pps->uniform_spacing_flag) {
1801 guint8 num_col = pps->num_tile_columns_minus1 + 1;
1802 guint8 num_row = pps->num_tile_rows_minus1 + 1;
1803 for (i = 0; i < num_col; i++) {
1804 pps->column_width_minus1[i] =
1805 ((i + 1) * pps->PicWidthInCtbsY / num_col
1806 - i * pps->PicWidthInCtbsY / num_col) - 1;
1808 for (i = 0; i < num_row; i++) {
1809 pps->row_height_minus1[i] =
1810 ((i + 1) * pps->PicHeightInCtbsY / num_row
1811 - i * pps->PicHeightInCtbsY / num_row) - 1;
1814 pps->column_width_minus1[pps->num_tile_columns_minus1] =
1815 pps->PicWidthInCtbsY - 1;
1816 for (i = 0; i < pps->num_tile_columns_minus1; i++) {
1817 READ_UE (&nr, pps->column_width_minus1[i]);
1818 pps->column_width_minus1[pps->num_tile_columns_minus1] -=
1819 (pps->column_width_minus1[i] + 1);
1822 pps->row_height_minus1[pps->num_tile_rows_minus1] =
1823 pps->PicHeightInCtbsY - 1;
1824 for (i = 0; i < pps->num_tile_rows_minus1; i++) {
1825 READ_UE (&nr, pps->row_height_minus1[i]);
1826 pps->row_height_minus1[pps->num_tile_rows_minus1] -=
1827 (pps->row_height_minus1[i] + 1);
1830 READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
1833 READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
1835 READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
1836 if (pps->deblocking_filter_control_present_flag) {
1837 READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
1839 READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
1840 if (!pps->deblocking_filter_disabled_flag) {
1841 READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
1842 READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
1846 READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
1847 if (pps->scaling_list_data_present_flag)
1848 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
1850 if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
1851 && !pps->scaling_list_data_present_flag)
1852 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
1855 READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
1856 READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
1857 READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
1858 READ_UINT8 (&nr, pps->pps_extension_flag, 1);
1861 return GST_H265_PARSER_OK;
1864 GST_WARNING ("error parsing \"Picture parameter set\"");
1866 return GST_H265_PARSER_ERROR;
1870 * gst_h265_parser_parse_pps:
1871 * @parser: a #GstH265Parser
1872 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1873 * @pps: The #GstH265PPS to fill.
1875 * Parses @data, and fills the @pps structure.
1877 * Returns: a #GstH265ParserResult
1880 gst_h265_parser_parse_pps (GstH265Parser * parser,
1881 GstH265NalUnit * nalu, GstH265PPS * pps)
1883 GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
1884 if (res == GST_H265_PARSER_OK) {
1885 GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
1887 parser->pps[pps->id] = *pps;
1888 parser->last_pps = &parser->pps[pps->id];
1895 * gst_h265_parser_parse_slice_hdr:
1896 * @parser: a #GstH265Parser
1897 * @nalu: The #GST_H265_NAL_SLICE #GstH265NalUnit to parse
1898 * @slice: The #GstH265SliceHdr to fill.
1900 * Parses @data, and fills the @slice structure.
1901 * The resulting @slice_hdr structure shall be deallocated with
1902 * gst_h265_slice_hdr_free() when it is no longer needed
1904 * Returns: a #GstH265ParserResult
1907 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
1908 GstH265NalUnit * nalu, GstH265SliceHdr * slice)
1915 GstH265ShortTermRefPicSet *stRPS = NULL;
1916 guint32 UsedByCurrPicLt[16];
1917 guint32 PicSizeInCtbsY;
1918 gint NumPocTotalCurr = 0;
1920 memset (slice, 0, sizeof (*slice));
1923 GST_DEBUG ("Invalid Nal Unit");
1924 return GST_H265_PARSER_ERROR;
1927 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1928 nalu->size - nalu->header_bytes);
1930 GST_DEBUG ("parsing \"Slice header\", slice type");
1932 READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
1934 if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP
1935 && nalu->type <= RESERVED_IRAP_NAL_TYPE_MAX)
1936 READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
1938 READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
1939 pps = gst_h265_parser_get_pps (parser, pps_id);
1942 ("couldn't find associated picture parameter set with id: %d", pps_id);
1943 return GST_H265_PARSER_BROKEN_LINK;
1950 ("couldn't find associated sequence parameter set with id: %d",
1952 return GST_H265_PARSER_BROKEN_LINK;
1955 PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
1956 /* set default values for fields that might not be present in the bitstream
1957 * and have valid defaults */
1958 slice->pic_output_flag = 1;
1959 slice->collocated_from_l0_flag = 1;
1960 slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
1961 slice->beta_offset_div2 = pps->beta_offset_div2;
1962 slice->tc_offset_div2 = pps->tc_offset_div2;
1963 slice->loop_filter_across_slices_enabled_flag =
1964 pps->loop_filter_across_slices_enabled_flag;
1966 if (!slice->first_slice_segment_in_pic_flag) {
1967 const guint n = ceil_log2 (PicSizeInCtbsY);
1969 if (pps->dependent_slice_segments_enabled_flag)
1970 READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
1971 /* sice_segment_address parsing */
1972 READ_UINT32 (&nr, slice->segment_address, n);
1975 if (!slice->dependent_slice_segment_flag) {
1976 for (i = 0; i < pps->num_extra_slice_header_bits; i++)
1977 nal_reader_skip (&nr, 1);
1978 READ_UE_MAX (&nr, slice->type, 63);
1981 if (pps->output_flag_present_flag)
1982 READ_UINT8 (&nr, slice->pic_output_flag, 1);
1983 if (sps->separate_colour_plane_flag == 1)
1984 READ_UINT8 (&nr, slice->colour_plane_id, 2);
1986 if ((nalu->type != GST_H265_NAL_SLICE_IDR_W_RADL)
1987 && (nalu->type != GST_H265_NAL_SLICE_IDR_N_LP)) {
1988 READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
1989 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
1991 READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
1992 if (!slice->short_term_ref_pic_set_sps_flag) {
1993 if (!gst_h265_parser_parse_short_term_ref_pic_sets
1994 (&slice->short_term_ref_pic_sets, &nr,
1995 sps->num_short_term_ref_pic_sets, sps))
1997 } else if (sps->num_short_term_ref_pic_sets > 1) {
1998 const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
1999 READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
2000 CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
2001 sps->num_short_term_ref_pic_sets - 1);
2004 if (sps->long_term_ref_pics_present_flag) {
2007 if (sps->num_long_term_ref_pics_sps > 0)
2008 READ_UE_MAX (&nr, slice->num_long_term_sps,
2009 sps->num_long_term_ref_pics_sps);
2011 READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2012 limit = slice->num_long_term_sps + slice->num_long_term_pics;
2013 for (i = 0; i < limit; i++) {
2014 if (i < slice->num_long_term_sps) {
2015 if (sps->num_long_term_ref_pics_sps > 1) {
2016 const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2017 READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2020 READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2021 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2022 READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2025 /* calculate UsedByCurrPicLt */
2026 if (i < slice->num_long_term_sps)
2027 UsedByCurrPicLt[i] =
2028 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2030 UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2031 READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2032 if (slice->delta_poc_msb_present_flag[i])
2033 READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2036 if (sps->temporal_mvp_enabled_flag)
2037 READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2040 if (sps->sample_adaptive_offset_enabled_flag) {
2041 READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2042 READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2045 if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2046 READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2048 if (slice->num_ref_idx_active_override_flag) {
2049 READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2050 if (GST_H265_IS_B_SLICE (slice))
2051 READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2053 /*set default values */
2054 slice->num_ref_idx_l0_active_minus1 =
2055 pps->num_ref_idx_l0_default_active_minus1;
2056 slice->num_ref_idx_l1_active_minus1 =
2057 pps->num_ref_idx_l1_default_active_minus1;
2060 /* calculate NumPocTotalCurr */
2061 if (slice->short_term_ref_pic_set_sps_flag)
2062 stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2064 stRPS = &slice->short_term_ref_pic_sets;
2066 for (i = 0; i < stRPS->NumNegativePics; i++)
2067 if (stRPS->UsedByCurrPicS0[i])
2069 for (i = 0; i < stRPS->NumPositivePics; i++)
2070 if (stRPS->UsedByCurrPicS1[i])
2073 i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2074 if (UsedByCurrPicLt[i])
2076 slice->NumPocTotalCurr = NumPocTotalCurr;
2078 if (pps->lists_modification_present_flag) {
2079 if (NumPocTotalCurr > 1)
2080 if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2085 if (GST_H265_IS_B_SLICE (slice))
2086 READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2087 if (pps->cabac_init_present_flag)
2088 READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2089 if (slice->temporal_mvp_enabled_flag) {
2090 if (GST_H265_IS_B_SLICE (slice))
2091 READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2093 if ((slice->collocated_from_l0_flag
2094 && slice->num_ref_idx_l0_active_minus1 > 0)
2095 || (!slice->collocated_from_l0_flag
2096 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2098 /*fixme: add optimization */
2099 if ((GST_H265_IS_P_SLICE (slice))
2100 || ((GST_H265_IS_B_SLICE (slice))
2101 && (slice->collocated_from_l0_flag))) {
2102 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2103 slice->num_ref_idx_l0_active_minus1);
2104 } else if ((GST_H265_IS_B_SLICE (slice))
2105 && (!slice->collocated_from_l0_flag)) {
2106 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2107 slice->num_ref_idx_l1_active_minus1);
2111 if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2112 (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2113 if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2115 READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2118 READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2119 if (pps->slice_chroma_qp_offsets_present_flag) {
2120 READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2121 READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2124 if (pps->deblocking_filter_override_enabled_flag)
2125 READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2126 if (slice->deblocking_filter_override_flag) {
2127 READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2128 if (!slice->deblocking_filter_disabled_flag) {
2129 READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2130 READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2134 if (pps->loop_filter_across_slices_enabled_flag &&
2135 (slice->sao_luma_flag || slice->sao_chroma_flag ||
2136 !slice->deblocking_filter_disabled_flag))
2137 READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2140 if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2143 if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2144 offset_max = pps->PicHeightInCtbsY - 1;
2145 else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2147 (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2151 (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2153 READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2154 if (slice->num_entry_point_offsets > 0) {
2155 READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2156 slice->entry_point_offset_minus1 =
2157 g_new0 (guint32, slice->num_entry_point_offsets);
2158 for (i = 0; i < slice->num_entry_point_offsets; i++)
2159 READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2160 (slice->offset_len_minus1 + 1));
2164 if (pps->slice_segment_header_extension_present_flag) {
2165 guint16 slice_segment_header_extension_length;
2166 READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2167 for (i = 0; i < slice_segment_header_extension_length; i++)
2168 if (!nal_reader_skip (&nr, 8))
2172 /* Skip the byte alignment bits */
2173 if (!nal_reader_skip (&nr, 1))
2175 while (!nal_reader_is_byte_aligned (&nr)) {
2176 if (!nal_reader_skip (&nr, 1))
2180 slice->header_size = nal_reader_get_pos (&nr);
2181 slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2183 return GST_H265_PARSER_OK;
2186 GST_WARNING ("error parsing \"Slice header\"");
2188 gst_h265_slice_hdr_free (slice);
2190 return GST_H265_PARSER_ERROR;
2194 nal_reader_has_more_data_in_payload (NalReader * nr,
2195 guint32 payload_start_pos_bit, guint32 payloadSize)
2197 if (nal_reader_is_byte_aligned (nr) &&
2198 (nal_reader_get_pos (nr) == (payload_start_pos_bit + 8 * payloadSize)))
2204 static GstH265ParserResult
2205 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2206 guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2208 guint32 payloadSize;
2209 guint8 payload_type_byte, payload_size_byte;
2210 guint remaining, payload_size;
2211 guint32 payload_start_pos_bit;
2212 GstH265ParserResult res = GST_H265_PARSER_OK;
2214 GST_DEBUG ("parsing \"Sei message\"");
2216 memset (sei, 0, sizeof (*sei));
2219 READ_UINT8 (nr, payload_type_byte, 8);
2220 sei->payloadType += payload_type_byte;
2221 } while (payload_type_byte == 0xff);
2224 READ_UINT8 (nr, payload_size_byte, 8);
2225 payloadSize += payload_size_byte;
2227 while (payload_size_byte == 0xff);
2229 remaining = nal_reader_get_remaining (nr);
2230 payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
2232 payload_start_pos_bit = nal_reader_get_pos (nr);
2234 ("SEI message received: payloadType %u, payloadSize = %u bytes",
2235 sei->payloadType, payload_size);
2237 if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2238 switch (sei->payloadType) {
2239 case GST_H265_SEI_BUF_PERIOD:
2240 /* size not set; might depend on emulation_prevention_three_byte */
2241 res = gst_h265_parser_parse_buffering_period (parser,
2242 &sei->payload.buffering_period, nr);
2244 case GST_H265_SEI_PIC_TIMING:
2245 /* size not set; might depend on emulation_prevention_three_byte */
2246 res = gst_h265_parser_parse_pic_timing (parser,
2247 &sei->payload.pic_timing, nr);
2250 /* Just consume payloadSize bytes, which does not account for
2251 emulation prevention bytes */
2252 if (!nal_reader_skip_long (nr, payload_size))
2254 res = GST_H265_PARSER_OK;
2257 } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2258 switch (sei->payloadType) {
2260 /* Just consume payloadSize bytes, which does not account for
2261 emulation prevention bytes */
2262 if (!nal_reader_skip_long (nr, payload_size))
2264 res = GST_H265_PARSER_OK;
2269 /* Not parsing the reserved_payload_extension, but it shouldn't be
2270 * an issue because of 1: There shall not be any reserved_payload_extension
2271 * present in bitstreams conforming to the specification.2. Even though
2272 * it is present, the size will be less than total PayloadSize since the
2273 * size of reserved_payload_extension is supposed to be
2274 * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2275 * the current implementation will still skip all unnecessary bits correctly.
2276 * In theory, we can have a more optimized implementation by skipping the
2277 * data left in PayLoadSize without out individually checking for each bits,
2278 * since the totoal size will be always less than payloadSize*/
2279 if (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
2281 /* Skip the byte alignment bits */
2282 if (!nal_reader_skip (nr, 1))
2284 while (!nal_reader_is_byte_aligned (nr)) {
2285 if (!nal_reader_skip (nr, 1))
2293 GST_WARNING ("error parsing \"Sei message\"");
2294 return GST_H265_PARSER_ERROR;
2298 * gst_h265_slice_hdr_copy:
2299 * @dst_slice: The destination #GstH265SliceHdr to copy into
2300 * @src_slice: The source #GstH265SliceHdr to copy from
2302 * Copies @src_slice into @dst_slice
2304 * Returns: %TRUE if everything went fine, %FALSE otherwise
2307 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2308 const GstH265SliceHdr * src_slice)
2312 g_return_val_if_fail (dst_slice != NULL, FALSE);
2313 g_return_val_if_fail (src_slice != NULL, FALSE);
2315 gst_h265_slice_hdr_free (dst_slice);
2317 *dst_slice = *src_slice;
2319 if (dst_slice->num_entry_point_offsets > 0) {
2320 dst_slice->entry_point_offset_minus1 =
2321 g_new0 (guint32, dst_slice->num_entry_point_offsets);
2322 for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2323 dst_slice->entry_point_offset_minus1[i] =
2324 src_slice->entry_point_offset_minus1[i];
2331 * gst_h265_slice_hdr_free:
2332 * slice_hdr: The #GstH265SliceHdr to free
2334 * Frees @slice_hdr fields.
2337 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2339 g_return_if_fail (slice_hdr != NULL);
2341 if (slice_hdr->num_entry_point_offsets > 0)
2342 g_free (slice_hdr->entry_point_offset_minus1);
2343 slice_hdr->entry_point_offset_minus1 = 0;
2347 * gst_h265_sei_copy:
2348 * @dst_sei: The destination #GstH265SEIMessage to copy into
2349 * @src_sei: The source #GstH265SEIMessage to copy from
2351 * Copies @src_sei into @dst_sei
2353 * Returns: %TRUE if everything went fine, %FALSE otherwise
2356 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2357 const GstH265SEIMessage * src_sei)
2361 g_return_val_if_fail (dst_sei != NULL, FALSE);
2362 g_return_val_if_fail (src_sei != NULL, FALSE);
2364 gst_h265_sei_free (dst_sei);
2366 *dst_sei = *src_sei;
2368 if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2369 GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2370 const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2372 if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2373 dst_pic_timing->num_nalus_in_du_minus1 =
2374 g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2375 dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2376 g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2378 for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2379 dst_pic_timing->num_nalus_in_du_minus1[i] =
2380 src_pic_timing->num_nalus_in_du_minus1[i];
2381 dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2382 src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2391 * gst_h265_sei_free:
2392 * sei: The #GstH265SEIMessage to free
2394 * Frees @sei fields.
2397 gst_h265_sei_free (GstH265SEIMessage * sei)
2399 g_return_if_fail (sei != NULL);
2401 if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2402 GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2403 if (pic_timing->num_decoding_units_minus1 > 0) {
2404 g_free (pic_timing->num_nalus_in_du_minus1);
2405 g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2407 pic_timing->num_nalus_in_du_minus1 = 0;
2408 pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2413 * gst_h265_parser_parse_sei:
2414 * @nalparser: a #GstH265Parser
2415 * @nalu: The #GST_H265_NAL_SEI #GstH265NalUnit to parse
2416 * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2418 * Parses @data, create and fills the @messages array.
2420 * Returns: a #GstH265ParserResult
2423 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2427 GstH265SEIMessage sei;
2428 GstH265ParserResult res;
2430 GST_DEBUG ("parsing SEI nal");
2431 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2432 nalu->size - nalu->header_bytes);
2433 *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
2434 g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
2437 res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
2438 if (res == GST_H265_PARSER_OK)
2439 g_array_append_val (*messages, sei);
2442 } while (nal_reader_has_more_data (&nr));
2449 * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
2450 * @out_quant: (out): The resulting quantization matrix
2451 * @quant: The source quantization matrix
2453 * Converts quantization matrix @quant from raster scan order to
2454 * zigzag scan order and store the resulting factors into @out_quant.
2456 * Note: it is an error to pass the same table in both @quant and
2457 * @out_quant arguments.
2462 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
2463 const guint8 quant[16])
2467 g_return_if_fail (out_quant != quant);
2469 for (i = 0; i < 16; i++)
2470 out_quant[i] = quant[zigzag_4x4[i]];
2474 * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
2475 * @out_quant: (out): The resulting quantization matrix
2476 * @quant: The source quantization matrix
2478 * Converts quantization matrix @quant from zigzag scan order to
2479 * raster scan order and store the resulting factors into @out_quant.
2481 * Note: it is an error to pass the same table in both @quant and
2482 * @out_quant arguments.
2487 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
2488 const guint8 quant[16])
2492 g_return_if_fail (out_quant != quant);
2494 for (i = 0; i < 16; i++)
2495 out_quant[zigzag_4x4[i]] = quant[i];
2499 * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
2500 * @out_quant: (out): The resulting quantization matrix
2501 * @quant: The source quantization matrix
2503 * Converts quantization matrix @quant from raster scan order to
2504 * zigzag scan order and store the resulting factors into @out_quant.
2506 * Note: it is an error to pass the same table in both @quant and
2507 * @out_quant arguments.
2512 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
2513 const guint8 quant[64])
2517 g_return_if_fail (out_quant != quant);
2519 for (i = 0; i < 64; i++)
2520 out_quant[i] = quant[zigzag_8x8[i]];
2524 * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
2525 * @out_quant: (out): The resulting quantization matrix
2526 * @quant: The source quantization matrix
2528 * Converts quantization matrix @quant from zigzag scan order to
2529 * raster scan order and store the resulting factors into @out_quant.
2531 * Note: it is an error to pass the same table in both @quant and
2532 * @out_quant arguments.
2537 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
2538 const guint8 quant[64])
2542 g_return_if_fail (out_quant != quant);
2544 for (i = 0; i < 64; i++)
2545 out_quant[zigzag_8x8[i]] = quant[i];
2549 * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
2550 * @out_quant: (out): The resulting quantization matrix
2551 * @quant: The source quantization matrix
2553 * Converts quantization matrix @quant from raster scan order to
2554 * uprightdiagonal scan order and store the resulting factors
2557 * Note: it is an error to pass the same table in both @quant and
2558 * @out_quant arguments.
2563 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
2564 const guint8 quant[16])
2568 g_return_if_fail (out_quant != quant);
2570 for (i = 0; i < 16; i++)
2571 out_quant[i] = quant[uprightdiagonal_4x4[i]];
2575 * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
2576 * @out_quant: (out): The resulting quantization matrix
2577 * @quant: The source quantization matrix
2579 * Converts quantization matrix @quant from uprightdiagonal scan order to
2580 * raster scan order and store the resulting factors into @out_quant.
2582 * Note: it is an error to pass the same table in both @quant and
2583 * @out_quant arguments.
2588 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
2589 const guint8 quant[16])
2593 g_return_if_fail (out_quant != quant);
2595 for (i = 0; i < 16; i++)
2596 out_quant[uprightdiagonal_4x4[i]] = quant[i];
2600 * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
2601 * @out_quant: (out): The resulting quantization matrix
2602 * @quant: The source quantization matrix
2604 * Converts quantization matrix @quant from raster scan order to
2605 * uprightdiagonal scan order and store the resulting factors
2608 * Note: it is an error to pass the same table in both @quant and
2609 * @out_quant arguments.
2614 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
2615 const guint8 quant[64])
2619 g_return_if_fail (out_quant != quant);
2621 for (i = 0; i < 64; i++)
2622 out_quant[i] = quant[uprightdiagonal_8x8[i]];
2626 * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
2627 * @out_quant: (out): The resulting quantization matrix
2628 * @quant: The source quantization matrix
2630 * Converts quantization matrix @quant from uprightdiagonal scan order to
2631 * raster scan order and store the resulting factors into @out_quant.
2633 * Note: it is an error to pass the same table in both @quant and
2634 * @out_quant arguments.
2639 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
2640 const guint8 quant[64])
2644 g_return_if_fail (out_quant != quant);
2646 for (i = 0; i < 64; i++)
2647 out_quant[uprightdiagonal_8x8[i]] = quant[i];
2652 GstH265Profile profile;
2654 guint8 max_12bit_constraint_flag;
2655 guint8 max_10bit_constraint_flag;
2656 guint8 max_8bit_constraint_flag;
2657 guint8 max_422chroma_constraint_flag;
2658 guint8 max_420chroma_constraint_flag;
2659 guint8 max_monochrome_constraint_flag;
2660 guint8 intra_constraint_flag;
2661 guint8 one_picture_only_constraint_flag;
2662 gboolean lower_bit_rate_constraint_flag_set;
2664 /* Tie breaker if more than one profiles are matching */
2666 } FormatRangeExtensionProfile;
2670 FormatRangeExtensionProfile *profile;
2671 guint extra_constraints;
2672 } FormatRangeExtensionProfileMatch;
2675 sort_fre_profile_matches (FormatRangeExtensionProfileMatch * a,
2676 FormatRangeExtensionProfileMatch * b)
2680 d = a->extra_constraints - b->extra_constraints;
2684 return b->profile->priority - a->profile->priority;
2687 static GstH265Profile
2688 get_format_range_extension_profile (GstH265ProfileTierLevel * ptl)
2690 /* See Table A.2 for the definition of those formats */
2691 FormatRangeExtensionProfile profiles[] = {
2692 {GST_H265_PROFILE_MONOCHROME, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
2693 {GST_H265_PROFILE_MONOCHROME_12, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 1},
2694 {GST_H265_PROFILE_MONOCHROME_16, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
2695 {GST_H265_PROFILE_MAIN_12, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 3},
2696 {GST_H265_PROFILE_MAIN_422_10, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 4},
2697 {GST_H265_PROFILE_MAIN_422_12, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 5},
2698 {GST_H265_PROFILE_MAIN_444, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 6},
2699 {GST_H265_PROFILE_MAIN_444_10, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 7},
2700 {GST_H265_PROFILE_MAIN_444_12, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 8},
2701 {GST_H265_PROFILE_MAIN_INTRA, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 9},
2702 {GST_H265_PROFILE_MAIN_10_INTRA, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 10},
2703 {GST_H265_PROFILE_MAIN_12_INTRA, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 11},
2704 {GST_H265_PROFILE_MAIN_422_10_INTRA, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 12},
2705 {GST_H265_PROFILE_MAIN_422_12_INTRA, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 13},
2706 {GST_H265_PROFILE_MAIN_444_INTRA, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 14},
2707 {GST_H265_PROFILE_MAIN_444_10_INTRA, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 15},
2708 {GST_H265_PROFILE_MAIN_444_12_INTRA, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 16},
2709 {GST_H265_PROFILE_MAIN_444_16_INTRA, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
2710 {GST_H265_PROFILE_MAIN_444_STILL_PICTURE, 1, 1, 1, 0, 0, 0, 1, 1, FALSE,
2712 {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE, 0, 0, 0, 0, 0, 0, 1, 1, FALSE,
2715 GstH265Profile result = GST_H265_PROFILE_INVALID;
2717 GList *matches = NULL;
2719 for (i = 0; i < G_N_ELEMENTS (profiles); i++) {
2720 FormatRangeExtensionProfile p = profiles[i];
2721 guint extra_constraints = 0;
2722 FormatRangeExtensionProfileMatch *m;
2724 /* Filter out all the profiles having constraints not satisified by @ptl.
2725 * Then pick the one having the least extra contraints. This allow us
2726 * to match the closet profile if bitstream contains not standard
2728 if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
2729 if (p.max_12bit_constraint_flag)
2731 extra_constraints++;
2734 if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
2735 if (p.max_10bit_constraint_flag)
2737 extra_constraints++;
2740 if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
2741 if (p.max_8bit_constraint_flag)
2743 extra_constraints++;
2746 if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
2747 if (p.max_422chroma_constraint_flag)
2749 extra_constraints++;
2752 if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
2753 if (p.max_420chroma_constraint_flag)
2755 extra_constraints++;
2758 if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
2759 if (p.max_monochrome_constraint_flag)
2761 extra_constraints++;
2764 if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
2765 if (p.intra_constraint_flag)
2767 extra_constraints++;
2770 if (p.one_picture_only_constraint_flag !=
2771 ptl->one_picture_only_constraint_flag) {
2772 if (p.one_picture_only_constraint_flag)
2774 extra_constraints++;
2777 if (p.lower_bit_rate_constraint_flag_set
2778 && !ptl->lower_bit_rate_constraint_flag)
2781 m = g_new0 (FormatRangeExtensionProfileMatch, 1);
2782 m->profile = &profiles[i];
2783 m->extra_constraints = extra_constraints;
2784 matches = g_list_prepend (matches, m);
2788 FormatRangeExtensionProfileMatch *m;
2790 matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
2792 result = m->profile->profile;
2793 g_list_free_full (matches, g_free);
2800 * gst_h265_profile_tier_level_get_profile:
2801 * @ptl: a #GstH265ProfileTierLevel
2803 * Return the H265 profile defined in @ptl.
2805 * Returns: a #GstH265Profile
2809 gst_h265_profile_tier_level_get_profile (GstH265ProfileTierLevel * ptl)
2811 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN
2812 || ptl->profile_compatibility_flag[1])
2813 return GST_H265_PROFILE_MAIN;
2815 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_10
2816 || ptl->profile_compatibility_flag[2])
2817 return GST_H265_PROFILE_MAIN_10;
2819 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE
2820 || ptl->profile_compatibility_flag[3])
2821 return GST_H265_PROFILE_MAIN_STILL_PICTURE;
2823 if (ptl->profile_idc == GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
2824 || ptl->profile_compatibility_flag[4])
2825 return get_format_range_extension_profile (ptl);
2828 * - GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
2829 * - GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
2832 return GST_H265_PROFILE_INVALID;