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