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 || nalu->size == 2)
1232 off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1234 GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1236 return GST_H265_PARSER_NO_NAL_END;
1239 /* Mini performance improvement:
1240 * We could have a way to store how many 0s were skipped to avoid
1241 * parsing them again on the next NAL */
1242 while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1247 return GST_H265_PARSER_BROKEN_DATA;
1249 GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1256 * gst_h265_parser_identify_nalu_hevc:
1257 * @parser: a #GstH265Parser
1258 * @data: The data to parse, must be the beging of the Nal unit
1259 * @offset: the offset from which to parse @data
1260 * @size: the size of @data
1261 * @nal_length_size: the size in bytes of the HEVC nal length prefix.
1262 * @nalu: The #GstH265NalUnit where to store parsed nal headers
1264 * Parses @data and sets @nalu.
1266 * Returns: a #GstH265ParserResult
1269 gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
1270 const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1271 GstH265NalUnit * nalu)
1275 memset (nalu, 0, sizeof (*nalu));
1277 if (size < offset + nal_length_size) {
1278 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1279 ", offset %u", size, offset);
1280 return GST_H265_PARSER_ERROR;
1283 size = size - offset;
1284 gst_bit_reader_init (&br, data + offset, size);
1286 nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1287 nal_length_size * 8);
1288 nalu->sc_offset = offset;
1289 nalu->offset = offset + nal_length_size;
1291 if (size < nalu->size + nal_length_size) {
1294 return GST_H265_PARSER_NO_NAL_END;
1297 nalu->data = (guint8 *) data;
1299 if (!gst_h265_parse_nalu_header (nalu)) {
1300 GST_WARNING ("error parsing \"NAL unit header\"");
1302 return GST_H265_PARSER_BROKEN_DATA;
1306 return GST_H265_PARSER_BROKEN_DATA;
1310 return GST_H265_PARSER_OK;
1314 * gst_h265_parser_parse_nal:
1315 * @parser: a #GstH265Parser
1316 * @nalu: The #GstH265NalUnit to parse
1318 * This function should be called in the case one doesn't need to
1319 * parse a specific structure. It is necessary to do so to make
1320 * sure @parser is up to date.
1322 * Returns: a #GstH265ParserResult
1325 gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
1331 switch (nalu->type) {
1332 case GST_H265_NAL_VPS:
1333 return gst_h265_parser_parse_vps (parser, nalu, &vps);
1335 case GST_H265_NAL_SPS:
1336 return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
1338 case GST_H265_NAL_PPS:
1339 return gst_h265_parser_parse_pps (parser, nalu, &pps);
1342 return GST_H265_PARSER_OK;
1346 * gst_h265_parser_parse_vps:
1347 * @parser: a #GstH265Parser
1348 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1349 * @vps: The #GstH265VPS to fill.
1351 * Parses @data, and fills the @vps structure.
1353 * Returns: a #GstH265ParserResult
1356 gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
1359 GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);
1361 if (res == GST_H265_PARSER_OK) {
1362 GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);
1364 parser->vps[vps->id] = *vps;
1365 parser->last_vps = &parser->vps[vps->id];
1372 * gst_h265_parse_vps:
1373 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1374 * @sps: The #GstH265VPS to fill.
1376 * Parses @data, and fills the @vps structure.
1378 * Returns: a #GstH265ParserResult
1381 gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
1386 INITIALIZE_DEBUG_CATEGORY;
1387 GST_DEBUG ("parsing VPS");
1389 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1390 nalu->size - nalu->header_bytes);
1392 memset (vps, 0, sizeof (*vps));
1394 vps->cprms_present_flag = 1;
1396 READ_UINT8 (&nr, vps->id, 4);
1398 /* skip reserved_three_2bits */
1399 if (!nal_reader_skip (&nr, 2))
1402 READ_UINT8 (&nr, vps->max_layers_minus1, 6);
1403 READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
1404 READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1406 /* skip reserved_0xffff_16bits */
1407 if (!nal_reader_skip (&nr, 16))
1410 if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1411 vps->max_sub_layers_minus1))
1414 READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1417 (vps->sub_layer_ordering_info_present_flag ? 0 :
1418 vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1419 READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1420 READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1421 vps->max_dec_pic_buffering_minus1[i]);
1422 READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1424 /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1425 if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1426 for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1427 vps->max_dec_pic_buffering_minus1[i] =
1428 vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1429 vps->max_num_reorder_pics[i] =
1430 vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1431 vps->max_latency_increase_plus1[i] =
1432 vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1436 READ_UINT8 (&nr, vps->max_layer_id, 6);
1437 CHECK_ALLOWED_MAX (vps->max_layer_id, 0);
1439 READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1440 CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 0);
1442 for (i = 1; i <= vps->num_layer_sets_minus1; i++)
1443 for (j = 0; j <= vps->max_layer_id; j++)
1444 nal_reader_skip (&nr, 1);
1446 READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1448 if (vps->timing_info_present_flag) {
1449 READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1450 READ_UINT32 (&nr, vps->time_scale, 32);
1451 READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1453 if (vps->poc_proportional_to_timing_flag)
1454 READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1456 READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1457 CHECK_ALLOWED_MAX (vps->num_hrd_parameters, 1);
1459 if (vps->num_hrd_parameters) {
1460 READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1461 CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, 0);
1463 if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1464 vps->cprms_present_flag, vps->max_sub_layers_minus1))
1468 READ_UINT8 (&nr, vps->vps_extension, 1);
1471 return GST_H265_PARSER_OK;
1474 GST_WARNING ("error parsing \"Video parameter set\"");
1476 return GST_H265_PARSER_ERROR;
1480 * gst_h265_parser_parse_sps:
1481 * @parser: a #GstH265Parser
1482 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1483 * @sps: The #GstH265SPS to fill.
1484 * @parse_vui_params: Whether to parse the vui_params or not
1486 * Parses @data, and fills the @sps structure.
1488 * Returns: a #GstH265ParserResult
1491 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1492 GstH265SPS * sps, gboolean parse_vui_params)
1494 GstH265ParserResult res =
1495 gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1497 if (res == GST_H265_PARSER_OK) {
1498 GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1500 parser->sps[sps->id] = *sps;
1501 parser->last_sps = &parser->sps[sps->id];
1508 * gst_h265_parse_sps:
1509 * parser: The #GstH265Parser
1510 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1511 * @sps: The #GstH265SPS to fill.
1512 * @parse_vui_params: Whether to parse the vui_params or not
1514 * Parses @data, and fills the @sps structure.
1516 * Returns: a #GstH265ParserResult
1519 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1520 GstH265SPS * sps, gboolean parse_vui_params)
1526 guint subwc[] = { 1, 2, 2, 1, 1 };
1527 guint subhc[] = { 1, 2, 1, 1, 1 };
1528 GstH265VUIParams *vui = NULL;
1530 INITIALIZE_DEBUG_CATEGORY;
1531 GST_DEBUG ("parsing SPS");
1533 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1534 nalu->size - nalu->header_bytes);
1536 memset (sps, 0, sizeof (*sps));
1538 READ_UINT8 (&nr, vps_id, 4);
1539 vps = gst_h265_parser_get_vps (parser, vps_id);
1541 GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1546 READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1547 READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1549 if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1550 sps->max_sub_layers_minus1))
1553 READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1555 READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1556 if (sps->chroma_format_idc == 3)
1557 READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1559 READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1560 READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1562 READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1563 if (sps->conformance_window_flag) {
1564 READ_UE (&nr, sps->conf_win_left_offset);
1565 READ_UE (&nr, sps->conf_win_right_offset);
1566 READ_UE (&nr, sps->conf_win_top_offset);
1567 READ_UE (&nr, sps->conf_win_bottom_offset);
1570 READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1571 READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1572 READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1574 READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1576 (sps->sub_layer_ordering_info_present_flag ? 0 :
1577 sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1578 READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1579 READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1580 sps->max_dec_pic_buffering_minus1[i]);
1581 READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1583 /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1584 if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1585 for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1586 sps->max_dec_pic_buffering_minus1[i] =
1587 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1588 sps->max_num_reorder_pics[i] =
1589 sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1590 sps->max_latency_increase_plus1[i] =
1591 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1595 /* The limits are calculted based on the profile_tier_level constraint
1596 * in Annex-A: CtbLog2SizeY = 4 to 6 */
1597 READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1598 READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1599 READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1600 READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1601 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1602 READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1604 READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1605 if (sps->scaling_list_enabled_flag) {
1606 READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1608 if (sps->scaling_list_data_present_flag)
1609 if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1613 READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1614 READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1615 READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1617 if (sps->pcm_enabled_flag) {
1618 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1619 READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1620 READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1621 READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1622 READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1625 READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1626 for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1627 if (!gst_h265_parser_parse_short_term_ref_pic_sets
1628 (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1631 READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1632 if (sps->long_term_ref_pics_present_flag) {
1633 READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1634 for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1635 READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1636 sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1637 READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1641 READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1642 READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1643 READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1645 if (sps->vui_parameters_present_flag && parse_vui_params) {
1646 if (!gst_h265_parse_vui_parameters (sps, &nr))
1648 vui = &sps->vui_params;
1651 READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1653 /* calculate ChromaArrayType */
1654 if (!sps->separate_colour_plane_flag)
1655 sps->chroma_array_type = sps->chroma_format_idc;
1657 /* Calculate width and height */
1658 sps->width = sps->pic_width_in_luma_samples;
1659 sps->height = sps->pic_height_in_luma_samples;
1660 if (sps->width < 0 || sps->height < 0) {
1661 GST_WARNING ("invalid width/height in SPS");
1665 if (sps->conformance_window_flag) {
1666 const guint crop_unit_x = subwc[sps->chroma_format_idc];
1667 const guint crop_unit_y = subhc[sps->chroma_format_idc];
1669 sps->crop_rect_width = sps->width -
1670 (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
1671 sps->crop_rect_height = sps->height -
1672 (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
1673 sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
1674 sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
1676 GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
1677 sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
1683 if (vui && vui->timing_info_present_flag) {
1684 /* derive framerate for progressive stream if the pic_struct
1685 * syntax element is not present in picture timing SEI messages */
1686 /* Fixme: handle other cases also */
1687 if (parse_vui_params && vui->timing_info_present_flag
1688 && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
1689 sps->fps_num = vui->time_scale;
1690 sps->fps_den = vui->num_units_in_tick;
1691 GST_LOG ("framerate %d/%d", sps->fps_num, sps->fps_den);
1694 GST_LOG ("No VUI, unknown framerate");
1699 return GST_H265_PARSER_OK;
1702 GST_WARNING ("error parsing \"Sequence parameter set\"");
1704 return GST_H265_PARSER_ERROR;
1708 * gst_h265_parse_pps:
1709 * @parser: a #GstH265Parser
1710 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1711 * @pps: The #GstH265PPS to fill.
1713 * Parses @data, and fills the @pps structure.
1715 * Returns: a #GstH265ParserResult
1718 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
1725 guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY;
1728 INITIALIZE_DEBUG_CATEGORY;
1729 GST_DEBUG ("parsing PPS");
1731 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1732 nalu->size - nalu->header_bytes);
1734 memset (pps, 0, sizeof (*pps));
1736 READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
1737 READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
1739 sps = gst_h265_parser_get_sps (parser, sps_id);
1741 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
1743 return GST_H265_PARSER_BROKEN_LINK;
1746 qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
1748 MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
1749 CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
1750 CtbSizeY = 1 << CtbLog2SizeY;
1751 pps->PicHeightInCtbsY =
1752 ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
1753 pps->PicWidthInCtbsY =
1754 ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
1756 /* set default values for fields that might not be present in the bitstream
1757 and have valid defaults */
1758 pps->uniform_spacing_flag = 1;
1759 pps->loop_filter_across_tiles_enabled_flag = 1;
1761 READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
1762 READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
1763 READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
1764 READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
1765 READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
1767 READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
1768 READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
1769 READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
1771 READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
1772 READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
1774 READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
1775 if (pps->cu_qp_delta_enabled_flag)
1776 READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
1777 sps->log2_diff_max_min_luma_coding_block_size);
1779 READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
1780 READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
1782 READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
1783 READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
1784 READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
1785 READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
1786 READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
1787 READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
1789 if (pps->tiles_enabled_flag) {
1790 READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 0, 19);
1791 READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 0, 21);
1793 READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
1794 /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
1795 if (pps->uniform_spacing_flag) {
1796 guint8 num_col = pps->num_tile_columns_minus1 + 1;
1797 guint8 num_row = pps->num_tile_rows_minus1 + 1;
1798 for (i = 0; i < num_col; i++) {
1799 pps->column_width_minus1[i] =
1800 ((i + 1) * pps->PicWidthInCtbsY / num_col
1801 - i * pps->PicWidthInCtbsY / num_col) - 1;
1803 for (i = 0; i < num_row; i++) {
1804 pps->row_height_minus1[i] =
1805 ((i + 1) * pps->PicHeightInCtbsY / num_row
1806 - i * pps->PicHeightInCtbsY / num_row) - 1;
1809 pps->column_width_minus1[pps->num_tile_columns_minus1] =
1810 pps->PicWidthInCtbsY - 1;
1811 for (i = 0; i < pps->num_tile_columns_minus1; i++) {
1812 READ_UE (&nr, pps->column_width_minus1[i]);
1813 pps->column_width_minus1[pps->num_tile_columns_minus1] -=
1814 (pps->column_width_minus1[i] + 1);
1817 pps->row_height_minus1[pps->num_tile_rows_minus1] =
1818 pps->PicHeightInCtbsY - 1;
1819 for (i = 0; i < pps->num_tile_rows_minus1; i++) {
1820 READ_UE (&nr, pps->row_height_minus1[i]);
1821 pps->row_height_minus1[pps->num_tile_rows_minus1] -=
1822 (pps->row_height_minus1[i] + 1);
1825 READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
1828 READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
1830 READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
1831 if (pps->deblocking_filter_control_present_flag) {
1832 READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
1834 READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
1835 if (!pps->deblocking_filter_disabled_flag) {
1836 READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
1837 READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
1841 READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
1842 if (pps->scaling_list_data_present_flag)
1843 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
1845 if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
1846 && !pps->scaling_list_data_present_flag)
1847 if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
1850 READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
1851 READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
1852 READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
1853 READ_UINT8 (&nr, pps->pps_extension_flag, 1);
1856 return GST_H265_PARSER_OK;
1859 GST_WARNING ("error parsing \"Picture parameter set\"");
1861 return GST_H265_PARSER_ERROR;
1865 * gst_h265_parser_parse_pps:
1866 * @parser: a #GstH265Parser
1867 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1868 * @pps: The #GstH265PPS to fill.
1870 * Parses @data, and fills the @pps structure.
1872 * Returns: a #GstH265ParserResult
1875 gst_h265_parser_parse_pps (GstH265Parser * parser,
1876 GstH265NalUnit * nalu, GstH265PPS * pps)
1878 GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
1879 if (res == GST_H265_PARSER_OK) {
1880 GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
1882 parser->pps[pps->id] = *pps;
1883 parser->last_pps = &parser->pps[pps->id];
1890 * gst_h265_parser_parse_slice_hdr:
1891 * @parser: a #GstH265Parser
1892 * @nalu: The #GST_H265_NAL_SLICE #GstH265NalUnit to parse
1893 * @slice: The #GstH265SliceHdr to fill.
1895 * Parses @data, and fills the @slice structure.
1896 * The resulting @slice_hdr structure shall be deallocated with
1897 * gst_h265_slice_hdr_free() when it is no longer needed
1899 * Returns: a #GstH265ParserResult
1902 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
1903 GstH265NalUnit * nalu, GstH265SliceHdr * slice)
1910 GstH265ShortTermRefPicSet *stRPS = NULL;
1911 guint32 UsedByCurrPicLt[16];
1912 guint32 PicSizeInCtbsY;
1913 gint NumPocTotalCurr = 0;
1915 memset (slice, 0, sizeof (*slice));
1918 GST_DEBUG ("Invalid Nal Unit");
1919 return GST_H265_PARSER_ERROR;
1922 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1923 nalu->size - nalu->header_bytes);
1925 GST_DEBUG ("parsing \"Slice header\", slice type");
1927 READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
1929 if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP
1930 && nalu->type <= RESERVED_IRAP_NAL_TYPE_MAX)
1931 READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
1933 READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
1934 pps = gst_h265_parser_get_pps (parser, pps_id);
1937 ("couldn't find associated picture parameter set with id: %d", pps_id);
1938 return GST_H265_PARSER_BROKEN_LINK;
1945 ("couldn't find associated sequence parameter set with id: %d",
1947 return GST_H265_PARSER_BROKEN_LINK;
1950 PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
1951 /* set default values for fields that might not be present in the bitstream
1952 * and have valid defaults */
1953 slice->pic_output_flag = 1;
1954 slice->collocated_from_l0_flag = 1;
1955 slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
1956 slice->beta_offset_div2 = pps->beta_offset_div2;
1957 slice->tc_offset_div2 = pps->tc_offset_div2;
1958 slice->loop_filter_across_slices_enabled_flag =
1959 pps->loop_filter_across_slices_enabled_flag;
1961 if (!slice->first_slice_segment_in_pic_flag) {
1962 const guint n = ceil_log2 (PicSizeInCtbsY);
1964 if (pps->dependent_slice_segments_enabled_flag)
1965 READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
1966 /* sice_segment_address parsing */
1967 READ_UINT32 (&nr, slice->segment_address, n);
1970 if (!slice->dependent_slice_segment_flag) {
1971 for (i = 0; i < pps->num_extra_slice_header_bits; i++)
1972 nal_reader_skip (&nr, 1);
1973 READ_UE_MAX (&nr, slice->type, 63);
1976 if (pps->output_flag_present_flag)
1977 READ_UINT8 (&nr, slice->pic_output_flag, 1);
1978 if (sps->separate_colour_plane_flag == 1)
1979 READ_UINT8 (&nr, slice->colour_plane_id, 2);
1981 if ((nalu->type != GST_H265_NAL_SLICE_IDR_W_RADL)
1982 && (nalu->type != GST_H265_NAL_SLICE_IDR_N_LP)) {
1983 READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
1984 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
1986 READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
1987 if (!slice->short_term_ref_pic_set_sps_flag) {
1988 if (!gst_h265_parser_parse_short_term_ref_pic_sets
1989 (&slice->short_term_ref_pic_sets, &nr,
1990 sps->num_short_term_ref_pic_sets, sps))
1992 } else if (sps->num_short_term_ref_pic_sets > 1) {
1993 const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
1994 READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
1995 CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
1996 sps->num_short_term_ref_pic_sets - 1);
1999 if (sps->long_term_ref_pics_present_flag) {
2002 if (sps->num_long_term_ref_pics_sps > 0)
2003 READ_UE_MAX (&nr, slice->num_long_term_sps,
2004 sps->num_long_term_ref_pics_sps);
2006 READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2007 limit = slice->num_long_term_sps + slice->num_long_term_pics;
2008 for (i = 0; i < limit; i++) {
2009 if (i < slice->num_long_term_sps) {
2010 if (sps->num_long_term_ref_pics_sps > 1) {
2011 const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2012 READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2015 READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2016 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2017 READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2020 /* calculate UsedByCurrPicLt */
2021 if (i < slice->num_long_term_sps)
2022 UsedByCurrPicLt[i] =
2023 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2025 UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2026 READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2027 if (slice->delta_poc_msb_present_flag[i])
2028 READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2031 if (sps->temporal_mvp_enabled_flag)
2032 READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2035 if (sps->sample_adaptive_offset_enabled_flag) {
2036 READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2037 READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2040 if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2041 READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2043 if (slice->num_ref_idx_active_override_flag) {
2044 READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2045 if (GST_H265_IS_B_SLICE (slice))
2046 READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2048 /*set default values */
2049 slice->num_ref_idx_l0_active_minus1 =
2050 pps->num_ref_idx_l0_default_active_minus1;
2051 slice->num_ref_idx_l1_active_minus1 =
2052 pps->num_ref_idx_l1_default_active_minus1;
2055 /* calculate NumPocTotalCurr */
2056 if (slice->short_term_ref_pic_set_sps_flag)
2057 stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2059 stRPS = &slice->short_term_ref_pic_sets;
2061 for (i = 0; i < stRPS->NumNegativePics; i++)
2062 if (stRPS->UsedByCurrPicS0[i])
2064 for (i = 0; i < stRPS->NumPositivePics; i++)
2065 if (stRPS->UsedByCurrPicS1[i])
2068 i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2069 if (UsedByCurrPicLt[i])
2071 slice->NumPocTotalCurr = NumPocTotalCurr;
2073 if (pps->lists_modification_present_flag) {
2074 if (NumPocTotalCurr > 1)
2075 if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2080 if (GST_H265_IS_B_SLICE (slice))
2081 READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2082 if (pps->cabac_init_present_flag)
2083 READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2084 if (slice->temporal_mvp_enabled_flag) {
2085 if (GST_H265_IS_B_SLICE (slice))
2086 READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2088 if ((slice->collocated_from_l0_flag
2089 && slice->num_ref_idx_l0_active_minus1 > 0)
2090 || (!slice->collocated_from_l0_flag
2091 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2093 /*fixme: add optimization */
2094 if ((GST_H265_IS_P_SLICE (slice))
2095 || ((GST_H265_IS_B_SLICE (slice))
2096 && (slice->collocated_from_l0_flag))) {
2097 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2098 slice->num_ref_idx_l0_active_minus1);
2099 } else if ((GST_H265_IS_B_SLICE (slice))
2100 && (!slice->collocated_from_l0_flag)) {
2101 READ_UE_MAX (&nr, slice->collocated_ref_idx,
2102 slice->num_ref_idx_l1_active_minus1);
2106 if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2107 (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2108 if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2110 READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2113 READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2114 if (pps->slice_chroma_qp_offsets_present_flag) {
2115 READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2116 READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2119 if (pps->deblocking_filter_override_enabled_flag)
2120 READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2121 if (slice->deblocking_filter_override_flag) {
2122 READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2123 if (!slice->deblocking_filter_disabled_flag) {
2124 READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2125 READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2129 if (pps->loop_filter_across_slices_enabled_flag &&
2130 (slice->sao_luma_flag || slice->sao_chroma_flag ||
2131 !slice->deblocking_filter_disabled_flag))
2132 READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2135 if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2138 if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2139 offset_max = pps->PicHeightInCtbsY - 1;
2140 else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2142 (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2146 (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2148 READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2149 if (slice->num_entry_point_offsets > 0) {
2150 READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2151 slice->entry_point_offset_minus1 =
2152 g_new0 (guint32, slice->num_entry_point_offsets);
2153 for (i = 0; i < slice->num_entry_point_offsets; i++)
2154 READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2155 (slice->offset_len_minus1 + 1));
2159 if (pps->slice_segment_header_extension_present_flag) {
2160 guint16 slice_segment_header_extension_length;
2161 READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2162 for (i = 0; i < slice_segment_header_extension_length; i++)
2163 if (!nal_reader_skip (&nr, 8))
2167 /* Skip the byte alignment bits */
2168 if (!nal_reader_skip (&nr, 1))
2170 while (!nal_reader_is_byte_aligned (&nr)) {
2171 if (!nal_reader_skip (&nr, 1))
2175 slice->header_size = nal_reader_get_pos (&nr);
2176 slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2178 return GST_H265_PARSER_OK;
2181 GST_WARNING ("error parsing \"Slice header\"");
2183 gst_h265_slice_hdr_free (slice);
2185 return GST_H265_PARSER_ERROR;
2189 nal_reader_has_more_data_in_payload (NalReader * nr,
2190 guint32 payload_start_pos_bit, guint32 payloadSize)
2192 if (nal_reader_is_byte_aligned (nr) &&
2193 (nal_reader_get_pos (nr) == (payload_start_pos_bit + 8 * payloadSize)))
2199 static GstH265ParserResult
2200 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2201 guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2203 guint32 payloadSize;
2204 guint8 payload_type_byte, payload_size_byte;
2205 guint remaining, payload_size;
2206 guint32 payload_start_pos_bit;
2207 GstH265ParserResult res = GST_H265_PARSER_OK;
2209 GST_DEBUG ("parsing \"Sei message\"");
2211 memset (sei, 0, sizeof (*sei));
2214 READ_UINT8 (nr, payload_type_byte, 8);
2215 sei->payloadType += payload_type_byte;
2216 } while (payload_type_byte == 0xff);
2219 READ_UINT8 (nr, payload_size_byte, 8);
2220 payloadSize += payload_size_byte;
2222 while (payload_size_byte == 0xff);
2224 remaining = nal_reader_get_remaining (nr);
2225 payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
2227 payload_start_pos_bit = nal_reader_get_pos (nr);
2229 ("SEI message received: payloadType %u, payloadSize = %u bytes",
2230 sei->payloadType, payload_size);
2232 if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2233 switch (sei->payloadType) {
2234 case GST_H265_SEI_BUF_PERIOD:
2235 /* size not set; might depend on emulation_prevention_three_byte */
2236 res = gst_h265_parser_parse_buffering_period (parser,
2237 &sei->payload.buffering_period, nr);
2239 case GST_H265_SEI_PIC_TIMING:
2240 /* size not set; might depend on emulation_prevention_three_byte */
2241 res = gst_h265_parser_parse_pic_timing (parser,
2242 &sei->payload.pic_timing, nr);
2245 /* Just consume payloadSize bytes, which does not account for
2246 emulation prevention bytes */
2247 if (!nal_reader_skip_long (nr, payload_size))
2249 res = GST_H265_PARSER_OK;
2252 } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2253 switch (sei->payloadType) {
2255 /* Just consume payloadSize bytes, which does not account for
2256 emulation prevention bytes */
2257 if (!nal_reader_skip_long (nr, payload_size))
2259 res = GST_H265_PARSER_OK;
2264 /* Not parsing the reserved_payload_extension, but it shouldn't be
2265 * an issue because of 1: There shall not be any reserved_payload_extension
2266 * present in bitstreams conforming to the specification.2. Even though
2267 * it is present, the size will be less than total PayloadSize since the
2268 * size of reserved_payload_extension is supposed to be
2269 * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2270 * the current implementation will still skip all unnecessary bits correctly.
2271 * In theory, we can have a more optimized implementation by skipping the
2272 * data left in PayLoadSize without out individually checking for each bits,
2273 * since the totoal size will be always less than payloadSize*/
2274 if (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
2276 /* Skip the byte alignment bits */
2277 if (!nal_reader_skip (nr, 1))
2279 while (!nal_reader_is_byte_aligned (nr)) {
2280 if (!nal_reader_skip (nr, 1))
2288 GST_WARNING ("error parsing \"Sei message\"");
2289 return GST_H265_PARSER_ERROR;
2293 * gst_h265_slice_hdr_copy:
2294 * @dst_slice: The destination #GstH265SliceHdr to copy into
2295 * @src_slice: The source #GstH265SliceHdr to copy from
2297 * Copies @src_slice into @dst_slice
2299 * Returns: %TRUE if everything went fine, %FALSE otherwise
2302 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2303 const GstH265SliceHdr * src_slice)
2307 g_return_val_if_fail (dst_slice != NULL, FALSE);
2308 g_return_val_if_fail (src_slice != NULL, FALSE);
2310 gst_h265_slice_hdr_free (dst_slice);
2312 *dst_slice = *src_slice;
2314 if (dst_slice->num_entry_point_offsets > 0) {
2315 dst_slice->entry_point_offset_minus1 =
2316 g_new0 (guint32, dst_slice->num_entry_point_offsets);
2317 for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2318 dst_slice->entry_point_offset_minus1[i] =
2319 src_slice->entry_point_offset_minus1[i];
2326 * gst_h265_slice_hdr_free:
2327 * slice_hdr: The #GstH265SliceHdr to free
2329 * Frees @slice_hdr fields.
2332 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2334 g_return_if_fail (slice_hdr != NULL);
2336 if (slice_hdr->num_entry_point_offsets > 0)
2337 g_free (slice_hdr->entry_point_offset_minus1);
2338 slice_hdr->entry_point_offset_minus1 = 0;
2342 * gst_h265_sei_copy:
2343 * @dst_sei: The destination #GstH265SEIMessage to copy into
2344 * @src_sei: The source #GstH265SEIMessage to copy from
2346 * Copies @src_sei into @dst_sei
2348 * Returns: %TRUE if everything went fine, %FALSE otherwise
2351 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2352 const GstH265SEIMessage * src_sei)
2356 g_return_val_if_fail (dst_sei != NULL, FALSE);
2357 g_return_val_if_fail (src_sei != NULL, FALSE);
2359 gst_h265_sei_free (dst_sei);
2361 *dst_sei = *src_sei;
2363 if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2364 GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2365 const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2367 if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2368 dst_pic_timing->num_nalus_in_du_minus1 =
2369 g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2370 dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2371 g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2373 for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2374 dst_pic_timing->num_nalus_in_du_minus1[i] =
2375 src_pic_timing->num_nalus_in_du_minus1[i];
2376 dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2377 src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2386 * gst_h265_sei_free:
2387 * sei: The #GstH265SEIMessage to free
2389 * Frees @sei fields.
2392 gst_h265_sei_free (GstH265SEIMessage * sei)
2394 g_return_if_fail (sei != NULL);
2396 if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2397 GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2398 if (pic_timing->num_decoding_units_minus1 > 0) {
2399 g_free (pic_timing->num_nalus_in_du_minus1);
2400 g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2402 pic_timing->num_nalus_in_du_minus1 = 0;
2403 pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2408 * gst_h265_parser_parse_sei:
2409 * @nalparser: a #GstH265Parser
2410 * @nalu: The #GST_H265_NAL_SEI #GstH265NalUnit to parse
2411 * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2413 * Parses @data, create and fills the @messages array.
2415 * Returns: a #GstH265ParserResult
2418 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2422 GstH265SEIMessage sei;
2423 GstH265ParserResult res;
2425 GST_DEBUG ("parsing SEI nal");
2426 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2427 nalu->size - nalu->header_bytes);
2428 *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
2429 g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
2432 res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
2433 if (res == GST_H265_PARSER_OK)
2434 g_array_append_val (*messages, sei);
2437 } while (nal_reader_has_more_data (&nr));
2444 * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
2445 * @out_quant: (out): The resulting quantization matrix
2446 * @quant: The source quantization matrix
2448 * Converts quantization matrix @quant from raster scan order to
2449 * zigzag scan order and store the resulting factors into @out_quant.
2451 * Note: it is an error to pass the same table in both @quant and
2452 * @out_quant arguments.
2457 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
2458 const guint8 quant[16])
2462 g_return_if_fail (out_quant != quant);
2464 for (i = 0; i < 16; i++)
2465 out_quant[i] = quant[zigzag_4x4[i]];
2469 * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
2470 * @out_quant: (out): The resulting quantization matrix
2471 * @quant: The source quantization matrix
2473 * Converts quantization matrix @quant from zigzag scan order to
2474 * raster scan order and store the resulting factors into @out_quant.
2476 * Note: it is an error to pass the same table in both @quant and
2477 * @out_quant arguments.
2482 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
2483 const guint8 quant[16])
2487 g_return_if_fail (out_quant != quant);
2489 for (i = 0; i < 16; i++)
2490 out_quant[zigzag_4x4[i]] = quant[i];
2494 * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
2495 * @out_quant: (out): The resulting quantization matrix
2496 * @quant: The source quantization matrix
2498 * Converts quantization matrix @quant from raster scan order to
2499 * zigzag scan order and store the resulting factors into @out_quant.
2501 * Note: it is an error to pass the same table in both @quant and
2502 * @out_quant arguments.
2507 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
2508 const guint8 quant[64])
2512 g_return_if_fail (out_quant != quant);
2514 for (i = 0; i < 64; i++)
2515 out_quant[i] = quant[zigzag_8x8[i]];
2519 * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
2520 * @out_quant: (out): The resulting quantization matrix
2521 * @quant: The source quantization matrix
2523 * Converts quantization matrix @quant from zigzag scan order to
2524 * raster scan order and store the resulting factors into @out_quant.
2526 * Note: it is an error to pass the same table in both @quant and
2527 * @out_quant arguments.
2532 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
2533 const guint8 quant[64])
2537 g_return_if_fail (out_quant != quant);
2539 for (i = 0; i < 64; i++)
2540 out_quant[zigzag_8x8[i]] = quant[i];
2544 * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
2545 * @out_quant: (out): The resulting quantization matrix
2546 * @quant: The source quantization matrix
2548 * Converts quantization matrix @quant from raster scan order to
2549 * uprightdiagonal scan order and store the resulting factors
2552 * Note: it is an error to pass the same table in both @quant and
2553 * @out_quant arguments.
2558 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
2559 const guint8 quant[16])
2563 g_return_if_fail (out_quant != quant);
2565 for (i = 0; i < 16; i++)
2566 out_quant[i] = quant[uprightdiagonal_4x4[i]];
2570 * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
2571 * @out_quant: (out): The resulting quantization matrix
2572 * @quant: The source quantization matrix
2574 * Converts quantization matrix @quant from uprightdiagonal scan order to
2575 * raster scan order and store the resulting factors into @out_quant.
2577 * Note: it is an error to pass the same table in both @quant and
2578 * @out_quant arguments.
2583 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
2584 const guint8 quant[16])
2588 g_return_if_fail (out_quant != quant);
2590 for (i = 0; i < 16; i++)
2591 out_quant[uprightdiagonal_4x4[i]] = quant[i];
2595 * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
2596 * @out_quant: (out): The resulting quantization matrix
2597 * @quant: The source quantization matrix
2599 * Converts quantization matrix @quant from raster scan order to
2600 * uprightdiagonal scan order and store the resulting factors
2603 * Note: it is an error to pass the same table in both @quant and
2604 * @out_quant arguments.
2609 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
2610 const guint8 quant[64])
2614 g_return_if_fail (out_quant != quant);
2616 for (i = 0; i < 64; i++)
2617 out_quant[i] = quant[uprightdiagonal_8x8[i]];
2621 * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
2622 * @out_quant: (out): The resulting quantization matrix
2623 * @quant: The source quantization matrix
2625 * Converts quantization matrix @quant from uprightdiagonal scan order to
2626 * raster scan order and store the resulting factors into @out_quant.
2628 * Note: it is an error to pass the same table in both @quant and
2629 * @out_quant arguments.
2634 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
2635 const guint8 quant[64])
2639 g_return_if_fail (out_quant != quant);
2641 for (i = 0; i < 64; i++)
2642 out_quant[uprightdiagonal_8x8[i]] = quant[i];
2647 GstH265Profile profile;
2649 guint8 max_12bit_constraint_flag;
2650 guint8 max_10bit_constraint_flag;
2651 guint8 max_8bit_constraint_flag;
2652 guint8 max_422chroma_constraint_flag;
2653 guint8 max_420chroma_constraint_flag;
2654 guint8 max_monochrome_constraint_flag;
2655 guint8 intra_constraint_flag;
2656 guint8 one_picture_only_constraint_flag;
2657 gboolean lower_bit_rate_constraint_flag_set;
2659 /* Tie breaker if more than one profiles are matching */
2661 } FormatRangeExtensionProfile;
2665 FormatRangeExtensionProfile *profile;
2666 guint extra_constraints;
2667 } FormatRangeExtensionProfileMatch;
2670 sort_fre_profile_matches (FormatRangeExtensionProfileMatch * a,
2671 FormatRangeExtensionProfileMatch * b)
2675 d = a->extra_constraints - b->extra_constraints;
2679 return b->profile->priority - a->profile->priority;
2682 static GstH265Profile
2683 get_format_range_extension_profile (GstH265ProfileTierLevel * ptl)
2685 /* See Table A.2 for the definition of those formats */
2686 FormatRangeExtensionProfile profiles[] = {
2687 {GST_H265_PROFILE_MONOCHROME, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
2688 {GST_H265_PROFILE_MONOCHROME_12, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 1},
2689 {GST_H265_PROFILE_MONOCHROME_16, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
2690 {GST_H265_PROFILE_MAIN_12, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 3},
2691 {GST_H265_PROFILE_MAIN_422_10, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 4},
2692 {GST_H265_PROFILE_MAIN_422_12, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 5},
2693 {GST_H265_PROFILE_MAIN_444, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 6},
2694 {GST_H265_PROFILE_MAIN_444_10, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 7},
2695 {GST_H265_PROFILE_MAIN_444_12, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 8},
2696 {GST_H265_PROFILE_MAIN_INTRA, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 9},
2697 {GST_H265_PROFILE_MAIN_10_INTRA, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 10},
2698 {GST_H265_PROFILE_MAIN_12_INTRA, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 11},
2699 {GST_H265_PROFILE_MAIN_422_10_INTRA, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 12},
2700 {GST_H265_PROFILE_MAIN_422_12_INTRA, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 13},
2701 {GST_H265_PROFILE_MAIN_444_INTRA, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 14},
2702 {GST_H265_PROFILE_MAIN_444_10_INTRA, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 15},
2703 {GST_H265_PROFILE_MAIN_444_12_INTRA, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 16},
2704 {GST_H265_PROFILE_MAIN_444_16_INTRA, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
2705 {GST_H265_PROFILE_MAIN_444_STILL_PICTURE, 1, 1, 1, 0, 0, 0, 1, 1, FALSE,
2707 {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE, 0, 0, 0, 0, 0, 0, 1, 1, FALSE,
2710 GstH265Profile result = GST_H265_PROFILE_INVALID;
2712 GList *matches = NULL;
2714 for (i = 0; i < G_N_ELEMENTS (profiles); i++) {
2715 FormatRangeExtensionProfile p = profiles[i];
2716 guint extra_constraints = 0;
2717 FormatRangeExtensionProfileMatch *m;
2719 /* Filter out all the profiles having constraints not satisified by @ptl.
2720 * Then pick the one having the least extra contraints. This allow us
2721 * to match the closet profile if bitstream contains not standard
2723 if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
2724 if (p.max_12bit_constraint_flag)
2726 extra_constraints++;
2729 if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
2730 if (p.max_10bit_constraint_flag)
2732 extra_constraints++;
2735 if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
2736 if (p.max_8bit_constraint_flag)
2738 extra_constraints++;
2741 if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
2742 if (p.max_422chroma_constraint_flag)
2744 extra_constraints++;
2747 if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
2748 if (p.max_420chroma_constraint_flag)
2750 extra_constraints++;
2753 if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
2754 if (p.max_monochrome_constraint_flag)
2756 extra_constraints++;
2759 if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
2760 if (p.intra_constraint_flag)
2762 extra_constraints++;
2765 if (p.one_picture_only_constraint_flag !=
2766 ptl->one_picture_only_constraint_flag) {
2767 if (p.one_picture_only_constraint_flag)
2769 extra_constraints++;
2772 if (p.lower_bit_rate_constraint_flag_set
2773 && !ptl->lower_bit_rate_constraint_flag)
2776 m = g_new0 (FormatRangeExtensionProfileMatch, 1);
2777 m->profile = &profiles[i];
2778 m->extra_constraints = extra_constraints;
2779 matches = g_list_prepend (matches, m);
2783 FormatRangeExtensionProfileMatch *m;
2785 matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
2787 result = m->profile->profile;
2788 g_list_free_full (matches, g_free);
2795 * gst_h265_profile_tier_level_get_profile:
2796 * @ptl: a #GstH265ProfileTierLevel
2798 * Return the H265 profile defined in @ptl.
2800 * Returns: a #GstH265Profile
2804 gst_h265_profile_tier_level_get_profile (GstH265ProfileTierLevel * ptl)
2806 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN
2807 || ptl->profile_compatibility_flag[1])
2808 return GST_H265_PROFILE_MAIN;
2810 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_10
2811 || ptl->profile_compatibility_flag[2])
2812 return GST_H265_PROFILE_MAIN_10;
2814 if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE
2815 || ptl->profile_compatibility_flag[3])
2816 return GST_H265_PROFILE_MAIN_STILL_PICTURE;
2818 if (ptl->profile_idc == GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
2819 || ptl->profile_compatibility_flag[4])
2820 return get_format_range_extension_profile (ptl);
2823 * - GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
2824 * - GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
2827 return GST_H265_PROFILE_INVALID;