documentation: fixed a heap o' typos
[platform/upstream/gstreamer.git] / gst-libs / gst / codecparsers / gsth265parser.c
1 /* Gstreamer H.265 bitstream parser
2  * Copyright (C) 2012 Intel Corporation
3  * Copyright (C) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
4  *
5  *  Contact: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 /**
24  * SECTION:gsth265parser
25  * @title: GstH265Parser
26  * @short_description: Convenience library for h265 video bitstream parsing.
27  *
28  * It offers you bitstream parsing in HEVC mode and non-HEVC mode. To identify
29  * Nals in a bitstream and parse its headers, you should call:
30  *
31  *   * gst_h265_parser_identify_nalu() to identify the following nalu in
32  *        non-HEVC bitstreams
33  *
34  *   * gst_h265_parser_identify_nalu_hevc() to identify the nalu in
35  *        HEVC bitstreams
36  *
37  * Then, depending on the #GstH265NalUnitType of the newly parsed #GstH265NalUnit,
38  * you should call the differents functions to parse the structure:
39  *
40  *   * From #GST_H265_NAL_SLICE_TRAIL_N to #GST_H265_NAL_SLICE_CRA_NUT: gst_h265_parser_parse_slice_hdr()
41  *
42  *   * `GST_H265_NAL_*_SEI`: gst_h265_parser_parse_sei()
43  *
44  *   * #GST_H265_NAL_VPS: gst_h265_parser_parse_vps()
45  *
46  *   * #GST_H265_NAL_SPS: gst_h265_parser_parse_sps()
47  *
48  *   * #GST_H265_NAL_PPS: #gst_h265_parser_parse_pps()
49  *
50  *   * Any other: gst_h265_parser_parse_nal()
51  *
52  * Note: You should always call gst_h265_parser_parse_nal() if you don't
53  * actually need #GstH265NalUnitType to be parsed for your personal use, in
54  * order to guarantee that the #GstH265Parser is always up to date.
55  *
56  * For more details about the structures, look at the ITU-T H.265
57  * specifications, you can download them from:
58  *
59  *   * ITU-T H.265: http://www.itu.int/rec/T-REC-H.265
60  *
61  */
62
63 #ifdef HAVE_CONFIG_H
64 #  include "config.h"
65 #endif
66
67 #include "nalutils.h"
68 #include "gsth265parser.h"
69
70 #include <gst/base/gstbytereader.h>
71 #include <gst/base/gstbitreader.h>
72 #include <string.h>
73 #include <math.h>
74
75 #ifndef GST_DISABLE_GST_DEBUG
76 #define GST_CAT_DEFAULT gst_h265_debug_category_get()
77 static GstDebugCategory *
78 gst_h265_debug_category_get (void)
79 {
80   static gsize cat_gonce = 0;
81
82   if (g_once_init_enter (&cat_gonce)) {
83     GstDebugCategory *cat = NULL;
84
85     GST_DEBUG_CATEGORY_INIT (cat, "codecparsers_h265", 0, "h265 parse library");
86
87     g_once_init_leave (&cat_gonce, (gsize) cat);
88   }
89
90   return (GstDebugCategory *) cat_gonce;
91 }
92 #endif /* GST_DISABLE_GST_DEBUG */
93
94 /**** Default scaling_lists according to Table 7-5 and 7-6 *****/
95
96 /* Table 7-5 */
97 static const guint8 default_scaling_list0[16] = {
98   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
99   16, 16, 16, 16
100 };
101
102 /*  Combined the values in Table  7-6 to make the calculation easier
103  *  Default scaling list of 8x8 and 16x16 matrices for matrixId = 0, 1 and 2
104  *  Default scaling list of 32x32 matrix for matrixId = 0
105  */
106 static const guint8 default_scaling_list1[64] = {
107   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16,
108   17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20,
109   21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24,
110   25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31,
111   29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70,
112   65, 88, 88, 115
113 };
114
115 /*  Combined the values in Table 7-6 to make the calculation easier
116  *  Default scaling list of 8x8 and 16x16 matrices for matrixId = 3, 4 and 5
117  *  Default scaling list of 32x32 matrix for matrixId = 1
118  */
119 static const guint8 default_scaling_list2[64] = {
120   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
121   17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20,
122   20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24,
123   25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28,
124   28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54,
125   54, 71, 71, 91
126 };
127
128 static const guint8 zigzag_4x4[16] = {
129   0, 1, 4, 8,
130   5, 2, 3, 6,
131   9, 12, 13, 10,
132   7, 11, 14, 15,
133 };
134
135 static const guint8 zigzag_8x8[64] = {
136   0, 1, 8, 16, 9, 2, 3, 10,
137   17, 24, 32, 25, 18, 11, 4, 5,
138   12, 19, 26, 33, 40, 48, 41, 34,
139   27, 20, 13, 6, 7, 14, 21, 28,
140   35, 42, 49, 56, 57, 50, 43, 36,
141   29, 22, 15, 23, 30, 37, 44, 51,
142   58, 59, 52, 45, 38, 31, 39, 46,
143   53, 60, 61, 54, 47, 55, 62, 63
144 };
145
146 static const guint8 uprightdiagonal_4x4[16] = {
147   0, 4, 1, 8,
148   5, 2, 12, 9,
149   6, 3, 13, 10,
150   7, 14, 11, 15
151 };
152
153 static const guint8 uprightdiagonal_8x8[64] = {
154   0, 8, 1, 16, 9, 2, 24, 17,
155   10, 3, 32, 25, 18, 11, 4, 40,
156   33, 26, 19, 12, 5, 48, 41, 34,
157   27, 20, 13, 6, 56, 49, 42, 35,
158   28, 21, 14, 7, 57, 50, 43, 36,
159   29, 22, 15, 58, 51, 44, 37, 30,
160   23, 59, 52, 45, 38, 31, 60, 53,
161   46, 39, 61, 54, 47, 62, 55, 63
162 };
163
164 typedef struct
165 {
166   guint par_n, par_d;
167 } PAR;
168
169 /* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
170 static const PAR aspect_ratios[17] = {
171   {0, 0},
172   {1, 1},
173   {12, 11},
174   {10, 11},
175   {16, 11},
176   {40, 33},
177   {24, 11},
178   {20, 11},
179   {32, 11},
180   {80, 33},
181   {18, 11},
182   {15, 11},
183   {64, 33},
184   {160, 99},
185   {4, 3},
186   {3, 2},
187   {2, 1}
188 };
189
190 /*****  Utils ****/
191 #define EXTENDED_SAR 255
192
193 static GstH265VPS *
194 gst_h265_parser_get_vps (GstH265Parser * parser, guint8 vps_id)
195 {
196   GstH265VPS *vps;
197
198   vps = &parser->vps[vps_id];
199
200   if (vps->valid)
201     return vps;
202
203   return NULL;
204 }
205
206 static GstH265SPS *
207 gst_h265_parser_get_sps (GstH265Parser * parser, guint8 sps_id)
208 {
209   GstH265SPS *sps;
210
211   sps = &parser->sps[sps_id];
212
213   if (sps->valid)
214     return sps;
215
216   return NULL;
217 }
218
219 static GstH265PPS *
220 gst_h265_parser_get_pps (GstH265Parser * parser, guint8 pps_id)
221 {
222   GstH265PPS *pps;
223
224   pps = &parser->pps[pps_id];
225
226   if (pps->valid)
227     return pps;
228
229   return NULL;
230 }
231
232 static gboolean
233 gst_h265_parse_nalu_header (GstH265NalUnit * nalu)
234 {
235   guint8 *data = nalu->data + nalu->offset;
236   GstBitReader br;
237
238   if (nalu->size < 2)
239     return FALSE;
240
241   gst_bit_reader_init (&br, data, nalu->size - nalu->offset);
242
243   /* skip the forbidden_zero_bit */
244   gst_bit_reader_skip_unchecked (&br, 1);
245
246   nalu->type = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
247   nalu->layer_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
248   nalu->temporal_id_plus1 = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
249   nalu->header_bytes = 2;
250
251   return TRUE;
252 }
253
254 /****** Parsing functions *****/
255
256 static gboolean
257 gst_h265_parse_profile_tier_level (GstH265ProfileTierLevel * ptl,
258     NalReader * nr, guint8 maxNumSubLayersMinus1)
259 {
260   guint i, j;
261   GST_DEBUG ("parsing \"ProfileTierLevel parameters\"");
262
263   READ_UINT8 (nr, ptl->profile_space, 2);
264   READ_UINT8 (nr, ptl->tier_flag, 1);
265   READ_UINT8 (nr, ptl->profile_idc, 5);
266
267   for (j = 0; j < 32; j++)
268     READ_UINT8 (nr, ptl->profile_compatibility_flag[j], 1);
269
270   READ_UINT8 (nr, ptl->progressive_source_flag, 1);
271   READ_UINT8 (nr, ptl->interlaced_source_flag, 1);
272   READ_UINT8 (nr, ptl->non_packed_constraint_flag, 1);
273   READ_UINT8 (nr, ptl->frame_only_constraint_flag, 1);
274
275   READ_UINT8 (nr, ptl->max_12bit_constraint_flag, 1);
276   READ_UINT8 (nr, ptl->max_10bit_constraint_flag, 1);
277   READ_UINT8 (nr, ptl->max_8bit_constraint_flag, 1);
278   READ_UINT8 (nr, ptl->max_422chroma_constraint_flag, 1);
279   READ_UINT8 (nr, ptl->max_420chroma_constraint_flag, 1);
280   READ_UINT8 (nr, ptl->max_monochrome_constraint_flag, 1);
281   READ_UINT8 (nr, ptl->intra_constraint_flag, 1);
282   READ_UINT8 (nr, ptl->one_picture_only_constraint_flag, 1);
283   READ_UINT8 (nr, ptl->lower_bit_rate_constraint_flag, 1);
284   READ_UINT8 (nr, ptl->max_14bit_constraint_flag, 1);
285
286   /* skip the reserved zero bits */
287   if (!nal_reader_skip (nr, 34))
288     goto error;
289
290   READ_UINT8 (nr, ptl->level_idc, 8);
291   for (j = 0; j < maxNumSubLayersMinus1; j++) {
292     READ_UINT8 (nr, ptl->sub_layer_profile_present_flag[j], 1);
293     READ_UINT8 (nr, ptl->sub_layer_level_present_flag[j], 1);
294   }
295
296   if (maxNumSubLayersMinus1 > 0) {
297     for (i = maxNumSubLayersMinus1; i < 8; i++)
298       if (!nal_reader_skip (nr, 2))
299         goto error;
300   }
301
302   for (i = 0; i < maxNumSubLayersMinus1; i++) {
303     if (ptl->sub_layer_profile_present_flag[i]) {
304       READ_UINT8 (nr, ptl->sub_layer_profile_space[i], 2);
305       READ_UINT8 (nr, ptl->sub_layer_tier_flag[i], 1);
306       READ_UINT8 (nr, ptl->sub_layer_profile_idc[i], 5);
307
308       for (j = 0; j < 32; j++)
309         READ_UINT8 (nr, ptl->sub_layer_profile_compatibility_flag[i][j], 1);
310
311       READ_UINT8 (nr, ptl->sub_layer_progressive_source_flag[i], 1);
312       READ_UINT8 (nr, ptl->sub_layer_interlaced_source_flag[i], 1);
313       READ_UINT8 (nr, ptl->sub_layer_non_packed_constraint_flag[i], 1);
314       READ_UINT8 (nr, ptl->sub_layer_frame_only_constraint_flag[i], 1);
315
316       if (!nal_reader_skip (nr, 44))
317         goto error;
318     }
319
320     if (ptl->sub_layer_level_present_flag[i])
321       READ_UINT8 (nr, ptl->sub_layer_level_idc[i], 8);
322   }
323
324   return TRUE;
325
326 error:
327   GST_WARNING ("error parsing \"ProfileTierLevel Parameters\"");
328   return FALSE;
329 }
330
331 static gboolean
332 gst_h265_parse_sub_layer_hrd_parameters (GstH265SubLayerHRDParams * sub_hrd,
333     NalReader * nr, guint8 CpbCnt, guint8 sub_pic_hrd_params_present_flag)
334 {
335   guint i;
336
337   GST_DEBUG ("parsing \"SubLayer HRD Parameters\"");
338
339   for (i = 0; i <= CpbCnt; i++) {
340     READ_UE_MAX (nr, sub_hrd->bit_rate_value_minus1[i], G_MAXUINT32 - 1);
341     READ_UE_MAX (nr, sub_hrd->cpb_size_value_minus1[i], G_MAXUINT32 - 1);
342
343     if (sub_pic_hrd_params_present_flag) {
344       READ_UE_MAX (nr, sub_hrd->cpb_size_du_value_minus1[i], G_MAXUINT32 - 1);
345       READ_UE_MAX (nr, sub_hrd->bit_rate_du_value_minus1[i], G_MAXUINT32 - 1);
346     }
347
348     READ_UINT8 (nr, sub_hrd->cbr_flag[i], 1);
349   }
350
351   return TRUE;
352
353 error:
354   GST_WARNING ("error parsing \"SubLayerHRD Parameters \"");
355   return FALSE;
356 }
357
358 static gboolean
359 gst_h265_parse_hrd_parameters (GstH265HRDParams * hrd, NalReader * nr,
360     guint8 commonInfPresentFlag, guint8 maxNumSubLayersMinus1)
361 {
362   guint i;
363
364   GST_DEBUG ("parsing \"HRD Parameters\"");
365
366   /* set default values for fields that might not be present in the bitstream
367      and have valid defaults */
368   hrd->initial_cpb_removal_delay_length_minus1 = 23;
369   hrd->au_cpb_removal_delay_length_minus1 = 23;
370   hrd->dpb_output_delay_length_minus1 = 23;
371
372   if (commonInfPresentFlag) {
373     READ_UINT8 (nr, hrd->nal_hrd_parameters_present_flag, 1);
374     READ_UINT8 (nr, hrd->vcl_hrd_parameters_present_flag, 1);
375
376     if (hrd->nal_hrd_parameters_present_flag
377         || hrd->vcl_hrd_parameters_present_flag) {
378
379       READ_UINT8 (nr, hrd->sub_pic_hrd_params_present_flag, 1);
380
381       if (hrd->sub_pic_hrd_params_present_flag) {
382         READ_UINT8 (nr, hrd->tick_divisor_minus2, 8);
383         READ_UINT8 (nr, hrd->du_cpb_removal_delay_increment_length_minus1, 5);
384         READ_UINT8 (nr, hrd->sub_pic_cpb_params_in_pic_timing_sei_flag, 1);
385         READ_UINT8 (nr, hrd->dpb_output_delay_du_length_minus1, 5);
386       }
387
388       READ_UINT8 (nr, hrd->bit_rate_scale, 4);
389       READ_UINT8 (nr, hrd->cpb_size_scale, 4);
390
391       if (hrd->sub_pic_hrd_params_present_flag)
392         READ_UINT8 (nr, hrd->cpb_size_du_scale, 4);
393
394       READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
395       READ_UINT8 (nr, hrd->au_cpb_removal_delay_length_minus1, 5);
396       READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
397     }
398   }
399
400   for (i = 0; i <= maxNumSubLayersMinus1; i++) {
401     READ_UINT8 (nr, hrd->fixed_pic_rate_general_flag[i], 1);
402
403     if (!hrd->fixed_pic_rate_general_flag[i]) {
404       READ_UINT8 (nr, hrd->fixed_pic_rate_within_cvs_flag[i], 1);
405     } else
406       hrd->fixed_pic_rate_within_cvs_flag[i] = 1;
407
408     if (hrd->fixed_pic_rate_within_cvs_flag[i]) {
409       READ_UE_MAX (nr, hrd->elemental_duration_in_tc_minus1[i], 2047);
410     } else
411       READ_UINT8 (nr, hrd->low_delay_hrd_flag[i], 1);
412
413     if (!hrd->low_delay_hrd_flag[i])
414       READ_UE_MAX (nr, hrd->cpb_cnt_minus1[i], 31);
415
416     if (hrd->nal_hrd_parameters_present_flag)
417       if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
418               [i], nr, hrd->cpb_cnt_minus1[i],
419               hrd->sub_pic_hrd_params_present_flag))
420         goto error;
421
422     if (hrd->vcl_hrd_parameters_present_flag)
423       if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
424               [i], nr, hrd->cpb_cnt_minus1[i],
425               hrd->sub_pic_hrd_params_present_flag))
426         goto error;
427   }
428
429   return TRUE;
430
431 error:
432   GST_WARNING ("error parsing \"HRD Parameters\"");
433   return FALSE;
434 }
435
436 static gboolean
437 gst_h265_parse_vui_parameters (GstH265SPS * sps, NalReader * nr)
438 {
439   GstH265VUIParams *vui = &sps->vui_params;
440
441   GST_DEBUG ("parsing \"VUI Parameters\"");
442
443   /* set default values for fields that might not be present in the bitstream
444      and have valid defaults */
445   vui->video_format = 5;
446   vui->colour_primaries = 2;
447   vui->transfer_characteristics = 2;
448   vui->matrix_coefficients = 2;
449   vui->motion_vectors_over_pic_boundaries_flag = 1;
450   vui->max_bytes_per_pic_denom = 2;
451   vui->max_bits_per_min_cu_denom = 1;
452   vui->log2_max_mv_length_horizontal = 15;
453   vui->log2_max_mv_length_vertical = 15;
454
455   if (sps && sps->profile_tier_level.progressive_source_flag
456       && sps->profile_tier_level.interlaced_source_flag)
457     vui->frame_field_info_present_flag = 1;
458
459   READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
460   if (vui->aspect_ratio_info_present_flag) {
461     READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
462     if (vui->aspect_ratio_idc == EXTENDED_SAR) {
463       READ_UINT16 (nr, vui->sar_width, 16);
464       READ_UINT16 (nr, vui->sar_height, 16);
465       vui->par_n = vui->sar_width;
466       vui->par_d = vui->sar_height;
467     } else if (vui->aspect_ratio_idc <= 16) {
468       vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
469       vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
470     }
471   }
472
473   READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
474   if (vui->overscan_info_present_flag)
475     READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);
476
477   READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
478   if (vui->video_signal_type_present_flag) {
479
480     READ_UINT8 (nr, vui->video_format, 3);
481     READ_UINT8 (nr, vui->video_full_range_flag, 1);
482     READ_UINT8 (nr, vui->colour_description_present_flag, 1);
483     if (vui->colour_description_present_flag) {
484       READ_UINT8 (nr, vui->colour_primaries, 8);
485       READ_UINT8 (nr, vui->transfer_characteristics, 8);
486       READ_UINT8 (nr, vui->matrix_coefficients, 8);
487     }
488   }
489
490   READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
491   if (vui->chroma_loc_info_present_flag) {
492     READ_UE_MAX (nr, vui->chroma_sample_loc_type_top_field, 5);
493     READ_UE_MAX (nr, vui->chroma_sample_loc_type_bottom_field, 5);
494   }
495
496   READ_UINT8 (nr, vui->neutral_chroma_indication_flag, 1);
497   READ_UINT8 (nr, vui->field_seq_flag, 1);
498   READ_UINT8 (nr, vui->frame_field_info_present_flag, 1);
499
500   READ_UINT8 (nr, vui->default_display_window_flag, 1);
501   if (vui->default_display_window_flag) {
502     READ_UE (nr, vui->def_disp_win_left_offset);
503     READ_UE (nr, vui->def_disp_win_right_offset);
504     READ_UE (nr, vui->def_disp_win_top_offset);
505     READ_UE (nr, vui->def_disp_win_bottom_offset);
506   }
507
508   READ_UINT8 (nr, vui->timing_info_present_flag, 1);
509   if (vui->timing_info_present_flag) {
510     READ_UINT32 (nr, vui->num_units_in_tick, 32);
511     if (vui->num_units_in_tick == 0)
512       GST_WARNING ("num_units_in_tick = 0 detected in stream "
513           "(incompliant to H.265 E.2.1).");
514
515     READ_UINT32 (nr, vui->time_scale, 32);
516     if (vui->time_scale == 0)
517       GST_WARNING ("time_scale = 0 detected in stream "
518           "(incompliant to H.265 E.2.1).");
519
520     READ_UINT8 (nr, vui->poc_proportional_to_timing_flag, 1);
521     if (vui->poc_proportional_to_timing_flag)
522       READ_UE_MAX (nr, vui->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
523
524     READ_UINT8 (nr, vui->hrd_parameters_present_flag, 1);
525     if (vui->hrd_parameters_present_flag)
526       if (!gst_h265_parse_hrd_parameters (&vui->hrd_params, nr, 1,
527               sps->max_sub_layers_minus1))
528         goto error;
529   }
530
531   READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
532   if (vui->bitstream_restriction_flag) {
533     READ_UINT8 (nr, vui->tiles_fixed_structure_flag, 1);
534     READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
535     READ_UINT8 (nr, vui->restricted_ref_pic_lists_flag, 1);
536     READ_UE_MAX (nr, vui->min_spatial_segmentation_idc, 4096);
537     READ_UE_MAX (nr, vui->max_bytes_per_pic_denom, 16);
538     READ_UE_MAX (nr, vui->max_bits_per_min_cu_denom, 16);
539     READ_UE_MAX (nr, vui->log2_max_mv_length_horizontal, 16);
540     READ_UE_MAX (nr, vui->log2_max_mv_length_vertical, 15);
541   }
542
543   return TRUE;
544
545 error:
546   GST_WARNING ("error parsing \"VUI Parameters\"");
547   return FALSE;
548 }
549
550 static gboolean
551 get_scaling_list_params (GstH265ScalingList * dest_scaling_list,
552     guint8 sizeId, guint8 matrixId, guint8 ** sl, guint8 * size,
553     gint16 ** scaling_list_dc_coef_minus8)
554 {
555   switch (sizeId) {
556     case GST_H265_QUANT_MATIX_4X4:
557       *sl = dest_scaling_list->scaling_lists_4x4[matrixId];
558       if (size)
559         *size = 16;
560       break;
561     case GST_H265_QUANT_MATIX_8X8:
562       *sl = dest_scaling_list->scaling_lists_8x8[matrixId];
563       if (size)
564         *size = 64;
565       break;
566     case GST_H265_QUANT_MATIX_16X16:
567       *sl = dest_scaling_list->scaling_lists_16x16[matrixId];
568       if (size)
569         *size = 64;
570       if (scaling_list_dc_coef_minus8)
571         *scaling_list_dc_coef_minus8 =
572             dest_scaling_list->scaling_list_dc_coef_minus8_16x16;
573       break;
574     case GST_H265_QUANT_MATIX_32X32:
575       *sl = dest_scaling_list->scaling_lists_32x32[matrixId];
576       if (size)
577         *size = 64;
578       if (scaling_list_dc_coef_minus8)
579         *scaling_list_dc_coef_minus8 =
580             dest_scaling_list->scaling_list_dc_coef_minus8_32x32;
581       break;
582     default:
583       return FALSE;
584   }
585   return TRUE;
586 }
587
588 static gboolean
589 get_default_scaling_lists (guint8 ** sl, guint8 sizeId, guint8 matrixId)
590 {
591   switch (sizeId) {
592     case GST_H265_QUANT_MATIX_4X4:
593       memcpy (*sl, default_scaling_list0, 16);
594       break;
595
596     case GST_H265_QUANT_MATIX_8X8:
597     case GST_H265_QUANT_MATIX_16X16:
598       if (matrixId <= 2)
599         memcpy (*sl, default_scaling_list1, 64);
600       else
601         memcpy (*sl, default_scaling_list2, 64);
602       break;
603
604     case GST_H265_QUANT_MATIX_32X32:
605       if (matrixId == 0)
606         memcpy (*sl, default_scaling_list1, 64);
607       else
608         memcpy (*sl, default_scaling_list2, 64);
609       break;
610
611     default:
612       return FALSE;
613       break;
614   }
615   return TRUE;
616 }
617
618 static gboolean
619 gst_h265_parser_parse_scaling_lists (NalReader * nr,
620     GstH265ScalingList * dest_scaling_list, gboolean use_default)
621 {
622   guint8 sizeId;
623   guint8 matrixId;
624   guint8 scaling_list_pred_mode_flag = 0;
625   guint8 scaling_list_pred_matrix_id_delta = 0;
626   guint8 size, i;
627
628   GST_DEBUG ("parsing scaling lists");
629
630   for (sizeId = 0; sizeId < 4; sizeId++) {
631     for (matrixId = 0; matrixId < ((sizeId == 3) ? 2 : 6); matrixId++) {
632       gint16 *scaling_list_dc_coef_minus8 = NULL;
633       guint8 *sl;
634
635       if (!get_scaling_list_params (dest_scaling_list, sizeId, matrixId, &sl,
636               &size, &scaling_list_dc_coef_minus8))
637         goto error;
638
639       /* use_default_scaling_matrices forcefully which means,
640        * sps_scaling_list_enabled_flag=TRUE,
641        * sps_scaling_list_data_present_flag=FALSE,
642        * pps_scaling_list_data_present_falg=FALSE */
643       if (use_default) {
644         if (!get_default_scaling_lists (&sl, sizeId, matrixId))
645           goto error;
646
647         /* Inferring the value of scaling_list_dc_coef_minus8 */
648         if (sizeId > 1)
649           scaling_list_dc_coef_minus8[matrixId] = 8;
650
651       } else {
652         READ_UINT8 (nr, scaling_list_pred_mode_flag, 1);
653
654         if (!scaling_list_pred_mode_flag) {
655           guint8 refMatrixId;
656
657           READ_UE_MAX (nr, scaling_list_pred_matrix_id_delta, matrixId);
658
659           if (!scaling_list_pred_matrix_id_delta) {
660             if (!get_default_scaling_lists (&sl, sizeId, matrixId))
661               goto error;
662
663             /* Inferring the value of scaling_list_dc_coef_minus8 */
664             if (sizeId > 1)
665               scaling_list_dc_coef_minus8[matrixId] = 8;
666
667           } else {
668             guint8 *temp_sl;
669
670             refMatrixId = matrixId - scaling_list_pred_matrix_id_delta; /* 7-30 */
671
672             if (!get_scaling_list_params (dest_scaling_list, sizeId,
673                     refMatrixId, &temp_sl, NULL, NULL))
674               goto error;
675
676             for (i = 0; i < size; i++)
677               sl[i] = temp_sl[i];       /* 7-31 */
678
679
680             /* Inferring the value of scaling_list_dc_coef_minus8 */
681             if (sizeId > 1)
682               scaling_list_dc_coef_minus8[matrixId] =
683                   scaling_list_dc_coef_minus8[refMatrixId];
684           }
685         } else {
686           guint8 nextCoef = 8;
687           gint8 scaling_list_delta_coef;
688
689           if (sizeId > 1) {
690             READ_SE_ALLOWED (nr, scaling_list_dc_coef_minus8[matrixId], -7,
691                 247);
692             nextCoef = scaling_list_dc_coef_minus8[matrixId] + 8;
693           }
694
695           for (i = 0; i < size; i++) {
696             READ_SE_ALLOWED (nr, scaling_list_delta_coef, -128, 127);
697             nextCoef = (nextCoef + scaling_list_delta_coef) & 0xff;
698             sl[i] = nextCoef;
699           }
700         }
701       }
702     }
703   }
704
705   return TRUE;
706
707 error:
708   GST_WARNING ("error parsing scaling lists");
709   return FALSE;
710 }
711
712 static gboolean
713 gst_h265_parser_parse_short_term_ref_pic_sets (GstH265ShortTermRefPicSet *
714     stRPS, NalReader * nr, guint8 stRpsIdx, GstH265SPS * sps)
715 {
716   guint8 num_short_term_ref_pic_sets;
717   guint8 RefRpsIdx = 0;
718   gint16 deltaRps = 0;
719   guint8 use_delta_flag[16] = { 0 };
720   guint8 used_by_curr_pic_flag[16] = { 0 };
721   guint32 delta_poc_s0_minus1[16] = { 0 };
722   guint32 delta_poc_s1_minus1[16] = { 0 };
723   gint j, i = 0;
724   gint dPoc;
725
726   GST_DEBUG ("parsing \"ShortTermRefPicSetParameters\"");
727
728   /* set default values for fields that might not be present in the bitstream
729      and have valid defaults */
730   for (j = 0; j < 16; j++)
731     use_delta_flag[j] = 1;
732
733   num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
734
735   if (stRpsIdx != 0)
736     READ_UINT8 (nr, stRPS->inter_ref_pic_set_prediction_flag, 1);
737
738   if (stRPS->inter_ref_pic_set_prediction_flag) {
739     GstH265ShortTermRefPicSet *RefRPS;
740
741     if (stRpsIdx == num_short_term_ref_pic_sets)
742       READ_UE_MAX (nr, stRPS->delta_idx_minus1, stRpsIdx - 1);
743
744     READ_UINT8 (nr, stRPS->delta_rps_sign, 1);
745     READ_UE_MAX (nr, stRPS->abs_delta_rps_minus1, 32767);
746
747     RefRpsIdx = stRpsIdx - stRPS->delta_idx_minus1 - 1; /* 7-45 */
748     deltaRps = (1 - 2 * stRPS->delta_rps_sign) * (stRPS->abs_delta_rps_minus1 + 1);     /* 7-46 */
749
750     RefRPS = &sps->short_term_ref_pic_set[RefRpsIdx];
751
752     for (j = 0; j <= RefRPS->NumDeltaPocs; j++) {
753       READ_UINT8 (nr, used_by_curr_pic_flag[j], 1);
754       if (!used_by_curr_pic_flag[j])
755         READ_UINT8 (nr, use_delta_flag[j], 1);
756     }
757
758     /* 7-47: calculate NumNegativePics, DeltaPocS0 and UsedByCurrPicS0 */
759     i = 0;
760     for (j = (RefRPS->NumPositivePics - 1); j >= 0; j--) {
761       dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
762       if (dPoc < 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
763         stRPS->DeltaPocS0[i] = dPoc;
764         stRPS->UsedByCurrPicS0[i++] =
765             used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
766       }
767     }
768     if (deltaRps < 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
769       stRPS->DeltaPocS0[i] = deltaRps;
770       stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
771     }
772     for (j = 0; j < RefRPS->NumNegativePics; j++) {
773       dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
774       if (dPoc < 0 && use_delta_flag[j]) {
775         stRPS->DeltaPocS0[i] = dPoc;
776         stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[j];
777       }
778     }
779     stRPS->NumNegativePics = i;
780
781     /* 7-48: calculate NumPositivePics, DeltaPocS1 and UsedByCurrPicS1 */
782     i = 0;
783     for (j = (RefRPS->NumNegativePics - 1); j >= 0; j--) {
784       dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
785       if (dPoc > 0 && use_delta_flag[j]) {
786         stRPS->DeltaPocS1[i] = dPoc;
787         stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[j];
788       }
789     }
790     if (deltaRps > 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
791       stRPS->DeltaPocS1[i] = deltaRps;
792       stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
793     }
794     for (j = 0; j < RefRPS->NumPositivePics; j++) {
795       dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
796       if (dPoc > 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
797         stRPS->DeltaPocS1[i] = dPoc;
798         stRPS->UsedByCurrPicS1[i++] =
799             used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
800       }
801     }
802     stRPS->NumPositivePics = i;
803
804   } else {
805     /* 7-49 */
806     READ_UE_MAX (nr, stRPS->NumNegativePics,
807         sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1]);
808
809     /* 7-50 */
810     READ_UE_MAX (nr, stRPS->NumPositivePics,
811         (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] -
812             stRPS->NumNegativePics));
813
814     for (i = 0; i < stRPS->NumNegativePics; i++) {
815       READ_UE_MAX (nr, delta_poc_s0_minus1[i], 32767);
816       /* 7-51 */
817       READ_UINT8 (nr, stRPS->UsedByCurrPicS0[i], 1);
818
819       if (i == 0) {
820         /* 7-53 */
821         stRPS->DeltaPocS0[i] = -(delta_poc_s0_minus1[i] + 1);
822       } else {
823         /* 7-55 */
824         stRPS->DeltaPocS0[i] =
825             stRPS->DeltaPocS0[i - 1] - (delta_poc_s0_minus1[i] + 1);
826       }
827     }
828
829     for (j = 0; j < stRPS->NumPositivePics; j++) {
830       READ_UE_MAX (nr, delta_poc_s1_minus1[j], 32767);
831
832       /* 7-52 */
833       READ_UINT8 (nr, stRPS->UsedByCurrPicS1[j], 1);
834
835       if (j == 0) {
836         /* 7-54 */
837         stRPS->DeltaPocS1[j] = delta_poc_s1_minus1[j] + 1;
838       } else {
839         /* 7-56 */
840         stRPS->DeltaPocS1[j] =
841             stRPS->DeltaPocS1[j - 1] + (delta_poc_s1_minus1[j] + 1);
842       }
843     }
844
845   }
846
847   /* 7-57 */
848   stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;
849
850   return TRUE;
851
852 error:
853   GST_WARNING ("error parsing \"ShortTermRefPicSet Parameters\"");
854   return FALSE;
855 }
856
857 static gboolean
858 gst_h265_slice_parse_ref_pic_list_modification (GstH265SliceHdr * slice,
859     NalReader * nr, gint NumPocTotalCurr)
860 {
861   guint i;
862   GstH265RefPicListModification *rpl_mod = &slice->ref_pic_list_modification;
863   const guint n = ceil_log2 (NumPocTotalCurr);
864
865   READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l0, 1);
866
867   if (rpl_mod->ref_pic_list_modification_flag_l0) {
868     for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
869       READ_UINT32 (nr, rpl_mod->list_entry_l0[i], n);
870       CHECK_ALLOWED_MAX (rpl_mod->list_entry_l0[i], (NumPocTotalCurr - 1));
871     }
872   }
873   if (GST_H265_IS_B_SLICE (slice)) {
874     READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l1, 1);
875     if (rpl_mod->ref_pic_list_modification_flag_l1)
876       for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
877         READ_UINT32 (nr, rpl_mod->list_entry_l1[i], n);
878         CHECK_ALLOWED_MAX (rpl_mod->list_entry_l1[i], (NumPocTotalCurr - 1));
879       }
880   }
881
882   return TRUE;
883
884 error:
885   GST_WARNING ("error parsing \"Prediction weight table\"");
886   return FALSE;
887 }
888
889 static gboolean
890 gst_h265_slice_parse_pred_weight_table (GstH265SliceHdr * slice, NalReader * nr)
891 {
892   GstH265PredWeightTable *p;
893   gint i, j;
894   GstH265PPS *pps = slice->pps;
895   GstH265SPS *sps = pps->sps;
896
897   GST_DEBUG ("parsing \"Prediction weight table\"");
898
899   p = &slice->pred_weight_table;
900
901   READ_UE_MAX (nr, p->luma_log2_weight_denom, 7);
902
903   if (sps->chroma_format_idc != 0) {
904     READ_SE_ALLOWED (nr, p->delta_chroma_log2_weight_denom,
905         (0 - p->luma_log2_weight_denom), (7 - p->luma_log2_weight_denom));
906   }
907
908   for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
909     READ_UINT8 (nr, p->luma_weight_l0_flag[i], 1);
910
911   if (sps->chroma_format_idc != 0)
912     for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
913       READ_UINT8 (nr, p->chroma_weight_l0_flag[i], 1);
914
915   for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
916     if (p->luma_weight_l0_flag[i]) {
917       READ_SE_ALLOWED (nr, p->delta_luma_weight_l0[i], -128, 127);
918       READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
919     }
920     if (p->chroma_weight_l0_flag[i])
921       for (j = 0; j < 2; j++) {
922         READ_SE_ALLOWED (nr, p->delta_chroma_weight_l0[i][j], -128, 127);
923         READ_SE_ALLOWED (nr, p->delta_chroma_offset_l0[i][j], -512, 511);
924       }
925   }
926
927   if (GST_H265_IS_B_SLICE (slice)) {
928     for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
929       READ_UINT8 (nr, p->luma_weight_l1_flag[i], 1);
930     if (sps->chroma_format_idc != 0)
931       for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
932         READ_UINT8 (nr, p->chroma_weight_l1_flag[i], 1);
933
934     for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
935       if (p->luma_weight_l1_flag[i]) {
936         READ_SE_ALLOWED (nr, p->delta_luma_weight_l1[i], -128, 127);
937         READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
938       }
939       if (p->chroma_weight_l1_flag[i])
940         for (j = 0; j < 2; j++) {
941           READ_SE_ALLOWED (nr, p->delta_chroma_weight_l1[i][j], -128, 127);
942           READ_SE_ALLOWED (nr, p->delta_chroma_offset_l1[i][j], -512, 511);
943         }
944     }
945   }
946
947   return TRUE;
948
949 error:
950   GST_WARNING ("error parsing \"Prediction weight table\"");
951   return FALSE;
952 }
953
954 static GstH265ParserResult
955 gst_h265_parser_parse_buffering_period (GstH265Parser * parser,
956     GstH265BufferingPeriod * per, NalReader * nr)
957 {
958   GstH265SPS *sps;
959   guint8 sps_id;
960   guint i;
961   guint n;
962
963   GST_DEBUG ("parsing \"Buffering period\"");
964
965   READ_UE_MAX (nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
966   sps = gst_h265_parser_get_sps (parser, sps_id);
967   if (!sps) {
968     GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
969         sps_id);
970     return GST_H265_PARSER_BROKEN_LINK;
971   }
972   per->sps = sps;
973
974   if (sps->vui_parameters_present_flag) {
975     GstH265VUIParams *vui = &sps->vui_params;
976     GstH265HRDParams *hrd = &vui->hrd_params;
977
978     if (!hrd->sub_pic_hrd_params_present_flag)
979       READ_UINT8 (nr, per->irap_cpb_params_present_flag, 1);
980
981     if (per->irap_cpb_params_present_flag) {
982       READ_UINT8 (nr, per->cpb_delay_offset,
983           (hrd->au_cpb_removal_delay_length_minus1 + 1));
984       READ_UINT8 (nr, per->dpb_delay_offset,
985           (hrd->dpb_output_delay_length_minus1 + 1));
986     }
987
988     n = hrd->initial_cpb_removal_delay_length_minus1 + 1;
989
990     READ_UINT8 (nr, per->concatenation_flag, 1);
991     READ_UINT8 (nr, per->au_cpb_removal_delay_delta_minus1,
992         (hrd->au_cpb_removal_delay_length_minus1 + 1));
993
994     if (hrd->nal_hrd_parameters_present_flag) {
995       for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
996         READ_UINT8 (nr, per->nal_initial_cpb_removal_delay[i], n);
997         READ_UINT8 (nr, per->nal_initial_cpb_removal_offset[i], n);
998         if (hrd->sub_pic_hrd_params_present_flag
999             || per->irap_cpb_params_present_flag) {
1000           READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_delay[i], n);
1001           READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_offset[i], n);
1002         }
1003       }
1004     }
1005
1006     if (hrd->vcl_hrd_parameters_present_flag) {
1007       for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
1008         READ_UINT8 (nr, per->vcl_initial_cpb_removal_delay[i], n);
1009         READ_UINT8 (nr, per->vcl_initial_cpb_removal_offset[i], n);
1010         if (hrd->sub_pic_hrd_params_present_flag
1011             || per->irap_cpb_params_present_flag) {
1012           READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_delay[i], n);
1013           READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_offset[i], n);
1014         }
1015       }
1016     }
1017
1018   }
1019   return GST_H265_PARSER_OK;
1020
1021 error:
1022   GST_WARNING ("error parsing \"Buffering period\"");
1023   return GST_H265_PARSER_ERROR;
1024 }
1025
1026 static GstH265ParserResult
1027 gst_h265_parser_parse_pic_timing (GstH265Parser * parser,
1028     GstH265PicTiming * tim, NalReader * nr)
1029 {
1030   GstH265ProfileTierLevel *profile_tier_level;
1031   guint i;
1032
1033   GST_DEBUG ("parsing \"Picture timing\"");
1034   if (!parser->last_sps || !parser->last_sps->valid) {
1035     GST_WARNING ("didn't get the associated sequence parameter set for the "
1036         "current access unit");
1037     goto error;
1038   }
1039
1040   profile_tier_level = &parser->last_sps->profile_tier_level;
1041
1042   /* set default values */
1043   if (!profile_tier_level->progressive_source_flag
1044       && profile_tier_level->interlaced_source_flag)
1045     tim->source_scan_type = 0;
1046   else if (profile_tier_level->progressive_source_flag
1047       && !profile_tier_level->interlaced_source_flag)
1048     tim->source_scan_type = 1;
1049   else
1050     tim->source_scan_type = 2;
1051
1052   if (parser->last_sps->vui_parameters_present_flag) {
1053     GstH265VUIParams *vui = &parser->last_sps->vui_params;
1054
1055     if (vui->frame_field_info_present_flag) {
1056       READ_UINT8 (nr, tim->pic_struct, 4);
1057       READ_UINT8 (nr, tim->source_scan_type, 2);
1058       READ_UINT8 (nr, tim->duplicate_flag, 1);
1059     } else {
1060       /* set default values */
1061       tim->pic_struct = 0;
1062     }
1063
1064     if (vui->hrd_parameters_present_flag) {
1065       GstH265HRDParams *hrd = &vui->hrd_params;
1066
1067       READ_UINT8 (nr, tim->au_cpb_removal_delay_minus1,
1068           (hrd->au_cpb_removal_delay_length_minus1 + 1));
1069       READ_UINT8 (nr, tim->pic_dpb_output_delay,
1070           (hrd->dpb_output_delay_length_minus1 + 1));
1071
1072       if (hrd->sub_pic_hrd_params_present_flag)
1073         READ_UINT8 (nr, tim->pic_dpb_output_du_delay,
1074             (hrd->dpb_output_delay_du_length_minus1 + 1));
1075
1076       if (hrd->sub_pic_hrd_params_present_flag
1077           && hrd->sub_pic_cpb_params_in_pic_timing_sei_flag) {
1078         READ_UE (nr, tim->num_decoding_units_minus1);
1079
1080         READ_UINT8 (nr, tim->du_common_cpb_removal_delay_flag, 1);
1081         if (tim->du_common_cpb_removal_delay_flag)
1082           READ_UINT8 (nr, tim->du_common_cpb_removal_delay_increment_minus1,
1083               (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1084
1085         tim->num_nalus_in_du_minus1 =
1086             g_new0 (guint32, (tim->num_decoding_units_minus1 + 1));
1087         tim->du_cpb_removal_delay_increment_minus1 =
1088             g_new0 (guint8, (tim->num_decoding_units_minus1 + 1));
1089
1090         for (i = 0; i <= (tim->num_decoding_units_minus1 + 1); i++) {
1091           READ_UE (nr, tim->num_nalus_in_du_minus1[i]);
1092
1093           if (!tim->du_common_cpb_removal_delay_flag
1094               && (i < tim->num_decoding_units_minus1))
1095             READ_UINT8 (nr, tim->du_cpb_removal_delay_increment_minus1[i],
1096                 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1097         }
1098       }
1099     }
1100   }
1101   return GST_H265_PARSER_OK;
1102
1103 error:
1104   GST_WARNING ("error parsing \"Picture timing\"");
1105   return GST_H265_PARSER_ERROR;
1106 }
1107
1108 static GstH265ParserResult
1109 gst_h265_parser_parse_recovery_point (GstH265Parser * parser,
1110     GstH265RecoveryPoint * rp, NalReader * nr)
1111 {
1112   GstH265SPS *const sps = parser->last_sps;
1113   gint32 max_pic_order_cnt_lsb;
1114
1115   GST_DEBUG ("parsing \"Recovery point\"");
1116   if (!sps || !sps->valid) {
1117     GST_WARNING ("didn't get the associated sequence parameter set for the "
1118         "current access unit");
1119     goto error;
1120   }
1121
1122   max_pic_order_cnt_lsb = pow (2, (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
1123   READ_SE_ALLOWED (nr, rp->recovery_poc_cnt, -max_pic_order_cnt_lsb / 2,
1124       max_pic_order_cnt_lsb - 1);
1125   READ_UINT8 (nr, rp->exact_match_flag, 1);
1126   READ_UINT8 (nr, rp->broken_link_flag, 1);
1127
1128   return GST_H265_PARSER_OK;
1129
1130 error:
1131   GST_WARNING ("error parsing \"Recovery point\"");
1132   return GST_H265_PARSER_ERROR;
1133 }
1134
1135
1136 static GstH265ParserResult
1137 gst_h265_parser_parse_registered_user_data (GstH265Parser * parser,
1138     GstH265RegisteredUserData * rud, NalReader * nr, guint payload_size)
1139 {
1140   guint8 *data = NULL;
1141   guint i;
1142
1143   rud->data = NULL;
1144   rud->size = 0;
1145
1146   if (payload_size < 2)
1147     return GST_H265_PARSER_ERROR;
1148
1149   READ_UINT8 (nr, rud->country_code, 8);
1150   --payload_size;
1151
1152   if (rud->country_code == 0xFF) {
1153     READ_UINT8 (nr, rud->country_code_extension, 8);
1154     --payload_size;
1155   } else {
1156     rud->country_code_extension = 0;
1157   }
1158
1159   if (payload_size < 8)
1160     return GST_H265_PARSER_ERROR;
1161
1162   data = g_malloc (payload_size);
1163   for (i = 0; i < payload_size / 8; ++i) {
1164     READ_UINT8 (nr, data[i], 8);
1165   }
1166
1167   GST_MEMDUMP ("SEI user data", data, payload_size / 8);
1168
1169   rud->data = data;
1170   rud->size = payload_size;
1171   return GST_H265_PARSER_OK;
1172
1173 error:
1174   {
1175     GST_WARNING ("error parsing \"Registered User Data\"");
1176     g_free (data);
1177     return GST_H265_PARSER_ERROR;
1178   }
1179 }
1180
1181
1182 static GstH265ParserResult
1183 gst_h265_parser_parse_time_code (GstH265Parser * parser,
1184     GstH265TimeCode * tc, NalReader * nr)
1185 {
1186   guint i;
1187
1188   GST_DEBUG ("parsing \"Time code\"");
1189
1190   READ_UINT8 (nr, tc->num_clock_ts, 2);
1191
1192   for (i = 0; i < tc->num_clock_ts; i++) {
1193     READ_UINT8 (nr, tc->clock_timestamp_flag[i], 1);
1194     if (tc->clock_timestamp_flag[i]) {
1195       READ_UINT8 (nr, tc->units_field_based_flag[i], 1);
1196       READ_UINT8 (nr, tc->counting_type[i], 5);
1197       READ_UINT8 (nr, tc->full_timestamp_flag[i], 1);
1198       READ_UINT8 (nr, tc->discontinuity_flag[i], 1);
1199       READ_UINT8 (nr, tc->cnt_dropped_flag[i], 1);
1200       READ_UINT16 (nr, tc->n_frames[i], 9);
1201
1202       if (tc->full_timestamp_flag[i]) {
1203         tc->seconds_flag[i] = TRUE;
1204         READ_UINT8 (nr, tc->seconds_value[i], 6);
1205
1206         tc->minutes_flag[i] = TRUE;
1207         READ_UINT8 (nr, tc->minutes_value[i], 6);
1208
1209         tc->hours_flag[i] = TRUE;
1210         READ_UINT8 (nr, tc->hours_value[i], 5);
1211       } else {
1212         READ_UINT8 (nr, tc->seconds_flag[i], 1);
1213         if (tc->seconds_flag[i]) {
1214           READ_UINT8 (nr, tc->seconds_value[i], 6);
1215           READ_UINT8 (nr, tc->minutes_flag[i], 1);
1216           if (tc->minutes_flag[i]) {
1217             READ_UINT8 (nr, tc->minutes_value[i], 6);
1218             READ_UINT8 (nr, tc->hours_flag[i], 1);
1219             if (tc->hours_flag[i]) {
1220               READ_UINT8 (nr, tc->hours_value[i], 5);
1221             }
1222           }
1223         }
1224       }
1225     }
1226
1227     READ_UINT8 (nr, tc->time_offset_length[i], 5);
1228
1229     if (tc->time_offset_length[i] > 0)
1230       READ_UINT32 (nr, tc->time_offset_value[i], tc->time_offset_length[i]);
1231   }
1232
1233   return GST_H265_PARSER_OK;
1234
1235 error:
1236   GST_WARNING ("error parsing \"Time code\"");
1237   return GST_H265_PARSER_ERROR;
1238 }
1239
1240 static GstH265ParserResult
1241 gst_h265_parser_parse_mastering_display_colour_volume (GstH265Parser * parser,
1242     GstH265MasteringDisplayColourVolume * mdcv, NalReader * nr)
1243 {
1244   guint i;
1245
1246   GST_DEBUG ("parsing \"Mastering display colour volume\"");
1247
1248   for (i = 0; i < 3; i++) {
1249     READ_UINT16 (nr, mdcv->display_primaries_x[i], 16);
1250     READ_UINT16 (nr, mdcv->display_primaries_y[i], 16);
1251   }
1252
1253   READ_UINT16 (nr, mdcv->white_point_x, 16);
1254   READ_UINT16 (nr, mdcv->white_point_y, 16);
1255   READ_UINT32 (nr, mdcv->max_display_mastering_luminance, 32);
1256   READ_UINT32 (nr, mdcv->min_display_mastering_luminance, 32);
1257
1258   return GST_H265_PARSER_OK;
1259
1260 error:
1261   GST_WARNING ("error parsing \"Mastering display colour volume\"");
1262   return GST_H265_PARSER_ERROR;
1263 }
1264
1265 static GstH265ParserResult
1266 gst_h265_parser_parse_content_light_level_info (GstH265Parser * parser,
1267     GstH265ContentLightLevel * cll, NalReader * nr)
1268 {
1269   GST_DEBUG ("parsing \"Content light level\"");
1270
1271   READ_UINT16 (nr, cll->max_content_light_level, 16);
1272   READ_UINT16 (nr, cll->max_pic_average_light_level, 16);
1273
1274   return GST_H265_PARSER_OK;
1275
1276 error:
1277   GST_WARNING ("error parsing \"Content light level\"");
1278   return GST_H265_PARSER_ERROR;
1279 }
1280
1281 /******** API *************/
1282
1283 /**
1284  * gst_h265_parser_new:
1285  *
1286  * Creates a new #GstH265Parser. It should be freed with
1287  * gst_h265_parser_free after use.
1288  *
1289  * Returns: a new #GstH265Parser
1290  */
1291 GstH265Parser *
1292 gst_h265_parser_new (void)
1293 {
1294   GstH265Parser *parser;
1295
1296   parser = g_slice_new0 (GstH265Parser);
1297
1298   return parser;
1299 }
1300
1301 /**
1302  * gst_h265_parser_free:
1303  * @parser: the #GstH265Parser to free
1304  *
1305  * Frees @parser and sets it to %NULL
1306  */
1307 void
1308 gst_h265_parser_free (GstH265Parser * parser)
1309 {
1310   g_slice_free (GstH265Parser, parser);
1311   parser = NULL;
1312 }
1313
1314 /**
1315  * gst_h265_parser_identify_nalu_unchecked:
1316  * @parser: a #GstH265Parser
1317  * @data: The data to parse
1318  * @offset: the offset from which to parse @data
1319  * @size: the size of @data
1320  * @nalu: The #GstH265NalUnit where to store parsed nal headers
1321  *
1322  * Parses @data and fills @nalu from the next nalu data from @data.
1323  *
1324  * This differs from @gst_h265_parser_identify_nalu in that it doesn't
1325  * check whether the packet is complete or not.
1326  *
1327  * Note: Only use this function if you already know the provided @data
1328  * is a complete NALU, else use @gst_h265_parser_identify_nalu.
1329  *
1330  * Returns: a #GstH265ParserResult
1331  */
1332 GstH265ParserResult
1333 gst_h265_parser_identify_nalu_unchecked (GstH265Parser * parser,
1334     const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1335 {
1336   gint off1;
1337
1338   memset (nalu, 0, sizeof (*nalu));
1339
1340   if (size < offset + 4) {
1341     GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1342         ", offset %u", size, offset);
1343     return GST_H265_PARSER_ERROR;
1344   }
1345
1346   off1 = scan_for_start_codes (data + offset, size - offset);
1347
1348   if (off1 < 0) {
1349     GST_DEBUG ("No start code prefix in this buffer");
1350     return GST_H265_PARSER_NO_NAL;
1351   }
1352
1353   if (offset + off1 == size - 1) {
1354     GST_DEBUG ("Missing data to identify nal unit");
1355
1356     return GST_H265_PARSER_ERROR;
1357   }
1358
1359   nalu->sc_offset = offset + off1;
1360
1361   /* sc might have 2 or 3 0-bytes */
1362   if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
1363     nalu->sc_offset--;
1364
1365   nalu->offset = offset + off1 + 3;
1366   nalu->data = (guint8 *) data;
1367   nalu->size = size - nalu->offset;
1368
1369   if (!gst_h265_parse_nalu_header (nalu)) {
1370     GST_WARNING ("error parsing \"NAL unit header\"");
1371     nalu->size = 0;
1372     return GST_H265_PARSER_BROKEN_DATA;
1373   }
1374
1375   nalu->valid = TRUE;
1376
1377   if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB) {
1378     GST_DEBUG ("end-of-seq or end-of-stream nal found");
1379     nalu->size = 2;
1380     return GST_H265_PARSER_OK;
1381   }
1382
1383   return GST_H265_PARSER_OK;
1384 }
1385
1386 /**
1387  * gst_h265_parser_identify_nalu:
1388  * @parser: a #GstH265Parser
1389  * @data: The data to parse
1390  * @offset: the offset from which to parse @data
1391  * @size: the size of @data
1392  * @nalu: The #GstH265NalUnit where to store parsed nal headers
1393  *
1394  * Parses @data and fills @nalu from the next nalu data from @data
1395  *
1396  * Returns: a #GstH265ParserResult
1397  */
1398 GstH265ParserResult
1399 gst_h265_parser_identify_nalu (GstH265Parser * parser,
1400     const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1401 {
1402   GstH265ParserResult res;
1403   gint off2;
1404
1405   res =
1406       gst_h265_parser_identify_nalu_unchecked (parser, data, offset, size,
1407       nalu);
1408
1409   if (res != GST_H265_PARSER_OK)
1410     goto beach;
1411
1412   /* The two NALs are exactly 2 bytes size and are placed at the end of an AU,
1413    * there is no need to wait for the following */
1414   if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB)
1415     goto beach;
1416
1417   off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1418   if (off2 < 0) {
1419     GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1420
1421     return GST_H265_PARSER_NO_NAL_END;
1422   }
1423
1424   /* Mini performance improvement:
1425    * We could have a way to store how many 0s were skipped to avoid
1426    * parsing them again on the next NAL */
1427   while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1428     off2--;
1429
1430   nalu->size = off2;
1431   if (nalu->size < 3)
1432     return GST_H265_PARSER_BROKEN_DATA;
1433
1434   GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1435
1436 beach:
1437   return res;
1438 }
1439
1440 /**
1441  * gst_h265_parser_identify_nalu_hevc:
1442  * @parser: a #GstH265Parser
1443  * @data: The data to parse, must be the beging of the Nal unit
1444  * @offset: the offset from which to parse @data
1445  * @size: the size of @data
1446  * @nal_length_size: the size in bytes of the HEVC nal length prefix.
1447  * @nalu: The #GstH265NalUnit where to store parsed nal headers
1448  *
1449  * Parses @data and sets @nalu.
1450  *
1451  * Returns: a #GstH265ParserResult
1452  */
1453 GstH265ParserResult
1454 gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
1455     const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1456     GstH265NalUnit * nalu)
1457 {
1458   GstBitReader br;
1459
1460   memset (nalu, 0, sizeof (*nalu));
1461
1462   if (size < offset + nal_length_size) {
1463     GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1464         ", offset %u", size, offset);
1465     return GST_H265_PARSER_ERROR;
1466   }
1467
1468   size = size - offset;
1469   gst_bit_reader_init (&br, data + offset, size);
1470
1471   nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1472       nal_length_size * 8);
1473   nalu->sc_offset = offset;
1474   nalu->offset = offset + nal_length_size;
1475
1476   if (size < nalu->size + nal_length_size) {
1477     nalu->size = 0;
1478
1479     return GST_H265_PARSER_NO_NAL_END;
1480   }
1481
1482   nalu->data = (guint8 *) data;
1483
1484   if (!gst_h265_parse_nalu_header (nalu)) {
1485     GST_WARNING ("error parsing \"NAL unit header\"");
1486     nalu->size = 0;
1487     return GST_H265_PARSER_BROKEN_DATA;
1488   }
1489
1490   if (nalu->size < 2)
1491     return GST_H265_PARSER_BROKEN_DATA;
1492
1493   nalu->valid = TRUE;
1494
1495   return GST_H265_PARSER_OK;
1496 }
1497
1498 /**
1499  * gst_h265_parser_parse_nal:
1500  * @parser: a #GstH265Parser
1501  * @nalu: The #GstH265NalUnit to parse
1502  *
1503  * This function should be called in the case one doesn't need to
1504  * parse a specific structure. It is necessary to do so to make
1505  * sure @parser is up to date.
1506  *
1507  * Returns: a #GstH265ParserResult
1508  */
1509 GstH265ParserResult
1510 gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
1511 {
1512   GstH265VPS vps;
1513   GstH265SPS sps;
1514   GstH265PPS pps;
1515
1516   switch (nalu->type) {
1517     case GST_H265_NAL_VPS:
1518       return gst_h265_parser_parse_vps (parser, nalu, &vps);
1519       break;
1520     case GST_H265_NAL_SPS:
1521       return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
1522       break;
1523     case GST_H265_NAL_PPS:
1524       return gst_h265_parser_parse_pps (parser, nalu, &pps);
1525   }
1526
1527   return GST_H265_PARSER_OK;
1528 }
1529
1530 /**
1531  * gst_h265_parser_parse_vps:
1532  * @parser: a #GstH265Parser
1533  * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1534  * @vps: The #GstH265VPS to fill.
1535  *
1536  * Parses @data, and fills the @vps structure.
1537  *
1538  * Returns: a #GstH265ParserResult
1539  */
1540 GstH265ParserResult
1541 gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
1542     GstH265VPS * vps)
1543 {
1544   GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);
1545
1546   if (res == GST_H265_PARSER_OK) {
1547     GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);
1548
1549     parser->vps[vps->id] = *vps;
1550     parser->last_vps = &parser->vps[vps->id];
1551   }
1552
1553   return res;
1554 }
1555
1556 /**
1557  * gst_h265_parse_vps:
1558  * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1559  * @sps: The #GstH265VPS to fill.
1560  *
1561  * Parses @data, and fills the @vps structure.
1562  *
1563  * Returns: a #GstH265ParserResult
1564  */
1565 GstH265ParserResult
1566 gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
1567 {
1568   NalReader nr;
1569   guint i, j;
1570
1571   GST_DEBUG ("parsing VPS");
1572
1573   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1574       nalu->size - nalu->header_bytes);
1575
1576   memset (vps, 0, sizeof (*vps));
1577
1578   vps->cprms_present_flag = 1;
1579
1580   READ_UINT8 (&nr, vps->id, 4);
1581
1582   READ_UINT8 (&nr, vps->base_layer_internal_flag, 1);
1583   READ_UINT8 (&nr, vps->base_layer_available_flag, 1);
1584
1585   READ_UINT8 (&nr, vps->max_layers_minus1, 6);
1586   READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
1587   READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1588
1589   /* skip reserved_0xffff_16bits */
1590   if (!nal_reader_skip (&nr, 16))
1591     goto error;
1592
1593   if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1594           vps->max_sub_layers_minus1))
1595     goto error;
1596
1597   READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1598
1599   for (i =
1600       (vps->sub_layer_ordering_info_present_flag ? 0 :
1601           vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1602     READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1603     READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1604         vps->max_dec_pic_buffering_minus1[i]);
1605     READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1606   }
1607   /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1608   if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1609     for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1610       vps->max_dec_pic_buffering_minus1[i] =
1611           vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1612       vps->max_num_reorder_pics[i] =
1613           vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1614       vps->max_latency_increase_plus1[i] =
1615           vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1616     }
1617   }
1618
1619   READ_UINT8 (&nr, vps->max_layer_id, 6);
1620   /* shall allow 63 */
1621   CHECK_ALLOWED_MAX (vps->max_layer_id, 63);
1622
1623   READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1624   /* allowed range is 0 to 1023 */
1625   CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 1023);
1626
1627   for (i = 1; i <= vps->num_layer_sets_minus1; i++) {
1628     for (j = 0; j <= vps->max_layer_id; j++) {
1629       /* layer_id_included_flag[i][j] */
1630       /* FIXME: need to parse this when we can support parsing multi-layer info. */
1631       nal_reader_skip (&nr, 1);
1632     }
1633   }
1634
1635   READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1636
1637   if (vps->timing_info_present_flag) {
1638     READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1639     READ_UINT32 (&nr, vps->time_scale, 32);
1640     READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1641
1642     if (vps->poc_proportional_to_timing_flag)
1643       READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1644
1645     READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1646     /* allowed range is
1647      * 0 to vps_num_layer_sets_minus1 + 1 */
1648     CHECK_ALLOWED_MAX (vps->num_hrd_parameters, vps->num_layer_sets_minus1 + 1);
1649
1650     if (vps->num_hrd_parameters) {
1651       READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1652       /* allowed range is
1653        * ( vps_base_layer_internal_flag ? 0 : 1 ) to vps_num_layer_sets_minus1
1654        */
1655       CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, vps->num_layer_sets_minus1);
1656
1657       if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1658               vps->cprms_present_flag, vps->max_sub_layers_minus1))
1659         goto error;
1660     }
1661
1662     /* FIXME: VPS can have multiple hrd parameters, and therefore hrd_params
1663      * should be an array (like Garray). But it also requires new _clear()
1664      * method for free the array in GstH265VPS whenever gst_h265_parse_vps()
1665      * is called. Need to work for multi-layer related parsing supporting
1666      *
1667      * FIXME: Following code is just work around to find correct
1668      * vps_extension position */
1669
1670     /* skip the first parsed one above */
1671     for (i = 1; i < vps->num_hrd_parameters; i++) {
1672       guint16 hrd_layer_set_idx;
1673       guint8 cprms_present_flag;
1674       GstH265HRDParams hrd_params;
1675
1676       READ_UE_MAX (&nr, hrd_layer_set_idx, 1023);
1677       CHECK_ALLOWED_MAX (hrd_layer_set_idx, vps->num_layer_sets_minus1);
1678
1679       /* need parsing if (i > 1) */
1680       READ_UINT8 (&nr, cprms_present_flag, 1);
1681
1682       if (!gst_h265_parse_hrd_parameters (&hrd_params, &nr,
1683               cprms_present_flag, vps->max_sub_layers_minus1))
1684         goto error;
1685     }
1686   }
1687   READ_UINT8 (&nr, vps->vps_extension, 1);
1688   vps->valid = TRUE;
1689
1690   return GST_H265_PARSER_OK;
1691
1692 error:
1693   GST_WARNING ("error parsing \"Video parameter set\"");
1694   vps->valid = FALSE;
1695   return GST_H265_PARSER_ERROR;
1696 }
1697
1698 /**
1699  * gst_h265_parser_parse_sps:
1700  * @parser: a #GstH265Parser
1701  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1702  * @sps: The #GstH265SPS to fill.
1703  * @parse_vui_params: Whether to parse the vui_params or not
1704  *
1705  * Parses @data, and fills the @sps structure.
1706  *
1707  * Returns: a #GstH265ParserResult
1708  */
1709 GstH265ParserResult
1710 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1711     GstH265SPS * sps, gboolean parse_vui_params)
1712 {
1713   GstH265ParserResult res =
1714       gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1715
1716   if (res == GST_H265_PARSER_OK) {
1717     GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1718
1719     parser->sps[sps->id] = *sps;
1720     parser->last_sps = &parser->sps[sps->id];
1721   }
1722
1723   return res;
1724 }
1725
1726 /**
1727  * gst_h265_parse_sps:
1728  * parser: The #GstH265Parser
1729  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1730  * @sps: The #GstH265SPS to fill.
1731  * @parse_vui_params: Whether to parse the vui_params or not
1732  *
1733  * Parses @data, and fills the @sps structure.
1734  *
1735  * Returns: a #GstH265ParserResult
1736  */
1737 GstH265ParserResult
1738 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1739     GstH265SPS * sps, gboolean parse_vui_params)
1740 {
1741   NalReader nr;
1742   GstH265VPS *vps;
1743   guint8 vps_id;
1744   guint i;
1745   guint subwc[] = { 1, 2, 2, 1, 1 };
1746   guint subhc[] = { 1, 2, 1, 1, 1 };
1747   GstH265VUIParams *vui = NULL;
1748
1749   GST_DEBUG ("parsing SPS");
1750
1751   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1752       nalu->size - nalu->header_bytes);
1753
1754   memset (sps, 0, sizeof (*sps));
1755
1756   READ_UINT8 (&nr, vps_id, 4);
1757   vps = gst_h265_parser_get_vps (parser, vps_id);
1758   if (!vps) {
1759     GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1760         vps_id);
1761   }
1762   sps->vps = vps;
1763
1764   READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1765   READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1766
1767   if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1768           sps->max_sub_layers_minus1))
1769     goto error;
1770
1771   READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1772
1773   READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1774   if (sps->chroma_format_idc == 3)
1775     READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1776
1777   READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1778   READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1779
1780   READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1781   if (sps->conformance_window_flag) {
1782     READ_UE (&nr, sps->conf_win_left_offset);
1783     READ_UE (&nr, sps->conf_win_right_offset);
1784     READ_UE (&nr, sps->conf_win_top_offset);
1785     READ_UE (&nr, sps->conf_win_bottom_offset);
1786   }
1787
1788   READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1789   READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1790   READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1791
1792   READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1793   for (i =
1794       (sps->sub_layer_ordering_info_present_flag ? 0 :
1795           sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1796     READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1797     READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1798         sps->max_dec_pic_buffering_minus1[i]);
1799     READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1800   }
1801   /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1802   if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1803     for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1804       sps->max_dec_pic_buffering_minus1[i] =
1805           sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1806       sps->max_num_reorder_pics[i] =
1807           sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1808       sps->max_latency_increase_plus1[i] =
1809           sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1810     }
1811   }
1812
1813   /* The limits are calculted based on the profile_tier_level constraint
1814    * in Annex-A: CtbLog2SizeY = 4 to 6 */
1815   READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1816   READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1817   READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1818   READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1819   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1820   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1821
1822   READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1823   if (sps->scaling_list_enabled_flag) {
1824     READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1825
1826     if (sps->scaling_list_data_present_flag)
1827       if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1828         goto error;
1829   }
1830
1831   READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1832   READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1833   READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1834
1835   if (sps->pcm_enabled_flag) {
1836     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1837     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1838     READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1839     READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1840     READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1841   }
1842
1843   READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1844   for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1845     if (!gst_h265_parser_parse_short_term_ref_pic_sets
1846         (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1847       goto error;
1848
1849   READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1850   if (sps->long_term_ref_pics_present_flag) {
1851     READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1852     for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1853       READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1854           sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1855       READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1856     }
1857   }
1858
1859   READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1860   READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1861   READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1862
1863   if (sps->vui_parameters_present_flag && parse_vui_params) {
1864     if (!gst_h265_parse_vui_parameters (sps, &nr))
1865       goto error;
1866     vui = &sps->vui_params;
1867   }
1868
1869   READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1870
1871   if (sps->sps_extension_flag) {
1872     READ_UINT8 (&nr, sps->sps_range_extension_flag, 1);
1873     READ_UINT8 (&nr, sps->sps_multilayer_extension_flag, 1);
1874     READ_UINT8 (&nr, sps->sps_3d_extension_flag, 1);
1875     READ_UINT8 (&nr, sps->sps_extension_5bits, 5);
1876   }
1877
1878   if (sps->sps_range_extension_flag) {
1879     READ_UINT8 (&nr,
1880         sps->sps_extnsion_params.transform_skip_rotation_enabled_flag, 1);
1881     READ_UINT8 (&nr,
1882         sps->sps_extnsion_params.transform_skip_context_enabled_flag, 1);
1883     READ_UINT8 (&nr, sps->sps_extnsion_params.implicit_rdpcm_enabled_flag, 1);
1884     READ_UINT8 (&nr, sps->sps_extnsion_params.explicit_rdpcm_enabled_flag, 1);
1885     READ_UINT8 (&nr,
1886         sps->sps_extnsion_params.extended_precision_processing_flag, 1);
1887     READ_UINT8 (&nr, sps->sps_extnsion_params.intra_smoothing_disabled_flag, 1);
1888     READ_UINT8 (&nr,
1889         sps->sps_extnsion_params.high_precision_offsets_enabled_flag, 1);
1890     READ_UINT8 (&nr,
1891         sps->sps_extnsion_params.persistent_rice_adaptation_enabled_flag, 1);
1892     READ_UINT8 (&nr,
1893         sps->sps_extnsion_params.cabac_bypass_alignment_enabled_flag, 1);
1894   }
1895
1896   /* calculate ChromaArrayType */
1897   if (!sps->separate_colour_plane_flag)
1898     sps->chroma_array_type = sps->chroma_format_idc;
1899
1900   /* Calculate  width and height */
1901   sps->width = sps->pic_width_in_luma_samples;
1902   sps->height = sps->pic_height_in_luma_samples;
1903   if (sps->width < 0 || sps->height < 0) {
1904     GST_WARNING ("invalid width/height in SPS");
1905     goto error;
1906   }
1907
1908   if (sps->conformance_window_flag) {
1909     const guint crop_unit_x = subwc[sps->chroma_format_idc];
1910     const guint crop_unit_y = subhc[sps->chroma_format_idc];
1911
1912     sps->crop_rect_width = sps->width -
1913         (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
1914     sps->crop_rect_height = sps->height -
1915         (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
1916     sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
1917     sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
1918
1919     GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
1920         sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
1921   }
1922
1923   sps->fps_num = 0;
1924   sps->fps_den = 1;
1925
1926   if (vui && vui->timing_info_present_flag) {
1927     /* derive framerate for progressive stream if the pic_struct
1928      * syntax element is not present in picture timing SEI messages */
1929     /* Fixme: handle other cases also */
1930     if (parse_vui_params && vui->timing_info_present_flag
1931         && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
1932       sps->fps_num = vui->time_scale;
1933       sps->fps_den = vui->num_units_in_tick;
1934       GST_LOG ("framerate %d/%d in VUI", sps->fps_num, sps->fps_den);
1935     }
1936   } else if (vps && vps->timing_info_present_flag) {
1937     sps->fps_num = vps->time_scale;
1938     sps->fps_den = vps->num_units_in_tick;
1939     GST_LOG ("framerate %d/%d in VPS", sps->fps_num, sps->fps_den);
1940   } else {
1941     GST_LOG ("No VUI, unknown framerate");
1942   }
1943
1944   sps->valid = TRUE;
1945
1946   return GST_H265_PARSER_OK;
1947
1948 error:
1949   GST_WARNING ("error parsing \"Sequence parameter set\"");
1950   sps->valid = FALSE;
1951   return GST_H265_PARSER_ERROR;
1952 }
1953
1954 /**
1955  * gst_h265_parse_pps:
1956  * @parser: a #GstH265Parser
1957  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1958  * @pps: The #GstH265PPS to fill.
1959  *
1960  * Parses @data, and fills the @pps structure.
1961  *
1962  * Returns: a #GstH265ParserResult
1963  */
1964 GstH265ParserResult
1965 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
1966     GstH265PPS * pps)
1967 {
1968   NalReader nr;
1969   GstH265SPS *sps;
1970   gint sps_id;
1971   gint qp_bd_offset;
1972   guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY, MaxBitDepthY, MaxBitDepthC;
1973   guint8 i;
1974
1975   GST_DEBUG ("parsing PPS");
1976
1977   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1978       nalu->size - nalu->header_bytes);
1979
1980   memset (pps, 0, sizeof (*pps));
1981
1982   READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
1983   READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
1984
1985   sps = gst_h265_parser_get_sps (parser, sps_id);
1986   if (!sps) {
1987     GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
1988         sps_id);
1989     return GST_H265_PARSER_BROKEN_LINK;
1990   }
1991   pps->sps = sps;
1992   qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
1993
1994   MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
1995   CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
1996   CtbSizeY = 1 << CtbLog2SizeY;
1997   pps->PicHeightInCtbsY =
1998       ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
1999   pps->PicWidthInCtbsY =
2000       ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
2001
2002   /* set default values for fields that might not be present in the bitstream
2003      and have valid defaults */
2004   pps->uniform_spacing_flag = 1;
2005   pps->loop_filter_across_tiles_enabled_flag = 1;
2006
2007   READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
2008   READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
2009   READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
2010   READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
2011   READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
2012
2013   READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
2014   READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
2015   READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
2016
2017   READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
2018   READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
2019
2020   READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
2021   if (pps->cu_qp_delta_enabled_flag)
2022     READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
2023         sps->log2_diff_max_min_luma_coding_block_size);
2024
2025   READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
2026   READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
2027
2028   READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
2029   READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
2030   READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
2031   READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
2032   READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
2033   READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
2034
2035   if (pps->tiles_enabled_flag) {
2036     READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 0, 19);
2037     READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 0, 21);
2038
2039     READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
2040     /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
2041     if (pps->uniform_spacing_flag) {
2042       guint8 num_col = pps->num_tile_columns_minus1 + 1;
2043       guint8 num_row = pps->num_tile_rows_minus1 + 1;
2044       for (i = 0; i < num_col; i++) {
2045         pps->column_width_minus1[i] =
2046             ((i + 1) * pps->PicWidthInCtbsY / num_col
2047             - i * pps->PicWidthInCtbsY / num_col) - 1;
2048       }
2049       for (i = 0; i < num_row; i++) {
2050         pps->row_height_minus1[i] =
2051             ((i + 1) * pps->PicHeightInCtbsY / num_row
2052             - i * pps->PicHeightInCtbsY / num_row) - 1;
2053       }
2054     } else {
2055       pps->column_width_minus1[pps->num_tile_columns_minus1] =
2056           pps->PicWidthInCtbsY - 1;
2057       for (i = 0; i < pps->num_tile_columns_minus1; i++) {
2058         READ_UE (&nr, pps->column_width_minus1[i]);
2059         pps->column_width_minus1[pps->num_tile_columns_minus1] -=
2060             (pps->column_width_minus1[i] + 1);
2061       }
2062
2063       pps->row_height_minus1[pps->num_tile_rows_minus1] =
2064           pps->PicHeightInCtbsY - 1;
2065       for (i = 0; i < pps->num_tile_rows_minus1; i++) {
2066         READ_UE (&nr, pps->row_height_minus1[i]);
2067         pps->row_height_minus1[pps->num_tile_rows_minus1] -=
2068             (pps->row_height_minus1[i] + 1);
2069       }
2070     }
2071     READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
2072   }
2073
2074   READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
2075
2076   READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
2077   if (pps->deblocking_filter_control_present_flag) {
2078     READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
2079
2080     READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
2081     if (!pps->deblocking_filter_disabled_flag) {
2082       READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
2083       READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
2084     }
2085   }
2086
2087   READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
2088   if (pps->scaling_list_data_present_flag)
2089     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
2090       goto error;
2091   if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
2092       && !pps->scaling_list_data_present_flag)
2093     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
2094       goto error;
2095
2096   READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
2097   READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
2098   READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
2099   READ_UINT8 (&nr, pps->pps_extension_flag, 1);
2100
2101   if (pps->pps_extension_flag) {
2102     READ_UINT8 (&nr, pps->pps_range_extension_flag, 1);
2103     READ_UINT8 (&nr, pps->pps_multilayer_extension_flag, 1);
2104     READ_UINT8 (&nr, pps->pps_3d_extension_flag, 1);
2105     READ_UINT8 (&nr, pps->pps_extension_5bits, 5);
2106   }
2107
2108   if (pps->pps_range_extension_flag) {
2109     if (pps->transform_skip_enabled_flag)
2110       READ_UE (&nr,
2111           pps->pps_extension_params.log2_max_transform_skip_block_size_minus2);
2112     READ_UINT8 (&nr,
2113         pps->pps_extension_params.cross_component_prediction_enabled_flag, 1);
2114     READ_UINT8 (&nr,
2115         pps->pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
2116     if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag) {
2117       READ_UE_MAX (&nr,
2118           pps->pps_extension_params.diff_cu_chroma_qp_offset_depth,
2119           sps->log2_diff_max_min_luma_coding_block_size);
2120       READ_UE_MAX (&nr,
2121           pps->pps_extension_params.chroma_qp_offset_list_len_minus1, 5);
2122       for (i = 0;
2123           i <= pps->pps_extension_params.chroma_qp_offset_list_len_minus1;
2124           i++) {
2125         READ_SE_ALLOWED (&nr, pps->pps_extension_params.cb_qp_offset_list[i],
2126             -12, 12);
2127         READ_SE_ALLOWED (&nr, pps->pps_extension_params.cr_qp_offset_list[i],
2128             -12, 12);
2129       }
2130     }
2131     MaxBitDepthY =
2132         sps->bit_depth_luma_minus8 > 2 ? sps->bit_depth_luma_minus8 - 2 : 0;
2133     MaxBitDepthC =
2134         sps->bit_depth_chroma_minus8 > 2 ? sps->bit_depth_chroma_minus8 - 2 : 0;
2135     READ_UE_ALLOWED (&nr, pps->pps_extension_params.log2_sao_offset_scale_luma,
2136         0, MaxBitDepthY);
2137     READ_UE_ALLOWED (&nr,
2138         pps->pps_extension_params.log2_sao_offset_scale_chroma, 0,
2139         MaxBitDepthC);
2140   }
2141   pps->valid = TRUE;
2142   return GST_H265_PARSER_OK;
2143
2144 error:
2145   GST_WARNING ("error parsing \"Picture parameter set\"");
2146   pps->valid = FALSE;
2147   return GST_H265_PARSER_ERROR;
2148 }
2149
2150 /**
2151  * gst_h265_parser_parse_pps:
2152  * @parser: a #GstH265Parser
2153  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2154  * @pps: The #GstH265PPS to fill.
2155  *
2156  * Parses @data, and fills the @pps structure.
2157  *
2158  * Returns: a #GstH265ParserResult
2159  */
2160 GstH265ParserResult
2161 gst_h265_parser_parse_pps (GstH265Parser * parser,
2162     GstH265NalUnit * nalu, GstH265PPS * pps)
2163 {
2164   GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
2165   if (res == GST_H265_PARSER_OK) {
2166     GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
2167
2168     parser->pps[pps->id] = *pps;
2169     parser->last_pps = &parser->pps[pps->id];
2170   }
2171
2172   return res;
2173 }
2174
2175 /**
2176  * gst_h265_parser_parse_slice_hdr:
2177  * @parser: a #GstH265Parser
2178  * @nalu: The `GST_H265_NAL_SLICE` #GstH265NalUnit to parse
2179  * @slice: The #GstH265SliceHdr to fill.
2180  *
2181  * Parses @data, and fills the @slice structure.
2182  * The resulting @slice_hdr structure shall be deallocated with
2183  * gst_h265_slice_hdr_free() when it is no longer needed
2184  *
2185  * Returns: a #GstH265ParserResult
2186  */
2187 GstH265ParserResult
2188 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
2189     GstH265NalUnit * nalu, GstH265SliceHdr * slice)
2190 {
2191   NalReader nr;
2192   gint pps_id;
2193   GstH265PPS *pps;
2194   GstH265SPS *sps;
2195   guint i;
2196   GstH265ShortTermRefPicSet *stRPS = NULL;
2197   guint32 UsedByCurrPicLt[16];
2198   guint32 PicSizeInCtbsY;
2199   gint NumPocTotalCurr = 0;
2200
2201   memset (slice, 0, sizeof (*slice));
2202
2203   if (!nalu->size) {
2204     GST_DEBUG ("Invalid Nal Unit");
2205     return GST_H265_PARSER_ERROR;
2206   }
2207
2208   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2209       nalu->size - nalu->header_bytes);
2210
2211   GST_DEBUG ("parsing \"Slice header\", slice type");
2212
2213   READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
2214
2215   if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP
2216       && nalu->type <= RESERVED_IRAP_NAL_TYPE_MAX)
2217     READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
2218
2219   READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
2220   pps = gst_h265_parser_get_pps (parser, pps_id);
2221   if (!pps) {
2222     GST_WARNING
2223         ("couldn't find associated picture parameter set with id: %d", pps_id);
2224     return GST_H265_PARSER_BROKEN_LINK;
2225   }
2226
2227   slice->pps = pps;
2228   sps = pps->sps;
2229   if (!sps) {
2230     GST_WARNING
2231         ("couldn't find associated sequence parameter set with id: %d",
2232         pps->id);
2233     return GST_H265_PARSER_BROKEN_LINK;
2234   }
2235
2236   PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
2237   /* set default values for fields that might not be present in the bitstream
2238    * and have valid defaults */
2239   slice->pic_output_flag = 1;
2240   slice->collocated_from_l0_flag = 1;
2241   slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
2242   slice->beta_offset_div2 = pps->beta_offset_div2;
2243   slice->tc_offset_div2 = pps->tc_offset_div2;
2244   slice->loop_filter_across_slices_enabled_flag =
2245       pps->loop_filter_across_slices_enabled_flag;
2246
2247   if (!slice->first_slice_segment_in_pic_flag) {
2248     const guint n = ceil_log2 (PicSizeInCtbsY);
2249
2250     if (pps->dependent_slice_segments_enabled_flag)
2251       READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
2252     /* sice_segment_address parsing */
2253     READ_UINT32 (&nr, slice->segment_address, n);
2254   }
2255
2256   if (!slice->dependent_slice_segment_flag) {
2257     for (i = 0; i < pps->num_extra_slice_header_bits; i++)
2258       nal_reader_skip (&nr, 1);
2259     READ_UE_MAX (&nr, slice->type, 63);
2260
2261
2262     if (pps->output_flag_present_flag)
2263       READ_UINT8 (&nr, slice->pic_output_flag, 1);
2264     if (sps->separate_colour_plane_flag == 1)
2265       READ_UINT8 (&nr, slice->colour_plane_id, 2);
2266
2267     if ((nalu->type != GST_H265_NAL_SLICE_IDR_W_RADL)
2268         && (nalu->type != GST_H265_NAL_SLICE_IDR_N_LP)) {
2269       READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
2270           (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2271
2272       READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
2273       if (!slice->short_term_ref_pic_set_sps_flag) {
2274         guint pos = nal_reader_get_pos (&nr);
2275         if (!gst_h265_parser_parse_short_term_ref_pic_sets
2276             (&slice->short_term_ref_pic_sets, &nr,
2277                 sps->num_short_term_ref_pic_sets, sps))
2278           goto error;
2279
2280         slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
2281       } else if (sps->num_short_term_ref_pic_sets > 1) {
2282         const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
2283         READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
2284         CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
2285             sps->num_short_term_ref_pic_sets - 1);
2286       }
2287
2288       if (sps->long_term_ref_pics_present_flag) {
2289         guint32 limit;
2290
2291         if (sps->num_long_term_ref_pics_sps > 0)
2292           READ_UE_MAX (&nr, slice->num_long_term_sps,
2293               sps->num_long_term_ref_pics_sps);
2294
2295         READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2296         limit = slice->num_long_term_sps + slice->num_long_term_pics;
2297         for (i = 0; i < limit; i++) {
2298           if (i < slice->num_long_term_sps) {
2299             if (sps->num_long_term_ref_pics_sps > 1) {
2300               const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2301               READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2302             }
2303           } else {
2304             READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2305                 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2306             READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2307           }
2308
2309           /* calculate UsedByCurrPicLt */
2310           if (i < slice->num_long_term_sps)
2311             UsedByCurrPicLt[i] =
2312                 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2313           else
2314             UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2315           READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2316           if (slice->delta_poc_msb_present_flag[i])
2317             READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2318         }
2319       }
2320       if (sps->temporal_mvp_enabled_flag)
2321         READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2322     }
2323
2324     if (sps->sample_adaptive_offset_enabled_flag) {
2325       READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2326       READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2327     }
2328
2329     if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2330       READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2331
2332       if (slice->num_ref_idx_active_override_flag) {
2333         READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2334         if (GST_H265_IS_B_SLICE (slice))
2335           READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2336       } else {
2337         /*set default values */
2338         slice->num_ref_idx_l0_active_minus1 =
2339             pps->num_ref_idx_l0_default_active_minus1;
2340         slice->num_ref_idx_l1_active_minus1 =
2341             pps->num_ref_idx_l1_default_active_minus1;
2342       }
2343
2344       /* calculate NumPocTotalCurr */
2345       if (slice->short_term_ref_pic_set_sps_flag)
2346         stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2347       else
2348         stRPS = &slice->short_term_ref_pic_sets;
2349
2350       for (i = 0; i < stRPS->NumNegativePics; i++)
2351         if (stRPS->UsedByCurrPicS0[i])
2352           NumPocTotalCurr++;
2353       for (i = 0; i < stRPS->NumPositivePics; i++)
2354         if (stRPS->UsedByCurrPicS1[i])
2355           NumPocTotalCurr++;
2356       for (i = 0;
2357           i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2358         if (UsedByCurrPicLt[i])
2359           NumPocTotalCurr++;
2360       slice->NumPocTotalCurr = NumPocTotalCurr;
2361
2362       if (pps->lists_modification_present_flag) {
2363         if (NumPocTotalCurr > 1)
2364           if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2365                   NumPocTotalCurr))
2366             goto error;
2367       }
2368
2369       if (GST_H265_IS_B_SLICE (slice))
2370         READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2371       if (pps->cabac_init_present_flag)
2372         READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2373       if (slice->temporal_mvp_enabled_flag) {
2374         if (GST_H265_IS_B_SLICE (slice))
2375           READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2376
2377         if ((slice->collocated_from_l0_flag
2378                 && slice->num_ref_idx_l0_active_minus1 > 0)
2379             || (!slice->collocated_from_l0_flag
2380                 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2381
2382           /*fixme: add optimization */
2383           if ((GST_H265_IS_P_SLICE (slice))
2384               || ((GST_H265_IS_B_SLICE (slice))
2385                   && (slice->collocated_from_l0_flag))) {
2386             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2387                 slice->num_ref_idx_l0_active_minus1);
2388           } else if ((GST_H265_IS_B_SLICE (slice))
2389               && (!slice->collocated_from_l0_flag)) {
2390             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2391                 slice->num_ref_idx_l1_active_minus1);
2392           }
2393         }
2394       }
2395       if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2396           (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2397         if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2398           goto error;
2399       READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2400     }
2401
2402     READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2403     if (pps->slice_chroma_qp_offsets_present_flag) {
2404       READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2405       READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2406     }
2407
2408     if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag)
2409       READ_UINT8 (&nr, slice->cu_chroma_qp_offset_enabled_flag, 1);
2410
2411     if (pps->deblocking_filter_override_enabled_flag)
2412       READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2413     if (slice->deblocking_filter_override_flag) {
2414       READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2415       if (!slice->deblocking_filter_disabled_flag) {
2416         READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2417         READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2418       }
2419     }
2420
2421     if (pps->loop_filter_across_slices_enabled_flag &&
2422         (slice->sao_luma_flag || slice->sao_chroma_flag ||
2423             !slice->deblocking_filter_disabled_flag))
2424       READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2425   }
2426
2427   if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2428     guint32 offset_max;
2429
2430     if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2431       offset_max = pps->PicHeightInCtbsY - 1;
2432     else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2433       offset_max =
2434           (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2435           1;
2436     else
2437       offset_max =
2438           (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2439
2440     READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2441     if (slice->num_entry_point_offsets > 0) {
2442       READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2443       slice->entry_point_offset_minus1 =
2444           g_new0 (guint32, slice->num_entry_point_offsets);
2445       for (i = 0; i < slice->num_entry_point_offsets; i++)
2446         READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2447             (slice->offset_len_minus1 + 1));
2448     }
2449   }
2450
2451   if (pps->slice_segment_header_extension_present_flag) {
2452     guint16 slice_segment_header_extension_length;
2453     READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2454     for (i = 0; i < slice_segment_header_extension_length; i++)
2455       if (!nal_reader_skip (&nr, 8))
2456         goto error;
2457   }
2458
2459   /* Skip the byte alignment bits */
2460   if (!nal_reader_skip (&nr, 1))
2461     goto error;
2462   while (!nal_reader_is_byte_aligned (&nr)) {
2463     if (!nal_reader_skip (&nr, 1))
2464       goto error;
2465   }
2466
2467   slice->header_size = nal_reader_get_pos (&nr);
2468   slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2469
2470   return GST_H265_PARSER_OK;
2471
2472 error:
2473   GST_WARNING ("error parsing \"Slice header\"");
2474
2475   gst_h265_slice_hdr_free (slice);
2476
2477   return GST_H265_PARSER_ERROR;
2478 }
2479
2480 static GstH265ParserResult
2481 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2482     guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2483 {
2484   guint32 payloadSizeBytes;
2485   guint8 payload_type_byte, payload_size_byte;
2486   guint32 remaining, payload_size_bits, next;
2487   GstH265ParserResult res = GST_H265_PARSER_OK;
2488
2489   GST_DEBUG ("parsing \"SEI message\" %u bits available",
2490       nal_reader_get_remaining (nr));
2491
2492   memset (sei, 0, sizeof (*sei));
2493
2494   do {
2495     READ_UINT8 (nr, payload_type_byte, 8);
2496     sei->payloadType += payload_type_byte;
2497   } while (payload_type_byte == 0xff);
2498   payloadSizeBytes = 0;
2499   do {
2500     READ_UINT8 (nr, payload_size_byte, 8);
2501     payloadSizeBytes += payload_size_byte;
2502   }
2503   while (payload_size_byte == 0xff);
2504
2505   remaining = nal_reader_get_remaining (nr);
2506   payload_size_bits =
2507       payloadSizeBytes * 8 < remaining ? payloadSizeBytes * 8 : remaining;
2508   next = nal_reader_get_pos (nr) + payload_size_bits;
2509
2510   GST_DEBUG
2511       ("SEI message received: payloadType  %u, payloadSize = %u bits",
2512       sei->payloadType, payload_size_bits);
2513
2514   if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2515     switch (sei->payloadType) {
2516       case GST_H265_SEI_BUF_PERIOD:
2517         /* size not set; might depend on emulation_prevention_three_byte */
2518         res = gst_h265_parser_parse_buffering_period (parser,
2519             &sei->payload.buffering_period, nr);
2520         break;
2521       case GST_H265_SEI_PIC_TIMING:
2522         /* size not set; might depend on emulation_prevention_three_byte */
2523         res = gst_h265_parser_parse_pic_timing (parser,
2524             &sei->payload.pic_timing, nr);
2525         break;
2526       case GST_H265_SEI_REGISTERED_USER_DATA:
2527         res = gst_h265_parser_parse_registered_user_data (parser,
2528             &sei->payload.registered_user_data, nr, payloadSizeBytes);
2529         break;
2530       case GST_H265_SEI_RECOVERY_POINT:
2531         res = gst_h265_parser_parse_recovery_point (parser,
2532             &sei->payload.recovery_point, nr);
2533         break;
2534       case GST_H265_SEI_TIME_CODE:
2535         res = gst_h265_parser_parse_time_code (parser,
2536             &sei->payload.time_code, nr);
2537         break;
2538       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
2539         res = gst_h265_parser_parse_mastering_display_colour_volume (parser,
2540             &sei->payload.mastering_display_colour_volume, nr);
2541         break;
2542       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
2543         res = gst_h265_parser_parse_content_light_level_info (parser,
2544             &sei->payload.content_light_level, nr);
2545         break;
2546       default:
2547         /* Just consume payloadSize bytes, which does not account for
2548            emulation prevention bytes */
2549         if (!nal_reader_skip_long (nr, payload_size_bits))
2550           goto error;
2551         res = GST_H265_PARSER_OK;
2552         break;
2553     }
2554   } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2555     switch (sei->payloadType) {
2556       default:
2557         /* Just consume payloadSize bytes, which does not account for
2558            emulation prevention bytes */
2559         if (!nal_reader_skip_long (nr, payload_size_bits))
2560           goto error;
2561         res = GST_H265_PARSER_OK;
2562         break;
2563     }
2564   }
2565
2566   /* Not parsing the reserved_payload_extension, but it shouldn't be
2567    * an issue because of 1: There shall not be any reserved_payload_extension
2568    * present in bitstreams conforming to the specification.2. Even though
2569    * it is present, the size will be less than total PayloadSize since the
2570    * size of reserved_payload_extension is supposed to be
2571    * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2572    * the current implementation will still skip all unnecessary bits correctly. */
2573
2574   /* Always make sure all the advertised SEI bits
2575    * were consumed during parsing. This is sufficient to skip to the next
2576    * byte aligned position after the SEI payload because we start
2577    * at a byte-aligned position and calculate the 'next' position as a
2578    * multiple of 8 bits, and this correctly skips any three-byte emulation
2579    * bytes encountered without getting confused. */
2580   if (next > nal_reader_get_pos (nr)) {
2581     GST_LOG ("Skipping %u unused SEI bits", next - nal_reader_get_pos (nr));
2582     if (!nal_reader_skip_long (nr, next - nal_reader_get_pos (nr)))
2583       goto error;
2584   }
2585
2586   return res;
2587
2588 error:
2589   GST_WARNING ("error parsing \"Sei message\"");
2590   return GST_H265_PARSER_ERROR;
2591 }
2592
2593 /**
2594  * gst_h265_slice_hdr_copy:
2595  * @dst_slice: The destination #GstH265SliceHdr to copy into
2596  * @src_slice: The source #GstH265SliceHdr to copy from
2597  *
2598  * Copies @src_slice into @dst_slice
2599  *
2600  * Returns: %TRUE if everything went fine, %FALSE otherwise
2601  */
2602 gboolean
2603 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2604     const GstH265SliceHdr * src_slice)
2605 {
2606   guint i;
2607
2608   g_return_val_if_fail (dst_slice != NULL, FALSE);
2609   g_return_val_if_fail (src_slice != NULL, FALSE);
2610
2611   gst_h265_slice_hdr_free (dst_slice);
2612
2613   *dst_slice = *src_slice;
2614
2615   if (dst_slice->num_entry_point_offsets > 0) {
2616     dst_slice->entry_point_offset_minus1 =
2617         g_new0 (guint32, dst_slice->num_entry_point_offsets);
2618     for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2619       dst_slice->entry_point_offset_minus1[i] =
2620           src_slice->entry_point_offset_minus1[i];
2621   }
2622
2623   return TRUE;
2624 }
2625
2626 /**
2627  * gst_h265_slice_hdr_free:
2628  * slice_hdr: The #GstH265SliceHdr to free
2629  *
2630  * Frees @slice_hdr fields.
2631  */
2632 void
2633 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2634 {
2635   g_return_if_fail (slice_hdr != NULL);
2636
2637   if (slice_hdr->num_entry_point_offsets > 0)
2638     g_free (slice_hdr->entry_point_offset_minus1);
2639   slice_hdr->entry_point_offset_minus1 = 0;
2640 }
2641
2642 /**
2643  * gst_h265_sei_copy:
2644  * @dst_sei: The destination #GstH265SEIMessage to copy into
2645  * @src_sei: The source #GstH265SEIMessage to copy from
2646  *
2647  * Copies @src_sei into @dst_sei
2648  *
2649  * Returns: %TRUE if everything went fine, %FALSE otherwise
2650  */
2651 gboolean
2652 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2653     const GstH265SEIMessage * src_sei)
2654 {
2655   guint i;
2656
2657   g_return_val_if_fail (dst_sei != NULL, FALSE);
2658   g_return_val_if_fail (src_sei != NULL, FALSE);
2659
2660   gst_h265_sei_free (dst_sei);
2661
2662   *dst_sei = *src_sei;
2663
2664   if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2665     GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2666     const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2667
2668     if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2669       dst_pic_timing->num_nalus_in_du_minus1 =
2670           g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2671       dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2672           g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2673
2674       for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2675         dst_pic_timing->num_nalus_in_du_minus1[i] =
2676             src_pic_timing->num_nalus_in_du_minus1[i];
2677         dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2678             src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2679       }
2680     }
2681   }
2682
2683   return TRUE;
2684 }
2685
2686 /**
2687  * gst_h265_sei_free:
2688  * sei: The #GstH265SEIMessage to free
2689  *
2690  * Frees @sei fields.
2691  */
2692 void
2693 gst_h265_sei_free (GstH265SEIMessage * sei)
2694 {
2695   g_return_if_fail (sei != NULL);
2696
2697   if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2698     GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2699     if (pic_timing->num_decoding_units_minus1 > 0) {
2700       g_free (pic_timing->num_nalus_in_du_minus1);
2701       g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2702     }
2703     pic_timing->num_nalus_in_du_minus1 = 0;
2704     pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2705   }
2706 }
2707
2708 /**
2709  * gst_h265_parser_parse_sei:
2710  * @nalparser: a #GstH265Parser
2711  * @nalu: The `GST_H265_NAL_*_SEI` #GstH265NalUnit to parse
2712  * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2713  *
2714  * Parses @data, create and fills the @messages array.
2715  *
2716  * Returns: a #GstH265ParserResult
2717  */
2718 GstH265ParserResult
2719 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2720     GArray ** messages)
2721 {
2722   NalReader nr;
2723   GstH265SEIMessage sei;
2724   GstH265ParserResult res;
2725
2726   GST_DEBUG ("parsing SEI nal");
2727   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2728       nalu->size - nalu->header_bytes);
2729   *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
2730   g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
2731
2732   do {
2733     res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
2734     if (res == GST_H265_PARSER_OK)
2735       g_array_append_val (*messages, sei);
2736     else
2737       break;
2738   } while (nal_reader_has_more_data (&nr));
2739
2740   return res;
2741 }
2742
2743
2744 /**
2745  * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
2746  * @out_quant: (out): The resulting quantization matrix
2747  * @quant: The source quantization matrix
2748  *
2749  * Converts quantization matrix @quant from raster scan order to
2750  * zigzag scan order and store the resulting factors into @out_quant.
2751  *
2752  * Note: it is an error to pass the same table in both @quant and
2753  * @out_quant arguments.
2754  *
2755  * Since: 1.6
2756  */
2757 void
2758 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
2759     const guint8 quant[16])
2760 {
2761   guint i;
2762
2763   g_return_if_fail (out_quant != quant);
2764
2765   for (i = 0; i < 16; i++)
2766     out_quant[i] = quant[zigzag_4x4[i]];
2767 }
2768
2769 /**
2770  * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
2771  * @out_quant: (out): The resulting quantization matrix
2772  * @quant: The source quantization matrix
2773  *
2774  * Converts quantization matrix @quant from zigzag scan order to
2775  * raster scan order and store the resulting factors into @out_quant.
2776  *
2777  * Note: it is an error to pass the same table in both @quant and
2778  * @out_quant arguments.
2779  *
2780  * Since: 1.6
2781  */
2782 void
2783 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
2784     const guint8 quant[16])
2785 {
2786   guint i;
2787
2788   g_return_if_fail (out_quant != quant);
2789
2790   for (i = 0; i < 16; i++)
2791     out_quant[zigzag_4x4[i]] = quant[i];
2792 }
2793
2794 /**
2795  * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
2796  * @out_quant: (out): The resulting quantization matrix
2797  * @quant: The source quantization matrix
2798  *
2799  * Converts quantization matrix @quant from raster scan order to
2800  * zigzag scan order and store the resulting factors into @out_quant.
2801  *
2802  * Note: it is an error to pass the same table in both @quant and
2803  * @out_quant arguments.
2804  *
2805  * Since: 1.6
2806  */
2807 void
2808 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
2809     const guint8 quant[64])
2810 {
2811   guint i;
2812
2813   g_return_if_fail (out_quant != quant);
2814
2815   for (i = 0; i < 64; i++)
2816     out_quant[i] = quant[zigzag_8x8[i]];
2817 }
2818
2819 /**
2820  * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
2821  * @out_quant: (out): The resulting quantization matrix
2822  * @quant: The source quantization matrix
2823  *
2824  * Converts quantization matrix @quant from zigzag scan order to
2825  * raster scan order and store the resulting factors into @out_quant.
2826  *
2827  * Note: it is an error to pass the same table in both @quant and
2828  * @out_quant arguments.
2829  *
2830  * Since: 1.6
2831  */
2832 void
2833 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
2834     const guint8 quant[64])
2835 {
2836   guint i;
2837
2838   g_return_if_fail (out_quant != quant);
2839
2840   for (i = 0; i < 64; i++)
2841     out_quant[zigzag_8x8[i]] = quant[i];
2842 }
2843
2844 /**
2845  * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
2846  * @out_quant: (out): The resulting quantization matrix
2847  * @quant: The source quantization matrix
2848  *
2849  * Converts quantization matrix @quant from raster scan order to
2850  * uprightdiagonal scan order and store the resulting factors
2851  * into @out_quant.
2852  *
2853  * Note: it is an error to pass the same table in both @quant and
2854  * @out_quant arguments.
2855  *
2856  * Since: 1.6
2857  */
2858 void
2859 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
2860     const guint8 quant[16])
2861 {
2862   guint i;
2863
2864   g_return_if_fail (out_quant != quant);
2865
2866   for (i = 0; i < 16; i++)
2867     out_quant[i] = quant[uprightdiagonal_4x4[i]];
2868 }
2869
2870 /**
2871  * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
2872  * @out_quant: (out): The resulting quantization matrix
2873  * @quant: The source quantization matrix
2874  *
2875  * Converts quantization matrix @quant from uprightdiagonal scan order to
2876  * raster scan order and store the resulting factors into @out_quant.
2877  *
2878  * Note: it is an error to pass the same table in both @quant and
2879  * @out_quant arguments.
2880  *
2881  * Since: 1.6
2882  */
2883 void
2884 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
2885     const guint8 quant[16])
2886 {
2887   guint i;
2888
2889   g_return_if_fail (out_quant != quant);
2890
2891   for (i = 0; i < 16; i++)
2892     out_quant[uprightdiagonal_4x4[i]] = quant[i];
2893 }
2894
2895 /**
2896  * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
2897  * @out_quant: (out): The resulting quantization matrix
2898  * @quant: The source quantization matrix
2899  *
2900  * Converts quantization matrix @quant from raster scan order to
2901  * uprightdiagonal scan order and store the resulting factors
2902  * into @out_quant.
2903  *
2904  * Note: it is an error to pass the same table in both @quant and
2905  * @out_quant arguments.
2906  *
2907  * Since: 1.6
2908  */
2909 void
2910 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
2911     const guint8 quant[64])
2912 {
2913   guint i;
2914
2915   g_return_if_fail (out_quant != quant);
2916
2917   for (i = 0; i < 64; i++)
2918     out_quant[i] = quant[uprightdiagonal_8x8[i]];
2919 }
2920
2921 /**
2922  * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
2923  * @out_quant: (out): The resulting quantization matrix
2924  * @quant: The source quantization matrix
2925  *
2926  * Converts quantization matrix @quant from uprightdiagonal scan order to
2927  * raster scan order and store the resulting factors into @out_quant.
2928  *
2929  * Note: it is an error to pass the same table in both @quant and
2930  * @out_quant arguments.
2931  *
2932  * Since: 1.6
2933  */
2934 void
2935 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
2936     const guint8 quant[64])
2937 {
2938   guint i;
2939
2940   g_return_if_fail (out_quant != quant);
2941
2942   for (i = 0; i < 64; i++)
2943     out_quant[uprightdiagonal_8x8[i]] = quant[i];
2944 }
2945
2946 typedef struct
2947 {
2948   GstH265Profile profile;
2949   GstH265ProfileIDC profile_idc;
2950
2951   guint8 max_14bit_constraint_flag;
2952   guint8 max_12bit_constraint_flag;
2953   guint8 max_10bit_constraint_flag;
2954   guint8 max_8bit_constraint_flag;
2955   guint8 max_422chroma_constraint_flag;
2956   guint8 max_420chroma_constraint_flag;
2957   guint8 max_monochrome_constraint_flag;
2958   guint8 intra_constraint_flag;
2959   guint8 one_picture_only_constraint_flag;
2960   gboolean lower_bit_rate_constraint_flag_set;
2961
2962   /* Tie breaker if more than one profiles are matching */
2963   guint priority;
2964 } FormatRangeExtensionProfile;
2965
2966 typedef struct
2967 {
2968   FormatRangeExtensionProfile *profile;
2969   guint extra_constraints;
2970 } FormatRangeExtensionProfileMatch;
2971
2972 static gint
2973 sort_fre_profile_matches (FormatRangeExtensionProfileMatch * a,
2974     FormatRangeExtensionProfileMatch * b)
2975 {
2976   gint d;
2977
2978   d = a->extra_constraints - b->extra_constraints;
2979   if (d)
2980     return d;
2981
2982   return b->profile->priority - a->profile->priority;
2983 }
2984
2985 static GstH265Profile
2986 get_format_range_extension_profile (GstH265ProfileTierLevel * ptl)
2987 {
2988   /* See Table A.2 for the definition of those formats */
2989   FormatRangeExtensionProfile profiles[] = {
2990     {GST_H265_PROFILE_MONOCHROME, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
2991         0, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
2992     {GST_H265_PROFILE_MONOCHROME_10,
2993           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
2994         0, 1, 1, 0, 1, 1, 1, 0, 0, TRUE, 1},
2995     {GST_H265_PROFILE_MONOCHROME_12,
2996           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
2997         0, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
2998     {GST_H265_PROFILE_MONOCHROME_16,
2999           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3000         0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 3},
3001     {GST_H265_PROFILE_MAIN_12, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3002         0, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 4},
3003     {GST_H265_PROFILE_MAIN_422_10, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3004         0, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 5},
3005     {GST_H265_PROFILE_MAIN_422_12, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3006         0, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 6},
3007     {GST_H265_PROFILE_MAIN_444, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3008         0, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 7},
3009     {GST_H265_PROFILE_MAIN_444_10, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3010         0, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 8},
3011     {GST_H265_PROFILE_MAIN_444_12, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3012         0, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 9},
3013     {GST_H265_PROFILE_MAIN_INTRA, GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3014         0, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 10},
3015     {GST_H265_PROFILE_MAIN_10_INTRA,
3016           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3017         0, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 11},
3018     {GST_H265_PROFILE_MAIN_12_INTRA,
3019           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3020         0, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 12},
3021     {GST_H265_PROFILE_MAIN_422_10_INTRA,
3022           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3023         0, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 13},
3024     {GST_H265_PROFILE_MAIN_422_12_INTRA,
3025           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3026         0, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 14},
3027     {GST_H265_PROFILE_MAIN_444_INTRA,
3028           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3029         0, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 15},
3030     {GST_H265_PROFILE_MAIN_444_10_INTRA,
3031           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3032         0, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 16},
3033     {GST_H265_PROFILE_MAIN_444_12_INTRA,
3034           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3035         0, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
3036     {GST_H265_PROFILE_MAIN_444_16_INTRA,
3037           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3038         0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 18},
3039     {GST_H265_PROFILE_MAIN_444_STILL_PICTURE,
3040           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3041         0, 1, 1, 1, 0, 0, 0, 1, 1, FALSE, 19},
3042     {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE,
3043           GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3044         0, 0, 0, 0, 0, 0, 0, 1, 1, FALSE, 20},
3045
3046     /* High Througput */
3047     {GST_H265_PROFILE_HIGH_THROUGHPUT_444, GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3048         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 21},
3049     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10,
3050           GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3051         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 22},
3052     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14,
3053           GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3054         1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 23},
3055     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
3056           GST_H265_PROFILE_IDC_HIGH_THROUGHPUT,
3057         0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 24},
3058
3059     /* Screen content coding */
3060     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN,
3061           GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3062         1, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 25},
3063     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10,
3064           GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3065         1, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 26},
3066     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
3067           GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3068         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 27},
3069     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10,
3070           GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3071         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 28},
3072     /* identical to screen-extended-main-444 */
3073     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
3074           GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3075         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 29},
3076     /* identical to screen-extended-main-444-10 */
3077     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
3078           GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3079         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 30},
3080     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
3081           GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3082         1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 31},
3083
3084     /* Multiview Main */
3085     {GST_H265_PROFILE_MULTIVIEW_MAIN, GST_H265_PROFILE_IDC_MULTIVIEW_MAIN,
3086         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 32},
3087
3088     /* Scalable Main */
3089     {GST_H265_PROFILE_SCALABLE_MAIN, GST_H265_PROFILE_IDC_SCALABLE_MAIN,
3090         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 33},
3091     {GST_H265_PROFILE_SCALABLE_MAIN_10, GST_H265_PROFILE_IDC_SCALABLE_MAIN,
3092         0, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 34},
3093
3094     /* Scalable format range extensions */
3095     {GST_H265_PROFILE_SCALABLE_MONOCHROME,
3096           GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3097         1, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 35},
3098     {GST_H265_PROFILE_SCALABLE_MONOCHROME_12,
3099           GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3100         1, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 36},
3101     {GST_H265_PROFILE_SCALABLE_MONOCHROME_16,
3102           GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3103         0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 37},
3104     {GST_H265_PROFILE_SCALABLE_MAIN_444,
3105           GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3106         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 38},
3107
3108     /* 3D Main */
3109     {GST_H265_PROFILE_3D_MAIN, GST_H265_PROFILE_IDC_3D_MAIN,
3110         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 39},
3111   };
3112   GstH265Profile result = GST_H265_PROFILE_INVALID;
3113   guint i;
3114   GList *matches = NULL;
3115
3116   for (i = 0; i < G_N_ELEMENTS (profiles); i++) {
3117     FormatRangeExtensionProfile p = profiles[i];
3118     guint extra_constraints = 0;
3119     FormatRangeExtensionProfileMatch *m;
3120
3121     /* Filter out all the profiles having constraints not satisfied by @ptl.
3122      * Then pick the one having the least extra constraints. This allow us
3123      * to match the closet profile if bitstream contains not standard
3124      * constraints. */
3125     if (p.max_14bit_constraint_flag != ptl->max_14bit_constraint_flag) {
3126       if (p.max_14bit_constraint_flag)
3127         continue;
3128       extra_constraints++;
3129     }
3130
3131     if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
3132       if (p.max_12bit_constraint_flag)
3133         continue;
3134       extra_constraints++;
3135     }
3136
3137     if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
3138       if (p.max_10bit_constraint_flag)
3139         continue;
3140       extra_constraints++;
3141     }
3142
3143     if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
3144       if (p.max_8bit_constraint_flag)
3145         continue;
3146       extra_constraints++;
3147     }
3148
3149     if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
3150       if (p.max_422chroma_constraint_flag)
3151         continue;
3152       extra_constraints++;
3153     }
3154
3155     if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
3156       if (p.max_420chroma_constraint_flag)
3157         continue;
3158       extra_constraints++;
3159     }
3160
3161     if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
3162       if (p.max_monochrome_constraint_flag)
3163         continue;
3164       extra_constraints++;
3165     }
3166
3167     if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
3168       if (p.intra_constraint_flag)
3169         continue;
3170       extra_constraints++;
3171     }
3172
3173     if (p.one_picture_only_constraint_flag !=
3174         ptl->one_picture_only_constraint_flag) {
3175       if (p.one_picture_only_constraint_flag)
3176         continue;
3177       extra_constraints++;
3178     }
3179
3180     if (p.lower_bit_rate_constraint_flag_set
3181         && !ptl->lower_bit_rate_constraint_flag)
3182       continue;
3183
3184     if (extra_constraints == 0 &&
3185         (p.profile_idc == ptl->profile_idc
3186             || ptl->profile_compatibility_flag[ptl->profile_idc])) {
3187       result = p.profile;
3188       break;
3189     }
3190
3191     m = g_new0 (FormatRangeExtensionProfileMatch, 1);
3192     m->profile = &profiles[i];
3193     m->extra_constraints = extra_constraints;
3194     matches = g_list_prepend (matches, m);
3195   }
3196
3197   if (result == GST_H265_PROFILE_INVALID && matches) {
3198     FormatRangeExtensionProfileMatch *m;
3199
3200     matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
3201     m = matches->data;
3202     result = m->profile->profile;
3203   }
3204
3205   if (matches)
3206     g_list_free_full (matches, g_free);
3207
3208   return result;
3209 }
3210
3211 /**
3212  * gst_h265_profile_tier_level_get_profile:
3213  * @ptl: a #GstH265ProfileTierLevel
3214  *
3215  * Return the H265 profile defined in @ptl.
3216  *
3217  * Returns: a #GstH265Profile
3218  * Since: 1.14
3219  */
3220 GstH265Profile
3221 gst_h265_profile_tier_level_get_profile (GstH265ProfileTierLevel * ptl)
3222 {
3223   if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN
3224       || ptl->profile_compatibility_flag[1])
3225     return GST_H265_PROFILE_MAIN;
3226
3227   if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_10
3228       || ptl->profile_compatibility_flag[2])
3229     return GST_H265_PROFILE_MAIN_10;
3230
3231   if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE
3232       || ptl->profile_compatibility_flag[3])
3233     return GST_H265_PROFILE_MAIN_STILL_PICTURE;
3234
3235   return get_format_range_extension_profile (ptl);
3236 }