cf7f71f5d9c1ca875422a59b94065ee4a0b097ae
[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 || nalu->size == 2)
1230     goto beach;
1231
1232   off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1233   if (off2 < 0) {
1234     GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1235
1236     return GST_H265_PARSER_NO_NAL_END;
1237   }
1238
1239   /* Mini performance improvement:
1240    * We could have a way to store how many 0s were skipped to avoid
1241    * parsing them again on the next NAL */
1242   while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1243     off2--;
1244
1245   nalu->size = off2;
1246   if (nalu->size < 3)
1247     return GST_H265_PARSER_BROKEN_DATA;
1248
1249   GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1250
1251 beach:
1252   return res;
1253 }
1254
1255 /**
1256  * gst_h265_parser_identify_nalu_hevc:
1257  * @parser: a #GstH265Parser
1258  * @data: The data to parse, must be the beging of the Nal unit
1259  * @offset: the offset from which to parse @data
1260  * @size: the size of @data
1261  * @nal_length_size: the size in bytes of the HEVC nal length prefix.
1262  * @nalu: The #GstH265NalUnit where to store parsed nal headers
1263  *
1264  * Parses @data and sets @nalu.
1265  *
1266  * Returns: a #GstH265ParserResult
1267  */
1268 GstH265ParserResult
1269 gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
1270     const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1271     GstH265NalUnit * nalu)
1272 {
1273   GstBitReader br;
1274
1275   memset (nalu, 0, sizeof (*nalu));
1276
1277   if (size < offset + nal_length_size) {
1278     GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1279         ", offset %u", size, offset);
1280     return GST_H265_PARSER_ERROR;
1281   }
1282
1283   size = size - offset;
1284   gst_bit_reader_init (&br, data + offset, size);
1285
1286   nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1287       nal_length_size * 8);
1288   nalu->sc_offset = offset;
1289   nalu->offset = offset + nal_length_size;
1290
1291   if (size < nalu->size + nal_length_size) {
1292     nalu->size = 0;
1293
1294     return GST_H265_PARSER_NO_NAL_END;
1295   }
1296
1297   nalu->data = (guint8 *) data;
1298
1299   if (!gst_h265_parse_nalu_header (nalu)) {
1300     GST_WARNING ("error parsing \"NAL unit header\"");
1301     nalu->size = 0;
1302     return GST_H265_PARSER_BROKEN_DATA;
1303   }
1304
1305   if (nalu->size < 2)
1306     return GST_H265_PARSER_BROKEN_DATA;
1307
1308   nalu->valid = TRUE;
1309
1310   return GST_H265_PARSER_OK;
1311 }
1312
1313 /**
1314  * gst_h265_parser_parse_nal:
1315  * @parser: a #GstH265Parser
1316  * @nalu: The #GstH265NalUnit to parse
1317  *
1318  * This function should be called in the case one doesn't need to
1319  * parse a specific structure. It is necessary to do so to make
1320  * sure @parser is up to date.
1321  *
1322  * Returns: a #GstH265ParserResult
1323  */
1324 GstH265ParserResult
1325 gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
1326 {
1327   GstH265VPS vps;
1328   GstH265SPS sps;
1329   GstH265PPS pps;
1330
1331   switch (nalu->type) {
1332     case GST_H265_NAL_VPS:
1333       return gst_h265_parser_parse_vps (parser, nalu, &vps);
1334       break;
1335     case GST_H265_NAL_SPS:
1336       return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
1337       break;
1338     case GST_H265_NAL_PPS:
1339       return gst_h265_parser_parse_pps (parser, nalu, &pps);
1340   }
1341
1342   return GST_H265_PARSER_OK;
1343 }
1344
1345 /**
1346  * gst_h265_parser_parse_vps:
1347  * @parser: a #GstH265Parser
1348  * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1349  * @vps: The #GstH265VPS to fill.
1350  *
1351  * Parses @data, and fills the @vps structure.
1352  *
1353  * Returns: a #GstH265ParserResult
1354  */
1355 GstH265ParserResult
1356 gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
1357     GstH265VPS * vps)
1358 {
1359   GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);
1360
1361   if (res == GST_H265_PARSER_OK) {
1362     GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);
1363
1364     parser->vps[vps->id] = *vps;
1365     parser->last_vps = &parser->vps[vps->id];
1366   }
1367
1368   return res;
1369 }
1370
1371 /**
1372  * gst_h265_parse_vps:
1373  * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1374  * @sps: The #GstH265VPS to fill.
1375  *
1376  * Parses @data, and fills the @vps structure.
1377  *
1378  * Returns: a #GstH265ParserResult
1379  */
1380 GstH265ParserResult
1381 gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
1382 {
1383   NalReader nr;
1384   guint i, j;
1385
1386   INITIALIZE_DEBUG_CATEGORY;
1387   GST_DEBUG ("parsing VPS");
1388
1389   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1390       nalu->size - nalu->header_bytes);
1391
1392   memset (vps, 0, sizeof (*vps));
1393
1394   vps->cprms_present_flag = 1;
1395
1396   READ_UINT8 (&nr, vps->id, 4);
1397
1398   /* skip reserved_three_2bits */
1399   if (!nal_reader_skip (&nr, 2))
1400     goto error;
1401
1402   READ_UINT8 (&nr, vps->max_layers_minus1, 6);
1403   READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
1404   READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1405
1406   /* skip reserved_0xffff_16bits */
1407   if (!nal_reader_skip (&nr, 16))
1408     goto error;
1409
1410   if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1411           vps->max_sub_layers_minus1))
1412     goto error;
1413
1414   READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1415
1416   for (i =
1417       (vps->sub_layer_ordering_info_present_flag ? 0 :
1418           vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1419     READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1420     READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1421         vps->max_dec_pic_buffering_minus1[i]);
1422     READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1423   }
1424   /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1425   if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1426     for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1427       vps->max_dec_pic_buffering_minus1[i] =
1428           vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1429       vps->max_num_reorder_pics[i] =
1430           vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1431       vps->max_latency_increase_plus1[i] =
1432           vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1433     }
1434   }
1435
1436   READ_UINT8 (&nr, vps->max_layer_id, 6);
1437   CHECK_ALLOWED_MAX (vps->max_layer_id, 0);
1438
1439   READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1440   CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 0);
1441
1442   for (i = 1; i <= vps->num_layer_sets_minus1; i++)
1443     for (j = 0; j <= vps->max_layer_id; j++)
1444       nal_reader_skip (&nr, 1);
1445
1446   READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1447
1448   if (vps->timing_info_present_flag) {
1449     READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1450     READ_UINT32 (&nr, vps->time_scale, 32);
1451     READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1452
1453     if (vps->poc_proportional_to_timing_flag)
1454       READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1455
1456     READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1457     CHECK_ALLOWED_MAX (vps->num_hrd_parameters, 1);
1458
1459     if (vps->num_hrd_parameters) {
1460       READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1461       CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, 0);
1462
1463       if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1464               vps->cprms_present_flag, vps->max_sub_layers_minus1))
1465         goto error;
1466     }
1467   }
1468   READ_UINT8 (&nr, vps->vps_extension, 1);
1469   vps->valid = TRUE;
1470
1471   return GST_H265_PARSER_OK;
1472
1473 error:
1474   GST_WARNING ("error parsing \"Video parameter set\"");
1475   vps->valid = FALSE;
1476   return GST_H265_PARSER_ERROR;
1477 }
1478
1479 /**
1480  * gst_h265_parser_parse_sps:
1481  * @parser: a #GstH265Parser
1482  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1483  * @sps: The #GstH265SPS to fill.
1484  * @parse_vui_params: Whether to parse the vui_params or not
1485  *
1486  * Parses @data, and fills the @sps structure.
1487  *
1488  * Returns: a #GstH265ParserResult
1489  */
1490 GstH265ParserResult
1491 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1492     GstH265SPS * sps, gboolean parse_vui_params)
1493 {
1494   GstH265ParserResult res =
1495       gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1496
1497   if (res == GST_H265_PARSER_OK) {
1498     GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1499
1500     parser->sps[sps->id] = *sps;
1501     parser->last_sps = &parser->sps[sps->id];
1502   }
1503
1504   return res;
1505 }
1506
1507 /**
1508  * gst_h265_parse_sps:
1509  * parser: The #GstH265Parser
1510  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1511  * @sps: The #GstH265SPS to fill.
1512  * @parse_vui_params: Whether to parse the vui_params or not
1513  *
1514  * Parses @data, and fills the @sps structure.
1515  *
1516  * Returns: a #GstH265ParserResult
1517  */
1518 GstH265ParserResult
1519 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1520     GstH265SPS * sps, gboolean parse_vui_params)
1521 {
1522   NalReader nr;
1523   GstH265VPS *vps;
1524   guint8 vps_id;
1525   guint i;
1526   guint subwc[] = { 1, 2, 2, 1, 1 };
1527   guint subhc[] = { 1, 2, 1, 1, 1 };
1528   GstH265VUIParams *vui = NULL;
1529
1530   INITIALIZE_DEBUG_CATEGORY;
1531   GST_DEBUG ("parsing SPS");
1532
1533   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1534       nalu->size - nalu->header_bytes);
1535
1536   memset (sps, 0, sizeof (*sps));
1537
1538   READ_UINT8 (&nr, vps_id, 4);
1539   vps = gst_h265_parser_get_vps (parser, vps_id);
1540   if (!vps) {
1541     GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1542         vps_id);
1543   }
1544   sps->vps = vps;
1545
1546   READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1547   READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1548
1549   if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1550           sps->max_sub_layers_minus1))
1551     goto error;
1552
1553   READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1554
1555   READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1556   if (sps->chroma_format_idc == 3)
1557     READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1558
1559   READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1560   READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1561
1562   READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1563   if (sps->conformance_window_flag) {
1564     READ_UE (&nr, sps->conf_win_left_offset);
1565     READ_UE (&nr, sps->conf_win_right_offset);
1566     READ_UE (&nr, sps->conf_win_top_offset);
1567     READ_UE (&nr, sps->conf_win_bottom_offset);
1568   }
1569
1570   READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1571   READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1572   READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1573
1574   READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1575   for (i =
1576       (sps->sub_layer_ordering_info_present_flag ? 0 :
1577           sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1578     READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1579     READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1580         sps->max_dec_pic_buffering_minus1[i]);
1581     READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1582   }
1583   /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1584   if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1585     for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1586       sps->max_dec_pic_buffering_minus1[i] =
1587           sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1588       sps->max_num_reorder_pics[i] =
1589           sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1590       sps->max_latency_increase_plus1[i] =
1591           sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1592     }
1593   }
1594
1595   /* The limits are calculted based on the profile_tier_level constraint
1596    * in Annex-A: CtbLog2SizeY = 4 to 6 */
1597   READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1598   READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1599   READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1600   READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1601   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1602   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1603
1604   READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1605   if (sps->scaling_list_enabled_flag) {
1606     READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1607
1608     if (sps->scaling_list_data_present_flag)
1609       if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1610         goto error;
1611   }
1612
1613   READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1614   READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1615   READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1616
1617   if (sps->pcm_enabled_flag) {
1618     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1619     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1620     READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1621     READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1622     READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1623   }
1624
1625   READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1626   for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1627     if (!gst_h265_parser_parse_short_term_ref_pic_sets
1628         (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1629       goto error;
1630
1631   READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1632   if (sps->long_term_ref_pics_present_flag) {
1633     READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1634     for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1635       READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1636           sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1637       READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1638     }
1639   }
1640
1641   READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1642   READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1643   READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1644
1645   if (sps->vui_parameters_present_flag && parse_vui_params) {
1646     if (!gst_h265_parse_vui_parameters (sps, &nr))
1647       goto error;
1648     vui = &sps->vui_params;
1649   }
1650
1651   READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1652
1653   /* calculate ChromaArrayType */
1654   if (!sps->separate_colour_plane_flag)
1655     sps->chroma_array_type = sps->chroma_format_idc;
1656
1657   /* Calculate  width and height */
1658   sps->width = sps->pic_width_in_luma_samples;
1659   sps->height = sps->pic_height_in_luma_samples;
1660   if (sps->width < 0 || sps->height < 0) {
1661     GST_WARNING ("invalid width/height in SPS");
1662     goto error;
1663   }
1664
1665   if (sps->conformance_window_flag) {
1666     const guint crop_unit_x = subwc[sps->chroma_format_idc];
1667     const guint crop_unit_y = subhc[sps->chroma_format_idc];
1668
1669     sps->crop_rect_width = sps->width -
1670         (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
1671     sps->crop_rect_height = sps->height -
1672         (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
1673     sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
1674     sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
1675
1676     GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
1677         sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
1678   }
1679
1680   sps->fps_num = 0;
1681   sps->fps_den = 1;
1682
1683   if (vui && vui->timing_info_present_flag) {
1684     /* derive framerate for progressive stream if the pic_struct
1685      * syntax element is not present in picture timing SEI messages */
1686     /* Fixme: handle other cases also */
1687     if (parse_vui_params && vui->timing_info_present_flag
1688         && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
1689       sps->fps_num = vui->time_scale;
1690       sps->fps_den = vui->num_units_in_tick;
1691       GST_LOG ("framerate %d/%d", sps->fps_num, sps->fps_den);
1692     }
1693   } else {
1694     GST_LOG ("No VUI, unknown framerate");
1695   }
1696
1697   sps->valid = TRUE;
1698
1699   return GST_H265_PARSER_OK;
1700
1701 error:
1702   GST_WARNING ("error parsing \"Sequence parameter set\"");
1703   sps->valid = FALSE;
1704   return GST_H265_PARSER_ERROR;
1705 }
1706
1707 /**
1708  * gst_h265_parse_pps:
1709  * @parser: a #GstH265Parser
1710  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1711  * @pps: The #GstH265PPS to fill.
1712  *
1713  * Parses @data, and fills the @pps structure.
1714  *
1715  * Returns: a #GstH265ParserResult
1716  */
1717 GstH265ParserResult
1718 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
1719     GstH265PPS * pps)
1720 {
1721   NalReader nr;
1722   GstH265SPS *sps;
1723   gint sps_id;
1724   gint qp_bd_offset;
1725   guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY;
1726   guint8 i;
1727
1728   INITIALIZE_DEBUG_CATEGORY;
1729   GST_DEBUG ("parsing PPS");
1730
1731   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1732       nalu->size - nalu->header_bytes);
1733
1734   memset (pps, 0, sizeof (*pps));
1735
1736   READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
1737   READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
1738
1739   sps = gst_h265_parser_get_sps (parser, sps_id);
1740   if (!sps) {
1741     GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
1742         sps_id);
1743     return GST_H265_PARSER_BROKEN_LINK;
1744   }
1745   pps->sps = sps;
1746   qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
1747
1748   MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
1749   CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
1750   CtbSizeY = 1 << CtbLog2SizeY;
1751   pps->PicHeightInCtbsY =
1752       ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
1753   pps->PicWidthInCtbsY =
1754       ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
1755
1756   /* set default values for fields that might not be present in the bitstream
1757      and have valid defaults */
1758   pps->uniform_spacing_flag = 1;
1759   pps->loop_filter_across_tiles_enabled_flag = 1;
1760
1761   READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
1762   READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
1763   READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
1764   READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
1765   READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
1766
1767   READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
1768   READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
1769   READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
1770
1771   READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
1772   READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
1773
1774   READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
1775   if (pps->cu_qp_delta_enabled_flag)
1776     READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
1777         sps->log2_diff_max_min_luma_coding_block_size);
1778
1779   READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
1780   READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
1781
1782   READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
1783   READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
1784   READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
1785   READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
1786   READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
1787   READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
1788
1789   if (pps->tiles_enabled_flag) {
1790     READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 0, 19);
1791     READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 0, 21);
1792
1793     READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
1794     /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
1795     if (pps->uniform_spacing_flag) {
1796       guint8 num_col = pps->num_tile_columns_minus1 + 1;
1797       guint8 num_row = pps->num_tile_rows_minus1 + 1;
1798       for (i = 0; i < num_col; i++) {
1799         pps->column_width_minus1[i] =
1800             ((i + 1) * pps->PicWidthInCtbsY / num_col
1801             - i * pps->PicWidthInCtbsY / num_col) - 1;
1802       }
1803       for (i = 0; i < num_row; i++) {
1804         pps->row_height_minus1[i] =
1805             ((i + 1) * pps->PicHeightInCtbsY / num_row
1806             - i * pps->PicHeightInCtbsY / num_row) - 1;
1807       }
1808     } else {
1809       pps->column_width_minus1[pps->num_tile_columns_minus1] =
1810           pps->PicWidthInCtbsY - 1;
1811       for (i = 0; i < pps->num_tile_columns_minus1; i++) {
1812         READ_UE (&nr, pps->column_width_minus1[i]);
1813         pps->column_width_minus1[pps->num_tile_columns_minus1] -=
1814             (pps->column_width_minus1[i] + 1);
1815       }
1816
1817       pps->row_height_minus1[pps->num_tile_rows_minus1] =
1818           pps->PicHeightInCtbsY - 1;
1819       for (i = 0; i < pps->num_tile_rows_minus1; i++) {
1820         READ_UE (&nr, pps->row_height_minus1[i]);
1821         pps->row_height_minus1[pps->num_tile_rows_minus1] -=
1822             (pps->row_height_minus1[i] + 1);
1823       }
1824     }
1825     READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
1826   }
1827
1828   READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
1829
1830   READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
1831   if (pps->deblocking_filter_control_present_flag) {
1832     READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
1833
1834     READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
1835     if (!pps->deblocking_filter_disabled_flag) {
1836       READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
1837       READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
1838     }
1839   }
1840
1841   READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
1842   if (pps->scaling_list_data_present_flag)
1843     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
1844       goto error;
1845   if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
1846       && !pps->scaling_list_data_present_flag)
1847     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
1848       goto error;
1849
1850   READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
1851   READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
1852   READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
1853   READ_UINT8 (&nr, pps->pps_extension_flag, 1);
1854
1855   pps->valid = TRUE;
1856   return GST_H265_PARSER_OK;
1857
1858 error:
1859   GST_WARNING ("error parsing \"Picture parameter set\"");
1860   pps->valid = FALSE;
1861   return GST_H265_PARSER_ERROR;
1862 }
1863
1864 /**
1865  * gst_h265_parser_parse_pps:
1866  * @parser: a #GstH265Parser
1867  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
1868  * @pps: The #GstH265PPS to fill.
1869  *
1870  * Parses @data, and fills the @pps structure.
1871  *
1872  * Returns: a #GstH265ParserResult
1873  */
1874 GstH265ParserResult
1875 gst_h265_parser_parse_pps (GstH265Parser * parser,
1876     GstH265NalUnit * nalu, GstH265PPS * pps)
1877 {
1878   GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
1879   if (res == GST_H265_PARSER_OK) {
1880     GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
1881
1882     parser->pps[pps->id] = *pps;
1883     parser->last_pps = &parser->pps[pps->id];
1884   }
1885
1886   return res;
1887 }
1888
1889 /**
1890  * gst_h265_parser_parse_slice_hdr:
1891  * @parser: a #GstH265Parser
1892  * @nalu: The #GST_H265_NAL_SLICE #GstH265NalUnit to parse
1893  * @slice: The #GstH265SliceHdr to fill.
1894  *
1895  * Parses @data, and fills the @slice structure.
1896  * The resulting @slice_hdr structure shall be deallocated with
1897  * gst_h265_slice_hdr_free() when it is no longer needed
1898  *
1899  * Returns: a #GstH265ParserResult
1900  */
1901 GstH265ParserResult
1902 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
1903     GstH265NalUnit * nalu, GstH265SliceHdr * slice)
1904 {
1905   NalReader nr;
1906   gint pps_id;
1907   GstH265PPS *pps;
1908   GstH265SPS *sps;
1909   guint i;
1910   GstH265ShortTermRefPicSet *stRPS = NULL;
1911   guint32 UsedByCurrPicLt[16];
1912   guint32 PicSizeInCtbsY;
1913   gint NumPocTotalCurr = 0;
1914
1915   memset (slice, 0, sizeof (*slice));
1916
1917   if (!nalu->size) {
1918     GST_DEBUG ("Invalid Nal Unit");
1919     return GST_H265_PARSER_ERROR;
1920   }
1921
1922   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1923       nalu->size - nalu->header_bytes);
1924
1925   GST_DEBUG ("parsing \"Slice header\", slice type");
1926
1927   READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
1928
1929   if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP
1930       && nalu->type <= RESERVED_IRAP_NAL_TYPE_MAX)
1931     READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
1932
1933   READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
1934   pps = gst_h265_parser_get_pps (parser, pps_id);
1935   if (!pps) {
1936     GST_WARNING
1937         ("couldn't find associated picture parameter set with id: %d", pps_id);
1938     return GST_H265_PARSER_BROKEN_LINK;
1939   }
1940
1941   slice->pps = pps;
1942   sps = pps->sps;
1943   if (!sps) {
1944     GST_WARNING
1945         ("couldn't find associated sequence parameter set with id: %d",
1946         pps->id);
1947     return GST_H265_PARSER_BROKEN_LINK;
1948   }
1949
1950   PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
1951   /* set default values for fields that might not be present in the bitstream
1952    * and have valid defaults */
1953   slice->pic_output_flag = 1;
1954   slice->collocated_from_l0_flag = 1;
1955   slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
1956   slice->beta_offset_div2 = pps->beta_offset_div2;
1957   slice->tc_offset_div2 = pps->tc_offset_div2;
1958   slice->loop_filter_across_slices_enabled_flag =
1959       pps->loop_filter_across_slices_enabled_flag;
1960
1961   if (!slice->first_slice_segment_in_pic_flag) {
1962     const guint n = ceil_log2 (PicSizeInCtbsY);
1963
1964     if (pps->dependent_slice_segments_enabled_flag)
1965       READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
1966     /* sice_segment_address parsing */
1967     READ_UINT32 (&nr, slice->segment_address, n);
1968   }
1969
1970   if (!slice->dependent_slice_segment_flag) {
1971     for (i = 0; i < pps->num_extra_slice_header_bits; i++)
1972       nal_reader_skip (&nr, 1);
1973     READ_UE_MAX (&nr, slice->type, 63);
1974
1975
1976     if (pps->output_flag_present_flag)
1977       READ_UINT8 (&nr, slice->pic_output_flag, 1);
1978     if (sps->separate_colour_plane_flag == 1)
1979       READ_UINT8 (&nr, slice->colour_plane_id, 2);
1980
1981     if ((nalu->type != GST_H265_NAL_SLICE_IDR_W_RADL)
1982         && (nalu->type != GST_H265_NAL_SLICE_IDR_N_LP)) {
1983       READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
1984           (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
1985
1986       READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
1987       if (!slice->short_term_ref_pic_set_sps_flag) {
1988         if (!gst_h265_parser_parse_short_term_ref_pic_sets
1989             (&slice->short_term_ref_pic_sets, &nr,
1990                 sps->num_short_term_ref_pic_sets, sps))
1991           goto error;
1992       } else if (sps->num_short_term_ref_pic_sets > 1) {
1993         const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
1994         READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
1995         CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
1996             sps->num_short_term_ref_pic_sets - 1);
1997       }
1998
1999       if (sps->long_term_ref_pics_present_flag) {
2000         guint32 limit;
2001
2002         if (sps->num_long_term_ref_pics_sps > 0)
2003           READ_UE_MAX (&nr, slice->num_long_term_sps,
2004               sps->num_long_term_ref_pics_sps);
2005
2006         READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2007         limit = slice->num_long_term_sps + slice->num_long_term_pics;
2008         for (i = 0; i < limit; i++) {
2009           if (i < slice->num_long_term_sps) {
2010             if (sps->num_long_term_ref_pics_sps > 1) {
2011               const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2012               READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2013             }
2014           } else {
2015             READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2016                 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2017             READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2018           }
2019
2020           /* calculate UsedByCurrPicLt */
2021           if (i < slice->num_long_term_sps)
2022             UsedByCurrPicLt[i] =
2023                 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2024           else
2025             UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2026           READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2027           if (slice->delta_poc_msb_present_flag[i])
2028             READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2029         }
2030       }
2031       if (sps->temporal_mvp_enabled_flag)
2032         READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2033     }
2034
2035     if (sps->sample_adaptive_offset_enabled_flag) {
2036       READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2037       READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2038     }
2039
2040     if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2041       READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2042
2043       if (slice->num_ref_idx_active_override_flag) {
2044         READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2045         if (GST_H265_IS_B_SLICE (slice))
2046           READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2047       } else {
2048         /*set default values */
2049         slice->num_ref_idx_l0_active_minus1 =
2050             pps->num_ref_idx_l0_default_active_minus1;
2051         slice->num_ref_idx_l1_active_minus1 =
2052             pps->num_ref_idx_l1_default_active_minus1;
2053       }
2054
2055       /* calculate NumPocTotalCurr */
2056       if (slice->short_term_ref_pic_set_sps_flag)
2057         stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2058       else
2059         stRPS = &slice->short_term_ref_pic_sets;
2060
2061       for (i = 0; i < stRPS->NumNegativePics; i++)
2062         if (stRPS->UsedByCurrPicS0[i])
2063           NumPocTotalCurr++;
2064       for (i = 0; i < stRPS->NumPositivePics; i++)
2065         if (stRPS->UsedByCurrPicS1[i])
2066           NumPocTotalCurr++;
2067       for (i = 0;
2068           i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2069         if (UsedByCurrPicLt[i])
2070           NumPocTotalCurr++;
2071       slice->NumPocTotalCurr = NumPocTotalCurr;
2072
2073       if (pps->lists_modification_present_flag) {
2074         if (NumPocTotalCurr > 1)
2075           if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2076                   NumPocTotalCurr))
2077             goto error;
2078       }
2079
2080       if (GST_H265_IS_B_SLICE (slice))
2081         READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2082       if (pps->cabac_init_present_flag)
2083         READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2084       if (slice->temporal_mvp_enabled_flag) {
2085         if (GST_H265_IS_B_SLICE (slice))
2086           READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2087
2088         if ((slice->collocated_from_l0_flag
2089                 && slice->num_ref_idx_l0_active_minus1 > 0)
2090             || (!slice->collocated_from_l0_flag
2091                 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2092
2093           /*fixme: add optimization */
2094           if ((GST_H265_IS_P_SLICE (slice))
2095               || ((GST_H265_IS_B_SLICE (slice))
2096                   && (slice->collocated_from_l0_flag))) {
2097             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2098                 slice->num_ref_idx_l0_active_minus1);
2099           } else if ((GST_H265_IS_B_SLICE (slice))
2100               && (!slice->collocated_from_l0_flag)) {
2101             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2102                 slice->num_ref_idx_l1_active_minus1);
2103           }
2104         }
2105       }
2106       if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2107           (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2108         if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2109           goto error;
2110       READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2111     }
2112
2113     READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2114     if (pps->slice_chroma_qp_offsets_present_flag) {
2115       READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2116       READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2117     }
2118
2119     if (pps->deblocking_filter_override_enabled_flag)
2120       READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2121     if (slice->deblocking_filter_override_flag) {
2122       READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2123       if (!slice->deblocking_filter_disabled_flag) {
2124         READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2125         READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2126       }
2127     }
2128
2129     if (pps->loop_filter_across_slices_enabled_flag &&
2130         (slice->sao_luma_flag || slice->sao_chroma_flag ||
2131             !slice->deblocking_filter_disabled_flag))
2132       READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2133   }
2134
2135   if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2136     guint32 offset_max;
2137
2138     if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2139       offset_max = pps->PicHeightInCtbsY - 1;
2140     else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2141       offset_max =
2142           (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2143           1;
2144     else
2145       offset_max =
2146           (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2147
2148     READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2149     if (slice->num_entry_point_offsets > 0) {
2150       READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2151       slice->entry_point_offset_minus1 =
2152           g_new0 (guint32, slice->num_entry_point_offsets);
2153       for (i = 0; i < slice->num_entry_point_offsets; i++)
2154         READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2155             (slice->offset_len_minus1 + 1));
2156     }
2157   }
2158
2159   if (pps->slice_segment_header_extension_present_flag) {
2160     guint16 slice_segment_header_extension_length;
2161     READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2162     for (i = 0; i < slice_segment_header_extension_length; i++)
2163       if (!nal_reader_skip (&nr, 8))
2164         goto error;
2165   }
2166
2167   /* Skip the byte alignment bits */
2168   if (!nal_reader_skip (&nr, 1))
2169     goto error;
2170   while (!nal_reader_is_byte_aligned (&nr)) {
2171     if (!nal_reader_skip (&nr, 1))
2172       goto error;
2173   }
2174
2175   slice->header_size = nal_reader_get_pos (&nr);
2176   slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2177
2178   return GST_H265_PARSER_OK;
2179
2180 error:
2181   GST_WARNING ("error parsing \"Slice header\"");
2182
2183   gst_h265_slice_hdr_free (slice);
2184
2185   return GST_H265_PARSER_ERROR;
2186 }
2187
2188 static gboolean
2189 nal_reader_has_more_data_in_payload (NalReader * nr,
2190     guint32 payload_start_pos_bit, guint32 payloadSize)
2191 {
2192   if (nal_reader_is_byte_aligned (nr) &&
2193       (nal_reader_get_pos (nr) == (payload_start_pos_bit + 8 * payloadSize)))
2194     return FALSE;
2195
2196   return TRUE;
2197 }
2198
2199 static GstH265ParserResult
2200 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2201     guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2202 {
2203   guint32 payloadSize;
2204   guint8 payload_type_byte, payload_size_byte;
2205   guint remaining, payload_size;
2206   guint32 payload_start_pos_bit;
2207   GstH265ParserResult res = GST_H265_PARSER_OK;
2208
2209   GST_DEBUG ("parsing \"Sei message\"");
2210
2211   memset (sei, 0, sizeof (*sei));
2212
2213   do {
2214     READ_UINT8 (nr, payload_type_byte, 8);
2215     sei->payloadType += payload_type_byte;
2216   } while (payload_type_byte == 0xff);
2217   payloadSize = 0;
2218   do {
2219     READ_UINT8 (nr, payload_size_byte, 8);
2220     payloadSize += payload_size_byte;
2221   }
2222   while (payload_size_byte == 0xff);
2223
2224   remaining = nal_reader_get_remaining (nr);
2225   payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
2226
2227   payload_start_pos_bit = nal_reader_get_pos (nr);
2228   GST_DEBUG
2229       ("SEI message received: payloadType  %u, payloadSize = %u bytes",
2230       sei->payloadType, payload_size);
2231
2232   if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2233     switch (sei->payloadType) {
2234       case GST_H265_SEI_BUF_PERIOD:
2235         /* size not set; might depend on emulation_prevention_three_byte */
2236         res = gst_h265_parser_parse_buffering_period (parser,
2237             &sei->payload.buffering_period, nr);
2238         break;
2239       case GST_H265_SEI_PIC_TIMING:
2240         /* size not set; might depend on emulation_prevention_three_byte */
2241         res = gst_h265_parser_parse_pic_timing (parser,
2242             &sei->payload.pic_timing, nr);
2243         break;
2244       default:
2245         /* Just consume payloadSize bytes, which does not account for
2246            emulation prevention bytes */
2247         if (!nal_reader_skip_long (nr, payload_size))
2248           goto error;
2249         res = GST_H265_PARSER_OK;
2250         break;
2251     }
2252   } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2253     switch (sei->payloadType) {
2254       default:
2255         /* Just consume payloadSize bytes, which does not account for
2256            emulation prevention bytes */
2257         if (!nal_reader_skip_long (nr, payload_size))
2258           goto error;
2259         res = GST_H265_PARSER_OK;
2260         break;
2261     }
2262   }
2263
2264   /* Not parsing the reserved_payload_extension, but it shouldn't be
2265    * an issue because of 1: There shall not be any reserved_payload_extension
2266    * present in bitstreams conforming to the specification.2. Even though
2267    * it is present, the size will be less than total PayloadSize since the
2268    * size of reserved_payload_extension is supposed to be
2269    * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2270    * the current implementation will still skip all unnecessary bits correctly.
2271    * In theory, we can have a more optimized implementation by skipping the
2272    * data left in PayLoadSize without out individually checking for each bits,
2273    * since the totoal size will be always less than payloadSize*/
2274   if (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
2275           payloadSize)) {
2276     /* Skip the byte alignment bits */
2277     if (!nal_reader_skip (nr, 1))
2278       goto error;
2279     while (!nal_reader_is_byte_aligned (nr)) {
2280       if (!nal_reader_skip (nr, 1))
2281         goto error;
2282     }
2283   }
2284
2285   return res;
2286
2287 error:
2288   GST_WARNING ("error parsing \"Sei message\"");
2289   return GST_H265_PARSER_ERROR;
2290 }
2291
2292 /**
2293  * gst_h265_slice_hdr_copy:
2294  * @dst_slice: The destination #GstH265SliceHdr to copy into
2295  * @src_slice: The source #GstH265SliceHdr to copy from
2296  *
2297  * Copies @src_slice into @dst_slice
2298  *
2299  * Returns: %TRUE if everything went fine, %FALSE otherwise
2300  */
2301 gboolean
2302 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2303     const GstH265SliceHdr * src_slice)
2304 {
2305   guint i;
2306
2307   g_return_val_if_fail (dst_slice != NULL, FALSE);
2308   g_return_val_if_fail (src_slice != NULL, FALSE);
2309
2310   gst_h265_slice_hdr_free (dst_slice);
2311
2312   *dst_slice = *src_slice;
2313
2314   if (dst_slice->num_entry_point_offsets > 0) {
2315     dst_slice->entry_point_offset_minus1 =
2316         g_new0 (guint32, dst_slice->num_entry_point_offsets);
2317     for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2318       dst_slice->entry_point_offset_minus1[i] =
2319           src_slice->entry_point_offset_minus1[i];
2320   }
2321
2322   return TRUE;
2323 }
2324
2325 /**
2326  * gst_h265_slice_hdr_free:
2327  * slice_hdr: The #GstH265SliceHdr to free
2328  *
2329  * Frees @slice_hdr fields.
2330  */
2331 void
2332 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2333 {
2334   g_return_if_fail (slice_hdr != NULL);
2335
2336   if (slice_hdr->num_entry_point_offsets > 0)
2337     g_free (slice_hdr->entry_point_offset_minus1);
2338   slice_hdr->entry_point_offset_minus1 = 0;
2339 }
2340
2341 /**
2342  * gst_h265_sei_copy:
2343  * @dst_sei: The destination #GstH265SEIMessage to copy into
2344  * @src_sei: The source #GstH265SEIMessage to copy from
2345  *
2346  * Copies @src_sei into @dst_sei
2347  *
2348  * Returns: %TRUE if everything went fine, %FALSE otherwise
2349  */
2350 gboolean
2351 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2352     const GstH265SEIMessage * src_sei)
2353 {
2354   guint i;
2355
2356   g_return_val_if_fail (dst_sei != NULL, FALSE);
2357   g_return_val_if_fail (src_sei != NULL, FALSE);
2358
2359   gst_h265_sei_free (dst_sei);
2360
2361   *dst_sei = *src_sei;
2362
2363   if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2364     GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2365     const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2366
2367     if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2368       dst_pic_timing->num_nalus_in_du_minus1 =
2369           g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2370       dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2371           g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2372
2373       for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2374         dst_pic_timing->num_nalus_in_du_minus1[i] =
2375             src_pic_timing->num_nalus_in_du_minus1[i];
2376         dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2377             src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2378       }
2379     }
2380   }
2381
2382   return TRUE;
2383 }
2384
2385 /**
2386  * gst_h265_sei_free:
2387  * sei: The #GstH265SEIMessage to free
2388  *
2389  * Frees @sei fields.
2390  */
2391 void
2392 gst_h265_sei_free (GstH265SEIMessage * sei)
2393 {
2394   g_return_if_fail (sei != NULL);
2395
2396   if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2397     GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2398     if (pic_timing->num_decoding_units_minus1 > 0) {
2399       g_free (pic_timing->num_nalus_in_du_minus1);
2400       g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2401     }
2402     pic_timing->num_nalus_in_du_minus1 = 0;
2403     pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2404   }
2405 }
2406
2407 /**
2408  * gst_h265_parser_parse_sei:
2409  * @nalparser: a #GstH265Parser
2410  * @nalu: The #GST_H265_NAL_SEI #GstH265NalUnit to parse
2411  * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2412  *
2413  * Parses @data, create and fills the @messages array.
2414  *
2415  * Returns: a #GstH265ParserResult
2416  */
2417 GstH265ParserResult
2418 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2419     GArray ** messages)
2420 {
2421   NalReader nr;
2422   GstH265SEIMessage sei;
2423   GstH265ParserResult res;
2424
2425   GST_DEBUG ("parsing SEI nal");
2426   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2427       nalu->size - nalu->header_bytes);
2428   *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
2429   g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
2430
2431   do {
2432     res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
2433     if (res == GST_H265_PARSER_OK)
2434       g_array_append_val (*messages, sei);
2435     else
2436       break;
2437   } while (nal_reader_has_more_data (&nr));
2438
2439   return res;
2440 }
2441
2442
2443 /**
2444  * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
2445  * @out_quant: (out): The resulting quantization matrix
2446  * @quant: The source quantization matrix
2447  *
2448  * Converts quantization matrix @quant from raster scan order to
2449  * zigzag scan order and store the resulting factors into @out_quant.
2450  *
2451  * Note: it is an error to pass the same table in both @quant and
2452  * @out_quant arguments.
2453  *
2454  * Since: 1.6
2455  */
2456 void
2457 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
2458     const guint8 quant[16])
2459 {
2460   guint i;
2461
2462   g_return_if_fail (out_quant != quant);
2463
2464   for (i = 0; i < 16; i++)
2465     out_quant[i] = quant[zigzag_4x4[i]];
2466 }
2467
2468 /**
2469  * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
2470  * @out_quant: (out): The resulting quantization matrix
2471  * @quant: The source quantization matrix
2472  *
2473  * Converts quantization matrix @quant from zigzag scan order to
2474  * raster scan order and store the resulting factors into @out_quant.
2475  *
2476  * Note: it is an error to pass the same table in both @quant and
2477  * @out_quant arguments.
2478  *
2479  * Since: 1.6
2480  */
2481 void
2482 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
2483     const guint8 quant[16])
2484 {
2485   guint i;
2486
2487   g_return_if_fail (out_quant != quant);
2488
2489   for (i = 0; i < 16; i++)
2490     out_quant[zigzag_4x4[i]] = quant[i];
2491 }
2492
2493 /**
2494  * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
2495  * @out_quant: (out): The resulting quantization matrix
2496  * @quant: The source quantization matrix
2497  *
2498  * Converts quantization matrix @quant from raster scan order to
2499  * zigzag scan order and store the resulting factors into @out_quant.
2500  *
2501  * Note: it is an error to pass the same table in both @quant and
2502  * @out_quant arguments.
2503  *
2504  * Since: 1.6
2505  */
2506 void
2507 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
2508     const guint8 quant[64])
2509 {
2510   guint i;
2511
2512   g_return_if_fail (out_quant != quant);
2513
2514   for (i = 0; i < 64; i++)
2515     out_quant[i] = quant[zigzag_8x8[i]];
2516 }
2517
2518 /**
2519  * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
2520  * @out_quant: (out): The resulting quantization matrix
2521  * @quant: The source quantization matrix
2522  *
2523  * Converts quantization matrix @quant from zigzag scan order to
2524  * raster scan order and store the resulting factors into @out_quant.
2525  *
2526  * Note: it is an error to pass the same table in both @quant and
2527  * @out_quant arguments.
2528  *
2529  * Since: 1.6
2530  */
2531 void
2532 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
2533     const guint8 quant[64])
2534 {
2535   guint i;
2536
2537   g_return_if_fail (out_quant != quant);
2538
2539   for (i = 0; i < 64; i++)
2540     out_quant[zigzag_8x8[i]] = quant[i];
2541 }
2542
2543 /**
2544  * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
2545  * @out_quant: (out): The resulting quantization matrix
2546  * @quant: The source quantization matrix
2547  *
2548  * Converts quantization matrix @quant from raster scan order to
2549  * uprightdiagonal scan order and store the resulting factors
2550  * into @out_quant.
2551  *
2552  * Note: it is an error to pass the same table in both @quant and
2553  * @out_quant arguments.
2554  *
2555  * Since: 1.6
2556  */
2557 void
2558 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
2559     const guint8 quant[16])
2560 {
2561   guint i;
2562
2563   g_return_if_fail (out_quant != quant);
2564
2565   for (i = 0; i < 16; i++)
2566     out_quant[i] = quant[uprightdiagonal_4x4[i]];
2567 }
2568
2569 /**
2570  * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
2571  * @out_quant: (out): The resulting quantization matrix
2572  * @quant: The source quantization matrix
2573  *
2574  * Converts quantization matrix @quant from uprightdiagonal scan order to
2575  * raster scan order and store the resulting factors into @out_quant.
2576  *
2577  * Note: it is an error to pass the same table in both @quant and
2578  * @out_quant arguments.
2579  *
2580  * Since: 1.6
2581  */
2582 void
2583 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
2584     const guint8 quant[16])
2585 {
2586   guint i;
2587
2588   g_return_if_fail (out_quant != quant);
2589
2590   for (i = 0; i < 16; i++)
2591     out_quant[uprightdiagonal_4x4[i]] = quant[i];
2592 }
2593
2594 /**
2595  * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
2596  * @out_quant: (out): The resulting quantization matrix
2597  * @quant: The source quantization matrix
2598  *
2599  * Converts quantization matrix @quant from raster scan order to
2600  * uprightdiagonal scan order and store the resulting factors
2601  * into @out_quant.
2602  *
2603  * Note: it is an error to pass the same table in both @quant and
2604  * @out_quant arguments.
2605  *
2606  * Since: 1.6
2607  */
2608 void
2609 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
2610     const guint8 quant[64])
2611 {
2612   guint i;
2613
2614   g_return_if_fail (out_quant != quant);
2615
2616   for (i = 0; i < 64; i++)
2617     out_quant[i] = quant[uprightdiagonal_8x8[i]];
2618 }
2619
2620 /**
2621  * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
2622  * @out_quant: (out): The resulting quantization matrix
2623  * @quant: The source quantization matrix
2624  *
2625  * Converts quantization matrix @quant from uprightdiagonal scan order to
2626  * raster scan order and store the resulting factors into @out_quant.
2627  *
2628  * Note: it is an error to pass the same table in both @quant and
2629  * @out_quant arguments.
2630  *
2631  * Since: 1.6
2632  */
2633 void
2634 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
2635     const guint8 quant[64])
2636 {
2637   guint i;
2638
2639   g_return_if_fail (out_quant != quant);
2640
2641   for (i = 0; i < 64; i++)
2642     out_quant[uprightdiagonal_8x8[i]] = quant[i];
2643 }
2644
2645 typedef struct
2646 {
2647   GstH265Profile profile;
2648
2649   guint8 max_12bit_constraint_flag;
2650   guint8 max_10bit_constraint_flag;
2651   guint8 max_8bit_constraint_flag;
2652   guint8 max_422chroma_constraint_flag;
2653   guint8 max_420chroma_constraint_flag;
2654   guint8 max_monochrome_constraint_flag;
2655   guint8 intra_constraint_flag;
2656   guint8 one_picture_only_constraint_flag;
2657   gboolean lower_bit_rate_constraint_flag_set;
2658
2659   /* Tie breaker if more than one profiles are matching */
2660   guint priority;
2661 } FormatRangeExtensionProfile;
2662
2663 typedef struct
2664 {
2665   FormatRangeExtensionProfile *profile;
2666   guint extra_constraints;
2667 } FormatRangeExtensionProfileMatch;
2668
2669 static gint
2670 sort_fre_profile_matches (FormatRangeExtensionProfileMatch * a,
2671     FormatRangeExtensionProfileMatch * b)
2672 {
2673   gint d;
2674
2675   d = a->extra_constraints - b->extra_constraints;
2676   if (d)
2677     return d;
2678
2679   return b->profile->priority - a->profile->priority;
2680 }
2681
2682 static GstH265Profile
2683 get_format_range_extension_profile (GstH265ProfileTierLevel * ptl)
2684 {
2685   /* See Table A.2 for the definition of those formats */
2686   FormatRangeExtensionProfile profiles[] = {
2687     {GST_H265_PROFILE_MONOCHROME, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
2688     {GST_H265_PROFILE_MONOCHROME_12, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 1},
2689     {GST_H265_PROFILE_MONOCHROME_16, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
2690     {GST_H265_PROFILE_MAIN_12, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 3},
2691     {GST_H265_PROFILE_MAIN_422_10, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 4},
2692     {GST_H265_PROFILE_MAIN_422_12, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 5},
2693     {GST_H265_PROFILE_MAIN_444, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 6},
2694     {GST_H265_PROFILE_MAIN_444_10, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 7},
2695     {GST_H265_PROFILE_MAIN_444_12, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 8},
2696     {GST_H265_PROFILE_MAIN_INTRA, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 9},
2697     {GST_H265_PROFILE_MAIN_10_INTRA, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 10},
2698     {GST_H265_PROFILE_MAIN_12_INTRA, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 11},
2699     {GST_H265_PROFILE_MAIN_422_10_INTRA, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 12},
2700     {GST_H265_PROFILE_MAIN_422_12_INTRA, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 13},
2701     {GST_H265_PROFILE_MAIN_444_INTRA, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 14},
2702     {GST_H265_PROFILE_MAIN_444_10_INTRA, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 15},
2703     {GST_H265_PROFILE_MAIN_444_12_INTRA, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 16},
2704     {GST_H265_PROFILE_MAIN_444_16_INTRA, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
2705     {GST_H265_PROFILE_MAIN_444_STILL_PICTURE, 1, 1, 1, 0, 0, 0, 1, 1, FALSE,
2706         18},
2707     {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE, 0, 0, 0, 0, 0, 0, 1, 1, FALSE,
2708         19},
2709   };
2710   GstH265Profile result = GST_H265_PROFILE_INVALID;
2711   guint i;
2712   GList *matches = NULL;
2713
2714   for (i = 0; i < G_N_ELEMENTS (profiles); i++) {
2715     FormatRangeExtensionProfile p = profiles[i];
2716     guint extra_constraints = 0;
2717     FormatRangeExtensionProfileMatch *m;
2718
2719     /* Filter out all the profiles having constraints not satisified by @ptl.
2720      * Then pick the one having the least extra contraints. This allow us
2721      * to match the closet profile if bitstream contains not standard
2722      * constraints. */
2723     if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
2724       if (p.max_12bit_constraint_flag)
2725         continue;
2726       extra_constraints++;
2727     }
2728
2729     if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
2730       if (p.max_10bit_constraint_flag)
2731         continue;
2732       extra_constraints++;
2733     }
2734
2735     if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
2736       if (p.max_8bit_constraint_flag)
2737         continue;
2738       extra_constraints++;
2739     }
2740
2741     if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
2742       if (p.max_422chroma_constraint_flag)
2743         continue;
2744       extra_constraints++;
2745     }
2746
2747     if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
2748       if (p.max_420chroma_constraint_flag)
2749         continue;
2750       extra_constraints++;
2751     }
2752
2753     if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
2754       if (p.max_monochrome_constraint_flag)
2755         continue;
2756       extra_constraints++;
2757     }
2758
2759     if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
2760       if (p.intra_constraint_flag)
2761         continue;
2762       extra_constraints++;
2763     }
2764
2765     if (p.one_picture_only_constraint_flag !=
2766         ptl->one_picture_only_constraint_flag) {
2767       if (p.one_picture_only_constraint_flag)
2768         continue;
2769       extra_constraints++;
2770     }
2771
2772     if (p.lower_bit_rate_constraint_flag_set
2773         && !ptl->lower_bit_rate_constraint_flag)
2774       continue;
2775
2776     m = g_new0 (FormatRangeExtensionProfileMatch, 1);
2777     m->profile = &profiles[i];
2778     m->extra_constraints = extra_constraints;
2779     matches = g_list_prepend (matches, m);
2780   }
2781
2782   if (matches) {
2783     FormatRangeExtensionProfileMatch *m;
2784
2785     matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
2786     m = matches->data;
2787     result = m->profile->profile;
2788     g_list_free_full (matches, g_free);
2789   }
2790
2791   return result;
2792 }
2793
2794 /**
2795  * gst_h265_profile_tier_level_get_profile:
2796  * @ptl: a #GstH265ProfileTierLevel
2797  *
2798  * Return the H265 profile defined in @ptl.
2799  *
2800  * Returns: a #GstH265Profile
2801  * Since: 1.14
2802  */
2803 GstH265Profile
2804 gst_h265_profile_tier_level_get_profile (GstH265ProfileTierLevel * ptl)
2805 {
2806   if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN
2807       || ptl->profile_compatibility_flag[1])
2808     return GST_H265_PROFILE_MAIN;
2809
2810   if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_10
2811       || ptl->profile_compatibility_flag[2])
2812     return GST_H265_PROFILE_MAIN_10;
2813
2814   if (ptl->profile_idc == GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE
2815       || ptl->profile_compatibility_flag[3])
2816     return GST_H265_PROFILE_MAIN_STILL_PICTURE;
2817
2818   if (ptl->profile_idc == GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
2819       || ptl->profile_compatibility_flag[4])
2820     return get_format_range_extension_profile (ptl);
2821
2822   /* TODO:
2823    * - GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
2824    * - GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
2825    */
2826
2827   return GST_H265_PROFILE_INVALID;
2828 }