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