• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Gstreamer H.265 bitstream parser
2  * Copyright (C) 2012 Intel Corporation
3  * Copyright (C) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
4  *
5  *  Contact: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 /**
24  * SECTION:gsth265parser
25  * @title: GstH265Parser
26  * @short_description: Convenience library for h265 video bitstream parsing.
27  *
28  * It offers you bitstream parsing in HEVC mode and non-HEVC mode. To identify
29  * Nals in a bitstream and parse its headers, you should call:
30  *
31  *   * gst_h265_parser_identify_nalu() to identify the following nalu in
32  *        non-HEVC bitstreams
33  *
34  *   * gst_h265_parser_identify_nalu_hevc() to identify the nalu in
35  *        HEVC bitstreams
36  *
37  * Then, depending on the #GstH265NalUnitType of the newly parsed #GstH265NalUnit,
38  * you should call the differents functions to parse the structure:
39  *
40  *   * From #GST_H265_NAL_SLICE_TRAIL_N to #GST_H265_NAL_SLICE_CRA_NUT: gst_h265_parser_parse_slice_hdr()
41  *
42  *   * `GST_H265_NAL_*_SEI`: gst_h265_parser_parse_sei()
43  *
44  *   * #GST_H265_NAL_VPS: gst_h265_parser_parse_vps()
45  *
46  *   * #GST_H265_NAL_SPS: gst_h265_parser_parse_sps()
47  *
48  *   * #GST_H265_NAL_PPS: #gst_h265_parser_parse_pps()
49  *
50  *   * Any other: gst_h265_parser_parse_nal()
51  *
52  * Note: You should always call gst_h265_parser_parse_nal() if you don't
53  * actually need #GstH265NalUnitType to be parsed for your personal use, in
54  * order to guarantee that the #GstH265Parser is always up to date.
55  *
56  * For more details about the structures, look at the ITU-T H.265
57  * specifications, you can download them from:
58  *
59  *   * ITU-T H.265: http://www.itu.int/rec/T-REC-H.265
60  *
61  */
62 
63 #ifdef HAVE_CONFIG_H
64 #  include "config.h"
65 #endif
66 
67 #include "nalutils.h"
68 #include "gsth265parser.h"
69 
70 #include <gst/base/gstbytereader.h>
71 #include <gst/base/gstbitreader.h>
72 #include <string.h>
73 #include <math.h>
74 
75 #ifndef GST_DISABLE_GST_DEBUG
76 #define GST_CAT_DEFAULT gst_h265_debug_category_get()
77 static GstDebugCategory *
gst_h265_debug_category_get(void)78 gst_h265_debug_category_get (void)
79 {
80   static gsize cat_gonce = 0;
81 
82   if (g_once_init_enter (&cat_gonce)) {
83     GstDebugCategory *cat = NULL;
84 
85     GST_DEBUG_CATEGORY_INIT (cat, "codecparsers_h265", 0, "h265 parse library");
86 
87     g_once_init_leave (&cat_gonce, (gsize) cat);
88   }
89 
90   return (GstDebugCategory *) cat_gonce;
91 }
92 #endif /* GST_DISABLE_GST_DEBUG */
93 
94 /**** Default scaling_lists according to Table 7-5 and 7-6 *****/
95 
96 /* Table 7-5 */
97 static const guint8 default_scaling_list0[16] = {
98   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
99   16, 16, 16, 16
100 };
101 
102 /*  Combined the values in Table  7-6 to make the calculation easier
103  *  Default scaling list of 8x8 and 16x16 matrices for matrixId = 0, 1 and 2
104  *  Default scaling list of 32x32 matrix for matrixId = 0
105  */
106 static const guint8 default_scaling_list1[64] = {
107   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16,
108   17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20,
109   21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24,
110   25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31,
111   29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70,
112   65, 88, 88, 115
113 };
114 
115 /*  Combined the values in Table 7-6 to make the calculation easier
116  *  Default scaling list of 8x8 and 16x16 matrices for matrixId = 3, 4 and 5
117  *  Default scaling list of 32x32 matrix for matrixId = 1
118  */
119 static const guint8 default_scaling_list2[64] = {
120   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
121   17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20,
122   20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24,
123   25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28,
124   28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54,
125   54, 71, 71, 91
126 };
127 
128 static const guint8 zigzag_4x4[16] = {
129   0, 1, 4, 8,
130   5, 2, 3, 6,
131   9, 12, 13, 10,
132   7, 11, 14, 15,
133 };
134 
135 static const guint8 zigzag_8x8[64] = {
136   0, 1, 8, 16, 9, 2, 3, 10,
137   17, 24, 32, 25, 18, 11, 4, 5,
138   12, 19, 26, 33, 40, 48, 41, 34,
139   27, 20, 13, 6, 7, 14, 21, 28,
140   35, 42, 49, 56, 57, 50, 43, 36,
141   29, 22, 15, 23, 30, 37, 44, 51,
142   58, 59, 52, 45, 38, 31, 39, 46,
143   53, 60, 61, 54, 47, 55, 62, 63
144 };
145 
146 static const guint8 uprightdiagonal_4x4[16] = {
147   0, 4, 1, 8,
148   5, 2, 12, 9,
149   6, 3, 13, 10,
150   7, 14, 11, 15
151 };
152 
153 static const guint8 uprightdiagonal_8x8[64] = {
154   0, 8, 1, 16, 9, 2, 24, 17,
155   10, 3, 32, 25, 18, 11, 4, 40,
156   33, 26, 19, 12, 5, 48, 41, 34,
157   27, 20, 13, 6, 56, 49, 42, 35,
158   28, 21, 14, 7, 57, 50, 43, 36,
159   29, 22, 15, 58, 51, 44, 37, 30,
160   23, 59, 52, 45, 38, 31, 60, 53,
161   46, 39, 61, 54, 47, 62, 55, 63
162 };
163 
164 typedef struct
165 {
166   guint par_n, par_d;
167 } PAR;
168 
169 /* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
170 static const PAR aspect_ratios[17] = {
171   {0, 0},
172   {1, 1},
173   {12, 11},
174   {10, 11},
175   {16, 11},
176   {40, 33},
177   {24, 11},
178   {20, 11},
179   {32, 11},
180   {80, 33},
181   {18, 11},
182   {15, 11},
183   {64, 33},
184   {160, 99},
185   {4, 3},
186   {3, 2},
187   {2, 1}
188 };
189 
190 /*****  Utils ****/
191 #define EXTENDED_SAR 255
192 
193 static GstH265VPS *
gst_h265_parser_get_vps(GstH265Parser * parser,guint8 vps_id)194 gst_h265_parser_get_vps (GstH265Parser * parser, guint8 vps_id)
195 {
196   GstH265VPS *vps;
197 
198   vps = &parser->vps[vps_id];
199 
200   if (vps->valid)
201     return vps;
202 
203   return NULL;
204 }
205 
206 static GstH265SPS *
gst_h265_parser_get_sps(GstH265Parser * parser,guint8 sps_id)207 gst_h265_parser_get_sps (GstH265Parser * parser, guint8 sps_id)
208 {
209   GstH265SPS *sps;
210 
211   sps = &parser->sps[sps_id];
212 
213   if (sps->valid)
214     return sps;
215 
216   return NULL;
217 }
218 
219 static GstH265PPS *
gst_h265_parser_get_pps(GstH265Parser * parser,guint8 pps_id)220 gst_h265_parser_get_pps (GstH265Parser * parser, guint8 pps_id)
221 {
222   GstH265PPS *pps;
223 
224   pps = &parser->pps[pps_id];
225 
226   if (pps->valid)
227     return pps;
228 
229   return NULL;
230 }
231 
232 static gboolean
gst_h265_parse_nalu_header(GstH265NalUnit * nalu)233 gst_h265_parse_nalu_header (GstH265NalUnit * nalu)
234 {
235   guint8 *data = nalu->data + nalu->offset;
236   GstBitReader br;
237 
238   if (nalu->size < 2)
239     return FALSE;
240 
241   gst_bit_reader_init (&br, data, nalu->size - nalu->offset);
242 
243   /* skip the forbidden_zero_bit */
244   gst_bit_reader_skip_unchecked (&br, 1);
245 
246   nalu->type = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
247   nalu->layer_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
248   nalu->temporal_id_plus1 = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
249   nalu->header_bytes = 2;
250 
251   return TRUE;
252 }
253 
254 struct h265_profile_string
255 {
256   GstH265Profile profile;
257   const gchar *name;
258 };
259 
260 static const struct h265_profile_string h265_profiles[] = {
261   /* keep in sync with definition in the header */
262   {GST_H265_PROFILE_MAIN, "main"},
263   {GST_H265_PROFILE_MAIN_10, "main-10"},
264   {GST_H265_PROFILE_MAIN_STILL_PICTURE, "main-still-picture"},
265   {GST_H265_PROFILE_MONOCHROME, "monochrome"},
266   {GST_H265_PROFILE_MONOCHROME_12, "monochrome-12"},
267   {GST_H265_PROFILE_MONOCHROME_16, "monochrome-16"},
268   {GST_H265_PROFILE_MAIN_12, "main-12"},
269   {GST_H265_PROFILE_MAIN_422_10, "main-422-10"},
270   {GST_H265_PROFILE_MAIN_422_12, "main-422-12"},
271   {GST_H265_PROFILE_MAIN_444, "main-444"},
272   {GST_H265_PROFILE_MAIN_444_10, "main-444-10"},
273   {GST_H265_PROFILE_MAIN_444_12, "main-444-12"},
274   {GST_H265_PROFILE_MAIN_INTRA, "main-intra"},
275   {GST_H265_PROFILE_MAIN_10_INTRA, "main-10-intra"},
276   {GST_H265_PROFILE_MAIN_12_INTRA, "main-12-intra"},
277   {GST_H265_PROFILE_MAIN_422_10_INTRA, "main-422-10-intra"},
278   {GST_H265_PROFILE_MAIN_422_12_INTRA, "main-422-12-intra"},
279   {GST_H265_PROFILE_MAIN_444_INTRA, "main-444-intra"},
280   {GST_H265_PROFILE_MAIN_444_10_INTRA, "main-444-10-intra"},
281   {GST_H265_PROFILE_MAIN_444_12_INTRA, "main-444-12-intra"},
282   {GST_H265_PROFILE_MAIN_444_16_INTRA, "main-444-16-intra"},
283   {GST_H265_PROFILE_MAIN_444_STILL_PICTURE, "main-444-still-picture"},
284   {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE, "main-444-16-still-picture"},
285   {GST_H265_PROFILE_MONOCHROME_10, "monochrome-10"},
286   {GST_H265_PROFILE_HIGH_THROUGHPUT_444, "high-throughput-444"},
287   {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10, "high-throughput-444-10"},
288   {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14, "high-throughput-444-14"},
289   {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
290       "high-throughput-444-16-intra"},
291   {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN, "screen-extended-main"},
292   {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10, "screen-extended-main-10"},
293   {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444, "screen-extended-main-444"},
294   {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10, "screen-extended-main-444-10"},
295   {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
296       "screen-extended-high-throughput-444"},
297   {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
298       "screen-extended-high-throughput-444-10"},
299   {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
300       "screen-extended-high-throughput-444-14"},
301   {GST_H265_PROFILE_MULTIVIEW_MAIN, "multiview-main"},
302   {GST_H265_PROFILE_SCALABLE_MAIN, "scalable-main"},
303   {GST_H265_PROFILE_SCALABLE_MAIN_10, "scalable-main-10"},
304   {GST_H265_PROFILE_SCALABLE_MONOCHROME, "scalable-monochrome"},
305   {GST_H265_PROFILE_SCALABLE_MONOCHROME_12, "scalable-monochrome-12"},
306   {GST_H265_PROFILE_SCALABLE_MONOCHROME_16, "scalable-monochrome-16"},
307   {GST_H265_PROFILE_SCALABLE_MAIN_444, "scalable-main-444"},
308   {GST_H265_PROFILE_3D_MAIN, "3d-main"},
309 };
310 
311 /****** Parsing functions *****/
312 
313 static gboolean
gst_h265_parse_profile_tier_level(GstH265ProfileTierLevel * ptl,NalReader * nr,guint8 maxNumSubLayersMinus1)314 gst_h265_parse_profile_tier_level (GstH265ProfileTierLevel * ptl,
315     NalReader * nr, guint8 maxNumSubLayersMinus1)
316 {
317   guint i, j;
318   GST_DEBUG ("parsing \"ProfileTierLevel parameters\"");
319 
320   READ_UINT8 (nr, ptl->profile_space, 2);
321   READ_UINT8 (nr, ptl->tier_flag, 1);
322   READ_UINT8 (nr, ptl->profile_idc, 5);
323 
324   for (j = 0; j < 32; j++)
325     READ_UINT8 (nr, ptl->profile_compatibility_flag[j], 1);
326 
327   READ_UINT8 (nr, ptl->progressive_source_flag, 1);
328   READ_UINT8 (nr, ptl->interlaced_source_flag, 1);
329   READ_UINT8 (nr, ptl->non_packed_constraint_flag, 1);
330   READ_UINT8 (nr, ptl->frame_only_constraint_flag, 1);
331 
332   READ_UINT8 (nr, ptl->max_12bit_constraint_flag, 1);
333   READ_UINT8 (nr, ptl->max_10bit_constraint_flag, 1);
334   READ_UINT8 (nr, ptl->max_8bit_constraint_flag, 1);
335   READ_UINT8 (nr, ptl->max_422chroma_constraint_flag, 1);
336   READ_UINT8 (nr, ptl->max_420chroma_constraint_flag, 1);
337   READ_UINT8 (nr, ptl->max_monochrome_constraint_flag, 1);
338   READ_UINT8 (nr, ptl->intra_constraint_flag, 1);
339   READ_UINT8 (nr, ptl->one_picture_only_constraint_flag, 1);
340   READ_UINT8 (nr, ptl->lower_bit_rate_constraint_flag, 1);
341   READ_UINT8 (nr, ptl->max_14bit_constraint_flag, 1);
342 
343   /* skip the reserved zero bits */
344   if (!nal_reader_skip (nr, 34))
345     goto error;
346 
347   READ_UINT8 (nr, ptl->level_idc, 8);
348   for (j = 0; j < maxNumSubLayersMinus1; j++) {
349     READ_UINT8 (nr, ptl->sub_layer_profile_present_flag[j], 1);
350     READ_UINT8 (nr, ptl->sub_layer_level_present_flag[j], 1);
351   }
352 
353   if (maxNumSubLayersMinus1 > 0) {
354     for (i = maxNumSubLayersMinus1; i < 8; i++)
355       if (!nal_reader_skip (nr, 2))
356         goto error;
357   }
358 
359   for (i = 0; i < maxNumSubLayersMinus1; i++) {
360     if (ptl->sub_layer_profile_present_flag[i]) {
361       READ_UINT8 (nr, ptl->sub_layer_profile_space[i], 2);
362       READ_UINT8 (nr, ptl->sub_layer_tier_flag[i], 1);
363       READ_UINT8 (nr, ptl->sub_layer_profile_idc[i], 5);
364 
365       for (j = 0; j < 32; j++)
366         READ_UINT8 (nr, ptl->sub_layer_profile_compatibility_flag[i][j], 1);
367 
368       READ_UINT8 (nr, ptl->sub_layer_progressive_source_flag[i], 1);
369       READ_UINT8 (nr, ptl->sub_layer_interlaced_source_flag[i], 1);
370       READ_UINT8 (nr, ptl->sub_layer_non_packed_constraint_flag[i], 1);
371       READ_UINT8 (nr, ptl->sub_layer_frame_only_constraint_flag[i], 1);
372 
373       if (!nal_reader_skip (nr, 44))
374         goto error;
375     }
376 
377     if (ptl->sub_layer_level_present_flag[i])
378       READ_UINT8 (nr, ptl->sub_layer_level_idc[i], 8);
379   }
380 
381   return TRUE;
382 
383 error:
384   GST_WARNING ("error parsing \"ProfileTierLevel Parameters\"");
385   return FALSE;
386 }
387 
388 static gboolean
gst_h265_parse_sub_layer_hrd_parameters(GstH265SubLayerHRDParams * sub_hrd,NalReader * nr,guint8 CpbCnt,guint8 sub_pic_hrd_params_present_flag)389 gst_h265_parse_sub_layer_hrd_parameters (GstH265SubLayerHRDParams * sub_hrd,
390     NalReader * nr, guint8 CpbCnt, guint8 sub_pic_hrd_params_present_flag)
391 {
392   guint i;
393 
394   GST_DEBUG ("parsing \"SubLayer HRD Parameters\"");
395 
396   for (i = 0; i <= CpbCnt; i++) {
397     READ_UE_MAX (nr, sub_hrd->bit_rate_value_minus1[i], G_MAXUINT32 - 1);
398     READ_UE_MAX (nr, sub_hrd->cpb_size_value_minus1[i], G_MAXUINT32 - 1);
399 
400     if (sub_pic_hrd_params_present_flag) {
401       READ_UE_MAX (nr, sub_hrd->cpb_size_du_value_minus1[i], G_MAXUINT32 - 1);
402       READ_UE_MAX (nr, sub_hrd->bit_rate_du_value_minus1[i], G_MAXUINT32 - 1);
403     }
404 
405     READ_UINT8 (nr, sub_hrd->cbr_flag[i], 1);
406   }
407 
408   return TRUE;
409 
410 error:
411   GST_WARNING ("error parsing \"SubLayerHRD Parameters \"");
412   return FALSE;
413 }
414 
415 static gboolean
gst_h265_parse_hrd_parameters(GstH265HRDParams * hrd,NalReader * nr,guint8 commonInfPresentFlag,guint8 maxNumSubLayersMinus1)416 gst_h265_parse_hrd_parameters (GstH265HRDParams * hrd, NalReader * nr,
417     guint8 commonInfPresentFlag, guint8 maxNumSubLayersMinus1)
418 {
419   guint i;
420 
421   GST_DEBUG ("parsing \"HRD Parameters\"");
422 
423   /* set default values for fields that might not be present in the bitstream
424      and have valid defaults */
425   hrd->initial_cpb_removal_delay_length_minus1 = 23;
426   hrd->au_cpb_removal_delay_length_minus1 = 23;
427   hrd->dpb_output_delay_length_minus1 = 23;
428 
429   if (commonInfPresentFlag) {
430     READ_UINT8 (nr, hrd->nal_hrd_parameters_present_flag, 1);
431     READ_UINT8 (nr, hrd->vcl_hrd_parameters_present_flag, 1);
432 
433     if (hrd->nal_hrd_parameters_present_flag
434         || hrd->vcl_hrd_parameters_present_flag) {
435 
436       READ_UINT8 (nr, hrd->sub_pic_hrd_params_present_flag, 1);
437 
438       if (hrd->sub_pic_hrd_params_present_flag) {
439         READ_UINT8 (nr, hrd->tick_divisor_minus2, 8);
440         READ_UINT8 (nr, hrd->du_cpb_removal_delay_increment_length_minus1, 5);
441         READ_UINT8 (nr, hrd->sub_pic_cpb_params_in_pic_timing_sei_flag, 1);
442         READ_UINT8 (nr, hrd->dpb_output_delay_du_length_minus1, 5);
443       }
444 
445       READ_UINT8 (nr, hrd->bit_rate_scale, 4);
446       READ_UINT8 (nr, hrd->cpb_size_scale, 4);
447 
448       if (hrd->sub_pic_hrd_params_present_flag)
449         READ_UINT8 (nr, hrd->cpb_size_du_scale, 4);
450 
451       READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
452       READ_UINT8 (nr, hrd->au_cpb_removal_delay_length_minus1, 5);
453       READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
454     }
455   }
456 
457   for (i = 0; i <= maxNumSubLayersMinus1; i++) {
458     READ_UINT8 (nr, hrd->fixed_pic_rate_general_flag[i], 1);
459 
460     if (!hrd->fixed_pic_rate_general_flag[i]) {
461       READ_UINT8 (nr, hrd->fixed_pic_rate_within_cvs_flag[i], 1);
462     } else
463       hrd->fixed_pic_rate_within_cvs_flag[i] = 1;
464 
465     if (hrd->fixed_pic_rate_within_cvs_flag[i]) {
466       READ_UE_MAX (nr, hrd->elemental_duration_in_tc_minus1[i], 2047);
467     } else
468       READ_UINT8 (nr, hrd->low_delay_hrd_flag[i], 1);
469 
470     if (!hrd->low_delay_hrd_flag[i])
471       READ_UE_MAX (nr, hrd->cpb_cnt_minus1[i], 31);
472 
473     if (hrd->nal_hrd_parameters_present_flag)
474       if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
475               [i], nr, hrd->cpb_cnt_minus1[i],
476               hrd->sub_pic_hrd_params_present_flag))
477         goto error;
478 
479     if (hrd->vcl_hrd_parameters_present_flag)
480       if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
481               [i], nr, hrd->cpb_cnt_minus1[i],
482               hrd->sub_pic_hrd_params_present_flag))
483         goto error;
484   }
485 
486   return TRUE;
487 
488 error:
489   GST_WARNING ("error parsing \"HRD Parameters\"");
490   return FALSE;
491 }
492 
493 static gboolean
gst_h265_parse_vui_parameters(GstH265SPS * sps,NalReader * nr)494 gst_h265_parse_vui_parameters (GstH265SPS * sps, NalReader * nr)
495 {
496   GstH265VUIParams *vui = &sps->vui_params;
497 
498   GST_DEBUG ("parsing \"VUI Parameters\"");
499 
500   /* set default values for fields that might not be present in the bitstream
501      and have valid defaults */
502   vui->video_format = 5;
503   vui->colour_primaries = 2;
504   vui->transfer_characteristics = 2;
505   vui->matrix_coefficients = 2;
506   vui->motion_vectors_over_pic_boundaries_flag = 1;
507   vui->max_bytes_per_pic_denom = 2;
508   vui->max_bits_per_min_cu_denom = 1;
509   vui->log2_max_mv_length_horizontal = 15;
510   vui->log2_max_mv_length_vertical = 15;
511 
512   if (sps && sps->profile_tier_level.progressive_source_flag
513       && sps->profile_tier_level.interlaced_source_flag)
514     vui->frame_field_info_present_flag = 1;
515 
516   READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
517   if (vui->aspect_ratio_info_present_flag) {
518     READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
519     if (vui->aspect_ratio_idc == EXTENDED_SAR) {
520       READ_UINT16 (nr, vui->sar_width, 16);
521       READ_UINT16 (nr, vui->sar_height, 16);
522       vui->par_n = vui->sar_width;
523       vui->par_d = vui->sar_height;
524     } else if (vui->aspect_ratio_idc <= 16) {
525       vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
526       vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
527     }
528   }
529 
530   READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
531   if (vui->overscan_info_present_flag)
532     READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);
533 
534   READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
535   if (vui->video_signal_type_present_flag) {
536 
537     READ_UINT8 (nr, vui->video_format, 3);
538     READ_UINT8 (nr, vui->video_full_range_flag, 1);
539     READ_UINT8 (nr, vui->colour_description_present_flag, 1);
540     if (vui->colour_description_present_flag) {
541       READ_UINT8 (nr, vui->colour_primaries, 8);
542       READ_UINT8 (nr, vui->transfer_characteristics, 8);
543       READ_UINT8 (nr, vui->matrix_coefficients, 8);
544     }
545   }
546 
547   READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
548   if (vui->chroma_loc_info_present_flag) {
549     READ_UE_MAX (nr, vui->chroma_sample_loc_type_top_field, 5);
550     READ_UE_MAX (nr, vui->chroma_sample_loc_type_bottom_field, 5);
551   }
552 
553   READ_UINT8 (nr, vui->neutral_chroma_indication_flag, 1);
554   READ_UINT8 (nr, vui->field_seq_flag, 1);
555   READ_UINT8 (nr, vui->frame_field_info_present_flag, 1);
556 
557   READ_UINT8 (nr, vui->default_display_window_flag, 1);
558   if (vui->default_display_window_flag) {
559     READ_UE (nr, vui->def_disp_win_left_offset);
560     READ_UE (nr, vui->def_disp_win_right_offset);
561     READ_UE (nr, vui->def_disp_win_top_offset);
562     READ_UE (nr, vui->def_disp_win_bottom_offset);
563   }
564 
565   READ_UINT8 (nr, vui->timing_info_present_flag, 1);
566   if (vui->timing_info_present_flag) {
567     READ_UINT32 (nr, vui->num_units_in_tick, 32);
568     if (vui->num_units_in_tick == 0)
569       GST_WARNING ("num_units_in_tick = 0 detected in stream "
570           "(incompliant to H.265 E.2.1).");
571 
572     READ_UINT32 (nr, vui->time_scale, 32);
573     if (vui->time_scale == 0)
574       GST_WARNING ("time_scale = 0 detected in stream "
575           "(incompliant to H.265 E.2.1).");
576 
577     READ_UINT8 (nr, vui->poc_proportional_to_timing_flag, 1);
578     if (vui->poc_proportional_to_timing_flag)
579       READ_UE_MAX (nr, vui->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
580 
581     READ_UINT8 (nr, vui->hrd_parameters_present_flag, 1);
582     if (vui->hrd_parameters_present_flag)
583       if (!gst_h265_parse_hrd_parameters (&vui->hrd_params, nr, 1,
584               sps->max_sub_layers_minus1))
585         goto error;
586   }
587 
588   READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
589   if (vui->bitstream_restriction_flag) {
590     READ_UINT8 (nr, vui->tiles_fixed_structure_flag, 1);
591     READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
592     READ_UINT8 (nr, vui->restricted_ref_pic_lists_flag, 1);
593     READ_UE_MAX (nr, vui->min_spatial_segmentation_idc, 4096);
594     READ_UE_MAX (nr, vui->max_bytes_per_pic_denom, 16);
595     READ_UE_MAX (nr, vui->max_bits_per_min_cu_denom, 16);
596     READ_UE_MAX (nr, vui->log2_max_mv_length_horizontal, 16);
597     READ_UE_MAX (nr, vui->log2_max_mv_length_vertical, 15);
598   }
599 
600   return TRUE;
601 
602 error:
603   GST_WARNING ("error parsing \"VUI Parameters\"");
604   return FALSE;
605 }
606 
607 static gboolean
get_scaling_list_params(GstH265ScalingList * dest_scaling_list,guint8 sizeId,guint8 matrixId,guint8 ** sl,guint8 * size,gint16 ** scaling_list_dc_coef_minus8)608 get_scaling_list_params (GstH265ScalingList * dest_scaling_list,
609     guint8 sizeId, guint8 matrixId, guint8 ** sl, guint8 * size,
610     gint16 ** scaling_list_dc_coef_minus8)
611 {
612   switch (sizeId) {
613     case GST_H265_QUANT_MATIX_4X4:
614       *sl = dest_scaling_list->scaling_lists_4x4[matrixId];
615       if (size)
616         *size = 16;
617       break;
618     case GST_H265_QUANT_MATIX_8X8:
619       *sl = dest_scaling_list->scaling_lists_8x8[matrixId];
620       if (size)
621         *size = 64;
622       break;
623     case GST_H265_QUANT_MATIX_16X16:
624       *sl = dest_scaling_list->scaling_lists_16x16[matrixId];
625       if (size)
626         *size = 64;
627       if (scaling_list_dc_coef_minus8)
628         *scaling_list_dc_coef_minus8 =
629             dest_scaling_list->scaling_list_dc_coef_minus8_16x16;
630       break;
631     case GST_H265_QUANT_MATIX_32X32:
632       *sl = dest_scaling_list->scaling_lists_32x32[matrixId];
633       if (size)
634         *size = 64;
635       if (scaling_list_dc_coef_minus8)
636         *scaling_list_dc_coef_minus8 =
637             dest_scaling_list->scaling_list_dc_coef_minus8_32x32;
638       break;
639     default:
640       return FALSE;
641   }
642   return TRUE;
643 }
644 
645 static gboolean
get_default_scaling_lists(guint8 ** sl,guint8 sizeId,guint8 matrixId)646 get_default_scaling_lists (guint8 ** sl, guint8 sizeId, guint8 matrixId)
647 {
648   switch (sizeId) {
649     case GST_H265_QUANT_MATIX_4X4:
650       memcpy (*sl, default_scaling_list0, 16);
651       break;
652 
653     case GST_H265_QUANT_MATIX_8X8:
654     case GST_H265_QUANT_MATIX_16X16:
655       if (matrixId <= 2)
656         memcpy (*sl, default_scaling_list1, 64);
657       else
658         memcpy (*sl, default_scaling_list2, 64);
659       break;
660 
661     case GST_H265_QUANT_MATIX_32X32:
662       if (matrixId == 0)
663         memcpy (*sl, default_scaling_list1, 64);
664       else
665         memcpy (*sl, default_scaling_list2, 64);
666       break;
667 
668     default:
669       return FALSE;
670       break;
671   }
672   return TRUE;
673 }
674 
675 static gboolean
gst_h265_parser_parse_scaling_lists(NalReader * nr,GstH265ScalingList * dest_scaling_list,gboolean use_default)676 gst_h265_parser_parse_scaling_lists (NalReader * nr,
677     GstH265ScalingList * dest_scaling_list, gboolean use_default)
678 {
679   guint8 sizeId;
680   guint8 matrixId;
681   guint8 scaling_list_pred_mode_flag = 0;
682   guint8 scaling_list_pred_matrix_id_delta = 0;
683   guint8 size, i;
684 
685   GST_DEBUG ("parsing scaling lists");
686 
687   for (sizeId = 0; sizeId < 4; sizeId++) {
688     for (matrixId = 0; matrixId < ((sizeId == 3) ? 2 : 6); matrixId++) {
689       gint16 *scaling_list_dc_coef_minus8 = NULL;
690       guint8 *sl;
691 
692       if (!get_scaling_list_params (dest_scaling_list, sizeId, matrixId, &sl,
693               &size, &scaling_list_dc_coef_minus8))
694         goto error;
695 
696       /* use_default_scaling_matrices forcefully which means,
697        * sps_scaling_list_enabled_flag=TRUE,
698        * sps_scaling_list_data_present_flag=FALSE,
699        * pps_scaling_list_data_present_falg=FALSE */
700       if (use_default) {
701         if (!get_default_scaling_lists (&sl, sizeId, matrixId))
702           goto error;
703 
704         /* Inferring the value of scaling_list_dc_coef_minus8 */
705         if (sizeId > 1)
706           scaling_list_dc_coef_minus8[matrixId] = 8;
707 
708       } else {
709         READ_UINT8 (nr, scaling_list_pred_mode_flag, 1);
710 
711         if (!scaling_list_pred_mode_flag) {
712           guint8 refMatrixId;
713 
714           READ_UE_MAX (nr, scaling_list_pred_matrix_id_delta, matrixId);
715 
716           if (!scaling_list_pred_matrix_id_delta) {
717             if (!get_default_scaling_lists (&sl, sizeId, matrixId))
718               goto error;
719 
720             /* Inferring the value of scaling_list_dc_coef_minus8 */
721             if (sizeId > 1)
722               scaling_list_dc_coef_minus8[matrixId] = 8;
723 
724           } else {
725             guint8 *temp_sl;
726 
727             refMatrixId = matrixId - scaling_list_pred_matrix_id_delta; /* 7-30 */
728 
729             if (!get_scaling_list_params (dest_scaling_list, sizeId,
730                     refMatrixId, &temp_sl, NULL, NULL))
731               goto error;
732 
733             for (i = 0; i < size; i++)
734               sl[i] = temp_sl[i];       /* 7-31 */
735 
736 
737             /* Inferring the value of scaling_list_dc_coef_minus8 */
738             if (sizeId > 1)
739               scaling_list_dc_coef_minus8[matrixId] =
740                   scaling_list_dc_coef_minus8[refMatrixId];
741           }
742         } else {
743           guint8 nextCoef = 8;
744           gint8 scaling_list_delta_coef;
745 
746           if (sizeId > 1) {
747             READ_SE_ALLOWED (nr, scaling_list_dc_coef_minus8[matrixId], -7,
748                 247);
749             nextCoef = scaling_list_dc_coef_minus8[matrixId] + 8;
750           }
751 
752           for (i = 0; i < size; i++) {
753             READ_SE_ALLOWED (nr, scaling_list_delta_coef, -128, 127);
754             nextCoef = (nextCoef + scaling_list_delta_coef) & 0xff;
755             sl[i] = nextCoef;
756           }
757         }
758       }
759     }
760   }
761 
762   return TRUE;
763 
764 error:
765   GST_WARNING ("error parsing scaling lists");
766   return FALSE;
767 }
768 
769 static gboolean
gst_h265_parser_parse_short_term_ref_pic_sets(GstH265ShortTermRefPicSet * stRPS,NalReader * nr,guint8 stRpsIdx,GstH265SPS * sps)770 gst_h265_parser_parse_short_term_ref_pic_sets (GstH265ShortTermRefPicSet *
771     stRPS, NalReader * nr, guint8 stRpsIdx, GstH265SPS * sps)
772 {
773   guint8 num_short_term_ref_pic_sets;
774   guint8 RefRpsIdx = 0;
775   gint16 deltaRps = 0;
776   guint8 use_delta_flag[16] = { 0 };
777   guint8 used_by_curr_pic_flag[16] = { 0 };
778   guint32 delta_poc_s0_minus1[16] = { 0 };
779   guint32 delta_poc_s1_minus1[16] = { 0 };
780   gint j, i = 0;
781   gint dPoc;
782 
783   GST_DEBUG ("parsing \"ShortTermRefPicSetParameters\"");
784 
785   /* set default values for fields that might not be present in the bitstream
786      and have valid defaults */
787   for (j = 0; j < 16; j++)
788     use_delta_flag[j] = 1;
789 
790   num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
791 
792   if (stRpsIdx != 0)
793     READ_UINT8 (nr, stRPS->inter_ref_pic_set_prediction_flag, 1);
794 
795   if (stRPS->inter_ref_pic_set_prediction_flag) {
796     GstH265ShortTermRefPicSet *RefRPS;
797 
798     if (stRpsIdx == num_short_term_ref_pic_sets)
799       READ_UE_MAX (nr, stRPS->delta_idx_minus1, stRpsIdx - 1);
800 
801     READ_UINT8 (nr, stRPS->delta_rps_sign, 1);
802     READ_UE_MAX (nr, stRPS->abs_delta_rps_minus1, 32767);
803 
804     RefRpsIdx = stRpsIdx - stRPS->delta_idx_minus1 - 1; /* 7-45 */
805     deltaRps = (1 - 2 * stRPS->delta_rps_sign) * (stRPS->abs_delta_rps_minus1 + 1);     /* 7-46 */
806 
807     RefRPS = &sps->short_term_ref_pic_set[RefRpsIdx];
808     stRPS->NumDeltaPocsOfRefRpsIdx = RefRPS->NumDeltaPocs;
809 
810     for (j = 0; j <= RefRPS->NumDeltaPocs; j++) {
811       READ_UINT8 (nr, used_by_curr_pic_flag[j], 1);
812       if (!used_by_curr_pic_flag[j])
813         READ_UINT8 (nr, use_delta_flag[j], 1);
814     }
815 
816     /* 7-47: calculate NumNegativePics, DeltaPocS0 and UsedByCurrPicS0 */
817     i = 0;
818     for (j = (RefRPS->NumPositivePics - 1); j >= 0; j--) {
819       dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
820       if (dPoc < 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
821         stRPS->DeltaPocS0[i] = dPoc;
822         stRPS->UsedByCurrPicS0[i++] =
823             used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
824       }
825     }
826     if (deltaRps < 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
827       stRPS->DeltaPocS0[i] = deltaRps;
828       stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
829     }
830     for (j = 0; j < RefRPS->NumNegativePics; j++) {
831       dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
832       if (dPoc < 0 && use_delta_flag[j]) {
833         stRPS->DeltaPocS0[i] = dPoc;
834         stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[j];
835       }
836     }
837     stRPS->NumNegativePics = i;
838 
839     /* 7-48: calculate NumPositivePics, DeltaPocS1 and UsedByCurrPicS1 */
840     i = 0;
841     for (j = (RefRPS->NumNegativePics - 1); j >= 0; j--) {
842       dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
843       if (dPoc > 0 && use_delta_flag[j]) {
844         stRPS->DeltaPocS1[i] = dPoc;
845         stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[j];
846       }
847     }
848     if (deltaRps > 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
849       stRPS->DeltaPocS1[i] = deltaRps;
850       stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
851     }
852     for (j = 0; j < RefRPS->NumPositivePics; j++) {
853       dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
854       if (dPoc > 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
855         stRPS->DeltaPocS1[i] = dPoc;
856         stRPS->UsedByCurrPicS1[i++] =
857             used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
858       }
859     }
860     stRPS->NumPositivePics = i;
861 
862   } else {
863     /* 7-49 */
864     READ_UE_MAX (nr, stRPS->NumNegativePics,
865         sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1]);
866 
867     /* 7-50 */
868     READ_UE_MAX (nr, stRPS->NumPositivePics,
869         (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] -
870             stRPS->NumNegativePics));
871 
872     for (i = 0; i < stRPS->NumNegativePics; i++) {
873       READ_UE_MAX (nr, delta_poc_s0_minus1[i], 32767);
874       /* 7-51 */
875       READ_UINT8 (nr, stRPS->UsedByCurrPicS0[i], 1);
876 
877       if (i == 0) {
878         /* 7-53 */
879         stRPS->DeltaPocS0[i] = -(delta_poc_s0_minus1[i] + 1);
880       } else {
881         /* 7-55 */
882         stRPS->DeltaPocS0[i] =
883             stRPS->DeltaPocS0[i - 1] - (delta_poc_s0_minus1[i] + 1);
884       }
885     }
886 
887     for (j = 0; j < stRPS->NumPositivePics; j++) {
888       READ_UE_MAX (nr, delta_poc_s1_minus1[j], 32767);
889 
890       /* 7-52 */
891       READ_UINT8 (nr, stRPS->UsedByCurrPicS1[j], 1);
892 
893       if (j == 0) {
894         /* 7-54 */
895         stRPS->DeltaPocS1[j] = delta_poc_s1_minus1[j] + 1;
896       } else {
897         /* 7-56 */
898         stRPS->DeltaPocS1[j] =
899             stRPS->DeltaPocS1[j - 1] + (delta_poc_s1_minus1[j] + 1);
900       }
901     }
902 
903   }
904 
905   /* 7-57 */
906   stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;
907 
908   return TRUE;
909 
910 error:
911   GST_WARNING ("error parsing \"ShortTermRefPicSet Parameters\"");
912   return FALSE;
913 }
914 
915 static gboolean
gst_h265_slice_parse_ref_pic_list_modification(GstH265SliceHdr * slice,NalReader * nr,gint NumPocTotalCurr)916 gst_h265_slice_parse_ref_pic_list_modification (GstH265SliceHdr * slice,
917     NalReader * nr, gint NumPocTotalCurr)
918 {
919   guint i;
920   GstH265RefPicListModification *rpl_mod = &slice->ref_pic_list_modification;
921   const guint n = ceil_log2 (NumPocTotalCurr);
922 
923   READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l0, 1);
924 
925   if (rpl_mod->ref_pic_list_modification_flag_l0) {
926     for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
927       READ_UINT32 (nr, rpl_mod->list_entry_l0[i], n);
928       CHECK_ALLOWED_MAX (rpl_mod->list_entry_l0[i], (NumPocTotalCurr - 1));
929     }
930   }
931   if (GST_H265_IS_B_SLICE (slice)) {
932     READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l1, 1);
933     if (rpl_mod->ref_pic_list_modification_flag_l1)
934       for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
935         READ_UINT32 (nr, rpl_mod->list_entry_l1[i], n);
936         CHECK_ALLOWED_MAX (rpl_mod->list_entry_l1[i], (NumPocTotalCurr - 1));
937       }
938   }
939 
940   return TRUE;
941 
942 error:
943   GST_WARNING ("error parsing \"Reference picture list modifications\"");
944   return FALSE;
945 }
946 
947 static gboolean
gst_h265_slice_parse_pred_weight_table(GstH265SliceHdr * slice,NalReader * nr)948 gst_h265_slice_parse_pred_weight_table (GstH265SliceHdr * slice, NalReader * nr)
949 {
950   GstH265PredWeightTable *p;
951   gint i, j;
952   GstH265PPS *pps = slice->pps;
953   GstH265SPS *sps = pps->sps;
954 
955   GST_DEBUG ("parsing \"Prediction weight table\"");
956 
957   p = &slice->pred_weight_table;
958 
959   READ_UE_MAX (nr, p->luma_log2_weight_denom, 7);
960 
961   if (sps->chroma_format_idc != 0) {
962     READ_SE_ALLOWED (nr, p->delta_chroma_log2_weight_denom,
963         (0 - p->luma_log2_weight_denom), (7 - p->luma_log2_weight_denom));
964   }
965 
966   for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
967     READ_UINT8 (nr, p->luma_weight_l0_flag[i], 1);
968 
969   if (sps->chroma_format_idc != 0)
970     for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
971       READ_UINT8 (nr, p->chroma_weight_l0_flag[i], 1);
972 
973   for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
974     if (p->luma_weight_l0_flag[i]) {
975       READ_SE_ALLOWED (nr, p->delta_luma_weight_l0[i], -128, 127);
976       READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
977     }
978     if (p->chroma_weight_l0_flag[i])
979       for (j = 0; j < 2; j++) {
980         READ_SE_ALLOWED (nr, p->delta_chroma_weight_l0[i][j], -128, 127);
981         READ_SE_ALLOWED (nr, p->delta_chroma_offset_l0[i][j], -512, 511);
982       }
983   }
984 
985   if (GST_H265_IS_B_SLICE (slice)) {
986     for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
987       READ_UINT8 (nr, p->luma_weight_l1_flag[i], 1);
988     if (sps->chroma_format_idc != 0)
989       for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
990         READ_UINT8 (nr, p->chroma_weight_l1_flag[i], 1);
991 
992     for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
993       if (p->luma_weight_l1_flag[i]) {
994         READ_SE_ALLOWED (nr, p->delta_luma_weight_l1[i], -128, 127);
995         READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
996       }
997       if (p->chroma_weight_l1_flag[i])
998         for (j = 0; j < 2; j++) {
999           READ_SE_ALLOWED (nr, p->delta_chroma_weight_l1[i][j], -128, 127);
1000           READ_SE_ALLOWED (nr, p->delta_chroma_offset_l1[i][j], -512, 511);
1001         }
1002     }
1003   }
1004 
1005   return TRUE;
1006 
1007 error:
1008   GST_WARNING ("error parsing \"Prediction weight table\"");
1009   return FALSE;
1010 }
1011 
1012 static GstH265ParserResult
gst_h265_parser_parse_buffering_period(GstH265Parser * parser,GstH265BufferingPeriod * per,NalReader * nr)1013 gst_h265_parser_parse_buffering_period (GstH265Parser * parser,
1014     GstH265BufferingPeriod * per, NalReader * nr)
1015 {
1016   GstH265SPS *sps;
1017   guint8 sps_id;
1018   guint i;
1019   guint n;
1020 
1021   GST_DEBUG ("parsing \"Buffering period\"");
1022 
1023   READ_UE_MAX (nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
1024   sps = gst_h265_parser_get_sps (parser, sps_id);
1025   if (!sps) {
1026     GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
1027         sps_id);
1028     return GST_H265_PARSER_BROKEN_LINK;
1029   }
1030   per->sps = sps;
1031 
1032   if (sps->vui_parameters_present_flag) {
1033     GstH265VUIParams *vui = &sps->vui_params;
1034     GstH265HRDParams *hrd = &vui->hrd_params;
1035 
1036     if (!hrd->sub_pic_hrd_params_present_flag)
1037       READ_UINT8 (nr, per->irap_cpb_params_present_flag, 1);
1038 
1039     if (per->irap_cpb_params_present_flag) {
1040       READ_UINT8 (nr, per->cpb_delay_offset,
1041           (hrd->au_cpb_removal_delay_length_minus1 + 1));
1042       READ_UINT8 (nr, per->dpb_delay_offset,
1043           (hrd->dpb_output_delay_length_minus1 + 1));
1044     }
1045 
1046     n = hrd->initial_cpb_removal_delay_length_minus1 + 1;
1047 
1048     READ_UINT8 (nr, per->concatenation_flag, 1);
1049     READ_UINT8 (nr, per->au_cpb_removal_delay_delta_minus1,
1050         (hrd->au_cpb_removal_delay_length_minus1 + 1));
1051 
1052     if (hrd->nal_hrd_parameters_present_flag) {
1053       for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
1054         READ_UINT8 (nr, per->nal_initial_cpb_removal_delay[i], n);
1055         READ_UINT8 (nr, per->nal_initial_cpb_removal_offset[i], n);
1056         if (hrd->sub_pic_hrd_params_present_flag
1057             || per->irap_cpb_params_present_flag) {
1058           READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_delay[i], n);
1059           READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_offset[i], n);
1060         }
1061       }
1062     }
1063 
1064     if (hrd->vcl_hrd_parameters_present_flag) {
1065       for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
1066         READ_UINT8 (nr, per->vcl_initial_cpb_removal_delay[i], n);
1067         READ_UINT8 (nr, per->vcl_initial_cpb_removal_offset[i], n);
1068         if (hrd->sub_pic_hrd_params_present_flag
1069             || per->irap_cpb_params_present_flag) {
1070           READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_delay[i], n);
1071           READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_offset[i], n);
1072         }
1073       }
1074     }
1075 
1076   }
1077   return GST_H265_PARSER_OK;
1078 
1079 error:
1080   GST_WARNING ("error parsing \"Buffering period\"");
1081   return GST_H265_PARSER_ERROR;
1082 }
1083 
1084 static GstH265ParserResult
gst_h265_parser_parse_pic_timing(GstH265Parser * parser,GstH265PicTiming * tim,NalReader * nr)1085 gst_h265_parser_parse_pic_timing (GstH265Parser * parser,
1086     GstH265PicTiming * tim, NalReader * nr)
1087 {
1088   GstH265ProfileTierLevel *profile_tier_level;
1089   guint i;
1090 
1091   GST_DEBUG ("parsing \"Picture timing\"");
1092   if (!parser->last_sps || !parser->last_sps->valid) {
1093     GST_WARNING ("didn't get the associated sequence parameter set for the "
1094         "current access unit");
1095     goto error;
1096   }
1097 
1098   profile_tier_level = &parser->last_sps->profile_tier_level;
1099 
1100   /* set default values */
1101   if (!profile_tier_level->progressive_source_flag
1102       && profile_tier_level->interlaced_source_flag)
1103     tim->source_scan_type = 0;
1104   else if (profile_tier_level->progressive_source_flag
1105       && !profile_tier_level->interlaced_source_flag)
1106     tim->source_scan_type = 1;
1107   else
1108     tim->source_scan_type = 2;
1109 
1110   if (parser->last_sps->vui_parameters_present_flag) {
1111     GstH265VUIParams *vui = &parser->last_sps->vui_params;
1112 
1113     if (vui->frame_field_info_present_flag) {
1114       READ_UINT8 (nr, tim->pic_struct, 4);
1115       READ_UINT8 (nr, tim->source_scan_type, 2);
1116       READ_UINT8 (nr, tim->duplicate_flag, 1);
1117     } else {
1118       /* set default values */
1119       tim->pic_struct = 0;
1120     }
1121 
1122     if (vui->hrd_parameters_present_flag) {
1123       GstH265HRDParams *hrd = &vui->hrd_params;
1124 
1125       READ_UINT8 (nr, tim->au_cpb_removal_delay_minus1,
1126           (hrd->au_cpb_removal_delay_length_minus1 + 1));
1127       READ_UINT8 (nr, tim->pic_dpb_output_delay,
1128           (hrd->dpb_output_delay_length_minus1 + 1));
1129 
1130       if (hrd->sub_pic_hrd_params_present_flag)
1131         READ_UINT8 (nr, tim->pic_dpb_output_du_delay,
1132             (hrd->dpb_output_delay_du_length_minus1 + 1));
1133 
1134       if (hrd->sub_pic_hrd_params_present_flag
1135           && hrd->sub_pic_cpb_params_in_pic_timing_sei_flag) {
1136         READ_UE (nr, tim->num_decoding_units_minus1);
1137 
1138         READ_UINT8 (nr, tim->du_common_cpb_removal_delay_flag, 1);
1139         if (tim->du_common_cpb_removal_delay_flag)
1140           READ_UINT8 (nr, tim->du_common_cpb_removal_delay_increment_minus1,
1141               (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1142 
1143         tim->num_nalus_in_du_minus1 =
1144             g_new0 (guint32, (tim->num_decoding_units_minus1 + 1));
1145         tim->du_cpb_removal_delay_increment_minus1 =
1146             g_new0 (guint8, (tim->num_decoding_units_minus1 + 1));
1147 
1148         for (i = 0; i <= tim->num_decoding_units_minus1; i++) {
1149           READ_UE (nr, tim->num_nalus_in_du_minus1[i]);
1150 
1151           if (!tim->du_common_cpb_removal_delay_flag
1152               && (i < tim->num_decoding_units_minus1))
1153             READ_UINT8 (nr, tim->du_cpb_removal_delay_increment_minus1[i],
1154                 (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
1155         }
1156       }
1157     }
1158   }
1159   return GST_H265_PARSER_OK;
1160 
1161 error:
1162   GST_WARNING ("error parsing \"Picture timing\"");
1163   return GST_H265_PARSER_ERROR;
1164 }
1165 
1166 static GstH265ParserResult
gst_h265_parser_parse_recovery_point(GstH265Parser * parser,GstH265RecoveryPoint * rp,NalReader * nr)1167 gst_h265_parser_parse_recovery_point (GstH265Parser * parser,
1168     GstH265RecoveryPoint * rp, NalReader * nr)
1169 {
1170   GstH265SPS *const sps = parser->last_sps;
1171   gint32 max_pic_order_cnt_lsb;
1172 
1173   GST_DEBUG ("parsing \"Recovery point\"");
1174   if (!sps || !sps->valid) {
1175     GST_WARNING ("didn't get the associated sequence parameter set for the "
1176         "current access unit");
1177     goto error;
1178   }
1179 
1180   max_pic_order_cnt_lsb = pow (2, (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
1181   READ_SE_ALLOWED (nr, rp->recovery_poc_cnt, -max_pic_order_cnt_lsb / 2,
1182       max_pic_order_cnt_lsb - 1);
1183   READ_UINT8 (nr, rp->exact_match_flag, 1);
1184   READ_UINT8 (nr, rp->broken_link_flag, 1);
1185 
1186   return GST_H265_PARSER_OK;
1187 
1188 error:
1189   GST_WARNING ("error parsing \"Recovery point\"");
1190   return GST_H265_PARSER_ERROR;
1191 }
1192 
1193 
1194 static GstH265ParserResult
gst_h265_parser_parse_registered_user_data(GstH265Parser * parser,GstH265RegisteredUserData * rud,NalReader * nr,guint payload_size)1195 gst_h265_parser_parse_registered_user_data (GstH265Parser * parser,
1196     GstH265RegisteredUserData * rud, NalReader * nr, guint payload_size)
1197 {
1198   guint8 *data = NULL;
1199   guint i;
1200 
1201   rud->data = NULL;
1202   rud->size = 0;
1203 
1204   if (payload_size < 2) {
1205     GST_WARNING ("Too small payload size %d", payload_size);
1206     return GST_H265_PARSER_BROKEN_DATA;
1207   }
1208 
1209   READ_UINT8 (nr, rud->country_code, 8);
1210   --payload_size;
1211 
1212   if (rud->country_code == 0xFF) {
1213     READ_UINT8 (nr, rud->country_code_extension, 8);
1214     --payload_size;
1215   } else {
1216     rud->country_code_extension = 0;
1217   }
1218 
1219   if (payload_size < 1) {
1220     GST_WARNING ("No more remaining payload data to store");
1221     return GST_H265_PARSER_BROKEN_DATA;
1222   }
1223 
1224   data = g_malloc (payload_size);
1225   for (i = 0; i < payload_size; ++i) {
1226     READ_UINT8 (nr, data[i], 8);
1227   }
1228 
1229   GST_MEMDUMP ("SEI user data", data, payload_size);
1230 
1231   rud->data = data;
1232   rud->size = payload_size;
1233   return GST_H265_PARSER_OK;
1234 
1235 error:
1236   {
1237     GST_WARNING ("error parsing \"Registered User Data\"");
1238     g_free (data);
1239     return GST_H265_PARSER_ERROR;
1240   }
1241 }
1242 
1243 
1244 static GstH265ParserResult
gst_h265_parser_parse_time_code(GstH265Parser * parser,GstH265TimeCode * tc,NalReader * nr)1245 gst_h265_parser_parse_time_code (GstH265Parser * parser,
1246     GstH265TimeCode * tc, NalReader * nr)
1247 {
1248   guint i;
1249 
1250   GST_DEBUG ("parsing \"Time code\"");
1251 
1252   READ_UINT8 (nr, tc->num_clock_ts, 2);
1253 
1254   for (i = 0; i < tc->num_clock_ts; i++) {
1255     READ_UINT8 (nr, tc->clock_timestamp_flag[i], 1);
1256     if (tc->clock_timestamp_flag[i]) {
1257       READ_UINT8 (nr, tc->units_field_based_flag[i], 1);
1258       READ_UINT8 (nr, tc->counting_type[i], 5);
1259       READ_UINT8 (nr, tc->full_timestamp_flag[i], 1);
1260       READ_UINT8 (nr, tc->discontinuity_flag[i], 1);
1261       READ_UINT8 (nr, tc->cnt_dropped_flag[i], 1);
1262       READ_UINT16 (nr, tc->n_frames[i], 9);
1263 
1264       if (tc->full_timestamp_flag[i]) {
1265         tc->seconds_flag[i] = TRUE;
1266         READ_UINT8 (nr, tc->seconds_value[i], 6);
1267 
1268         tc->minutes_flag[i] = TRUE;
1269         READ_UINT8 (nr, tc->minutes_value[i], 6);
1270 
1271         tc->hours_flag[i] = TRUE;
1272         READ_UINT8 (nr, tc->hours_value[i], 5);
1273       } else {
1274         READ_UINT8 (nr, tc->seconds_flag[i], 1);
1275         if (tc->seconds_flag[i]) {
1276           READ_UINT8 (nr, tc->seconds_value[i], 6);
1277           READ_UINT8 (nr, tc->minutes_flag[i], 1);
1278           if (tc->minutes_flag[i]) {
1279             READ_UINT8 (nr, tc->minutes_value[i], 6);
1280             READ_UINT8 (nr, tc->hours_flag[i], 1);
1281             if (tc->hours_flag[i]) {
1282               READ_UINT8 (nr, tc->hours_value[i], 5);
1283             }
1284           }
1285         }
1286       }
1287     }
1288 
1289     READ_UINT8 (nr, tc->time_offset_length[i], 5);
1290 
1291     if (tc->time_offset_length[i] > 0)
1292       READ_UINT32 (nr, tc->time_offset_value[i], tc->time_offset_length[i]);
1293   }
1294 
1295   return GST_H265_PARSER_OK;
1296 
1297 error:
1298   GST_WARNING ("error parsing \"Time code\"");
1299   return GST_H265_PARSER_ERROR;
1300 }
1301 
1302 static GstH265ParserResult
gst_h265_parser_parse_mastering_display_colour_volume(GstH265Parser * parser,GstH265MasteringDisplayColourVolume * mdcv,NalReader * nr)1303 gst_h265_parser_parse_mastering_display_colour_volume (GstH265Parser * parser,
1304     GstH265MasteringDisplayColourVolume * mdcv, NalReader * nr)
1305 {
1306   guint i;
1307 
1308   GST_DEBUG ("parsing \"Mastering display colour volume\"");
1309 
1310   for (i = 0; i < 3; i++) {
1311     READ_UINT16 (nr, mdcv->display_primaries_x[i], 16);
1312     READ_UINT16 (nr, mdcv->display_primaries_y[i], 16);
1313   }
1314 
1315   READ_UINT16 (nr, mdcv->white_point_x, 16);
1316   READ_UINT16 (nr, mdcv->white_point_y, 16);
1317   READ_UINT32 (nr, mdcv->max_display_mastering_luminance, 32);
1318   READ_UINT32 (nr, mdcv->min_display_mastering_luminance, 32);
1319 
1320   return GST_H265_PARSER_OK;
1321 
1322 error:
1323   GST_WARNING ("error parsing \"Mastering display colour volume\"");
1324   return GST_H265_PARSER_ERROR;
1325 }
1326 
1327 static GstH265ParserResult
gst_h265_parser_parse_content_light_level_info(GstH265Parser * parser,GstH265ContentLightLevel * cll,NalReader * nr)1328 gst_h265_parser_parse_content_light_level_info (GstH265Parser * parser,
1329     GstH265ContentLightLevel * cll, NalReader * nr)
1330 {
1331   GST_DEBUG ("parsing \"Content light level\"");
1332 
1333   READ_UINT16 (nr, cll->max_content_light_level, 16);
1334   READ_UINT16 (nr, cll->max_pic_average_light_level, 16);
1335 
1336   return GST_H265_PARSER_OK;
1337 
1338 error:
1339   GST_WARNING ("error parsing \"Content light level\"");
1340   return GST_H265_PARSER_ERROR;
1341 }
1342 
1343 /******** API *************/
1344 
1345 /**
1346  * gst_h265_parser_new:
1347  *
1348  * Creates a new #GstH265Parser. It should be freed with
1349  * gst_h265_parser_free after use.
1350  *
1351  * Returns: a new #GstH265Parser
1352  */
1353 GstH265Parser *
gst_h265_parser_new(void)1354 gst_h265_parser_new (void)
1355 {
1356   GstH265Parser *parser;
1357 
1358   parser = g_slice_new0 (GstH265Parser);
1359 
1360   return parser;
1361 }
1362 
1363 /**
1364  * gst_h265_parser_free:
1365  * @parser: the #GstH265Parser to free
1366  *
1367  * Frees @parser and sets it to %NULL
1368  */
1369 void
gst_h265_parser_free(GstH265Parser * parser)1370 gst_h265_parser_free (GstH265Parser * parser)
1371 {
1372   g_slice_free (GstH265Parser, parser);
1373   parser = NULL;
1374 }
1375 
1376 /**
1377  * gst_h265_parser_identify_nalu_unchecked:
1378  * @parser: a #GstH265Parser
1379  * @data: The data to parse
1380  * @offset: the offset from which to parse @data
1381  * @size: the size of @data
1382  * @nalu: The #GstH265NalUnit where to store parsed nal headers
1383  *
1384  * Parses @data and fills @nalu from the next nalu data from @data.
1385  *
1386  * This differs from @gst_h265_parser_identify_nalu in that it doesn't
1387  * check whether the packet is complete or not.
1388  *
1389  * Note: Only use this function if you already know the provided @data
1390  * is a complete NALU, else use @gst_h265_parser_identify_nalu.
1391  *
1392  * Returns: a #GstH265ParserResult
1393  */
1394 GstH265ParserResult
gst_h265_parser_identify_nalu_unchecked(GstH265Parser * parser,const guint8 * data,guint offset,gsize size,GstH265NalUnit * nalu)1395 gst_h265_parser_identify_nalu_unchecked (GstH265Parser * parser,
1396     const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1397 {
1398   gint off1;
1399 
1400   memset (nalu, 0, sizeof (*nalu));
1401 
1402   if (size < offset + 4) {
1403     GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1404         ", offset %u", size, offset);
1405     return GST_H265_PARSER_ERROR;
1406   }
1407 
1408   off1 = scan_for_start_codes (data + offset, size - offset);
1409 
1410   if (off1 < 0) {
1411     GST_DEBUG ("No start code prefix in this buffer");
1412     return GST_H265_PARSER_NO_NAL;
1413   }
1414 
1415   nalu->sc_offset = offset + off1;
1416 
1417   /* The scanner ensures one byte passed the start code but to
1418    * identify an HEVC NAL, we need 2. */
1419   if (size - nalu->sc_offset - 3 < 2) {
1420     GST_DEBUG ("Not enough bytes after start code to identify");
1421     return GST_H265_PARSER_NO_NAL;
1422   }
1423 
1424   /* sc might have 2 or 3 0-bytes */
1425   if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
1426     nalu->sc_offset--;
1427 
1428   nalu->offset = offset + off1 + 3;
1429   nalu->data = (guint8 *) data;
1430   nalu->size = size - nalu->offset;
1431 
1432   if (!gst_h265_parse_nalu_header (nalu)) {
1433     GST_WARNING ("error parsing \"NAL unit header\"");
1434     nalu->size = 0;
1435     return GST_H265_PARSER_BROKEN_DATA;
1436   }
1437 
1438   nalu->valid = TRUE;
1439 
1440   if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB) {
1441     GST_DEBUG ("end-of-seq or end-of-stream nal found");
1442     nalu->size = 2;
1443     return GST_H265_PARSER_OK;
1444   }
1445 
1446   return GST_H265_PARSER_OK;
1447 }
1448 
1449 /**
1450  * gst_h265_parser_identify_nalu:
1451  * @parser: a #GstH265Parser
1452  * @data: The data to parse
1453  * @offset: the offset from which to parse @data
1454  * @size: the size of @data
1455  * @nalu: The #GstH265NalUnit where to store parsed nal headers
1456  *
1457  * Parses @data and fills @nalu from the next nalu data from @data
1458  *
1459  * Returns: a #GstH265ParserResult
1460  */
1461 GstH265ParserResult
gst_h265_parser_identify_nalu(GstH265Parser * parser,const guint8 * data,guint offset,gsize size,GstH265NalUnit * nalu)1462 gst_h265_parser_identify_nalu (GstH265Parser * parser,
1463     const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
1464 {
1465   GstH265ParserResult res;
1466   gint off2;
1467 
1468   res =
1469       gst_h265_parser_identify_nalu_unchecked (parser, data, offset, size,
1470       nalu);
1471 
1472   if (res != GST_H265_PARSER_OK)
1473     goto beach;
1474 
1475   /* The two NALs are exactly 2 bytes size and are placed at the end of an AU,
1476    * there is no need to wait for the following */
1477   if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB)
1478     goto beach;
1479 
1480   off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1481   if (off2 < 0) {
1482     GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1483 
1484     return GST_H265_PARSER_NO_NAL_END;
1485   }
1486 
1487   /* Callers assumes that enough data will available to identify the next NAL,
1488    * but scan_for_start_codes() only ensure 1 extra byte is available. Ensure
1489    * we have the required two header bytes (3 bytes start code and 2 byte
1490    * header). */
1491   if (size - (nalu->offset + off2) < 5) {
1492     GST_DEBUG ("Not enough bytes identify the next NAL.");
1493     return GST_H265_PARSER_NO_NAL_END;
1494   }
1495 
1496   /* Mini performance improvement:
1497    * We could have a way to store how many 0s were skipped to avoid
1498    * parsing them again on the next NAL */
1499   while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1500     off2--;
1501 
1502   nalu->size = off2;
1503   if (nalu->size < 3)
1504     return GST_H265_PARSER_BROKEN_DATA;
1505 
1506   GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1507 
1508 beach:
1509   return res;
1510 }
1511 
1512 /**
1513  * gst_h265_parser_identify_nalu_hevc:
1514  * @parser: a #GstH265Parser
1515  * @data: The data to parse, must be the beging of the Nal unit
1516  * @offset: the offset from which to parse @data
1517  * @size: the size of @data
1518  * @nal_length_size: the size in bytes of the HEVC nal length prefix.
1519  * @nalu: The #GstH265NalUnit where to store parsed nal headers
1520  *
1521  * Parses @data and sets @nalu.
1522  *
1523  * Returns: a #GstH265ParserResult
1524  */
1525 GstH265ParserResult
gst_h265_parser_identify_nalu_hevc(GstH265Parser * parser,const guint8 * data,guint offset,gsize size,guint8 nal_length_size,GstH265NalUnit * nalu)1526 gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
1527     const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1528     GstH265NalUnit * nalu)
1529 {
1530   GstBitReader br;
1531 
1532   memset (nalu, 0, sizeof (*nalu));
1533 
1534   /* Would overflow guint below otherwise: the callers needs to ensure that
1535    * this never happens */
1536   if (offset > G_MAXUINT32 - nal_length_size) {
1537     GST_WARNING ("offset + nal_length_size overflow");
1538     nalu->size = 0;
1539     return GST_H265_PARSER_BROKEN_DATA;
1540   }
1541 
1542   if (size < offset + nal_length_size) {
1543     GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1544         ", offset %u", size, offset);
1545     return GST_H265_PARSER_ERROR;
1546   }
1547 
1548   size = size - offset;
1549   gst_bit_reader_init (&br, data + offset, size);
1550 
1551   nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1552       nal_length_size * 8);
1553   nalu->sc_offset = offset;
1554   nalu->offset = offset + nal_length_size;
1555 
1556   if (nalu->size > G_MAXUINT32 - nal_length_size) {
1557     GST_WARNING ("NALU size + nal_length_size overflow");
1558     nalu->size = 0;
1559     return GST_H265_PARSER_BROKEN_DATA;
1560   }
1561 
1562   if (size < (gsize) nalu->size + nal_length_size) {
1563     nalu->size = 0;
1564 
1565     return GST_H265_PARSER_NO_NAL_END;
1566   }
1567 
1568   nalu->data = (guint8 *) data;
1569 
1570   if (!gst_h265_parse_nalu_header (nalu)) {
1571     GST_WARNING ("error parsing \"NAL unit header\"");
1572     nalu->size = 0;
1573     return GST_H265_PARSER_BROKEN_DATA;
1574   }
1575 
1576   if (nalu->size < 2)
1577     return GST_H265_PARSER_BROKEN_DATA;
1578 
1579   nalu->valid = TRUE;
1580 
1581   return GST_H265_PARSER_OK;
1582 }
1583 
1584 /**
1585  * gst_h265_parser_parse_nal:
1586  * @parser: a #GstH265Parser
1587  * @nalu: The #GstH265NalUnit to parse
1588  *
1589  * This function should be called in the case one doesn't need to
1590  * parse a specific structure. It is necessary to do so to make
1591  * sure @parser is up to date.
1592  *
1593  * Returns: a #GstH265ParserResult
1594  */
1595 GstH265ParserResult
gst_h265_parser_parse_nal(GstH265Parser * parser,GstH265NalUnit * nalu)1596 gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
1597 {
1598   GstH265VPS vps;
1599   GstH265SPS sps;
1600   GstH265PPS pps;
1601 
1602   switch (nalu->type) {
1603     case GST_H265_NAL_VPS:
1604       return gst_h265_parser_parse_vps (parser, nalu, &vps);
1605       break;
1606     case GST_H265_NAL_SPS:
1607       return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
1608       break;
1609     case GST_H265_NAL_PPS:
1610       return gst_h265_parser_parse_pps (parser, nalu, &pps);
1611   }
1612 
1613   return GST_H265_PARSER_OK;
1614 }
1615 
1616 /**
1617  * gst_h265_parser_parse_vps:
1618  * @parser: a #GstH265Parser
1619  * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1620  * @vps: The #GstH265VPS to fill.
1621  *
1622  * Parses @data, and fills the @vps structure.
1623  *
1624  * Returns: a #GstH265ParserResult
1625  */
1626 GstH265ParserResult
gst_h265_parser_parse_vps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265VPS * vps)1627 gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
1628     GstH265VPS * vps)
1629 {
1630   GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);
1631 
1632   if (res == GST_H265_PARSER_OK) {
1633     GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);
1634 
1635     parser->vps[vps->id] = *vps;
1636     parser->last_vps = &parser->vps[vps->id];
1637   }
1638 
1639   return res;
1640 }
1641 
1642 /**
1643  * gst_h265_parse_vps:
1644  * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
1645  * @sps: The #GstH265VPS to fill.
1646  *
1647  * Parses @data, and fills the @vps structure.
1648  *
1649  * Returns: a #GstH265ParserResult
1650  */
1651 GstH265ParserResult
gst_h265_parse_vps(GstH265NalUnit * nalu,GstH265VPS * vps)1652 gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
1653 {
1654   NalReader nr;
1655   guint i, j;
1656 
1657   GST_DEBUG ("parsing VPS");
1658 
1659   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1660       nalu->size - nalu->header_bytes);
1661 
1662   memset (vps, 0, sizeof (*vps));
1663 
1664   vps->cprms_present_flag = 1;
1665 
1666   READ_UINT8 (&nr, vps->id, 4);
1667 
1668   READ_UINT8 (&nr, vps->base_layer_internal_flag, 1);
1669   READ_UINT8 (&nr, vps->base_layer_available_flag, 1);
1670 
1671   READ_UINT8 (&nr, vps->max_layers_minus1, 6);
1672   READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
1673   CHECK_ALLOWED (vps->max_sub_layers_minus1, 0, 6);
1674   READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1675 
1676   /* skip reserved_0xffff_16bits */
1677   if (!nal_reader_skip (&nr, 16))
1678     goto error;
1679 
1680   if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1681           vps->max_sub_layers_minus1))
1682     goto error;
1683 
1684   READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1685 
1686   for (i =
1687       (vps->sub_layer_ordering_info_present_flag ? 0 :
1688           vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1689     READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1690     READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1691         vps->max_dec_pic_buffering_minus1[i]);
1692     READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1693   }
1694   /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1695   if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1696     for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1697       vps->max_dec_pic_buffering_minus1[i] =
1698           vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1699       vps->max_num_reorder_pics[i] =
1700           vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1701       vps->max_latency_increase_plus1[i] =
1702           vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1703     }
1704   }
1705 
1706   READ_UINT8 (&nr, vps->max_layer_id, 6);
1707   /* shall allow 63 */
1708   CHECK_ALLOWED_MAX (vps->max_layer_id, 63);
1709 
1710   READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1711   /* allowed range is 0 to 1023 */
1712   CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 1023);
1713 
1714   for (i = 1; i <= vps->num_layer_sets_minus1; i++) {
1715     for (j = 0; j <= vps->max_layer_id; j++) {
1716       /* layer_id_included_flag[i][j] */
1717       /* FIXME: need to parse this when we can support parsing multi-layer info. */
1718       nal_reader_skip (&nr, 1);
1719     }
1720   }
1721 
1722   READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1723 
1724   if (vps->timing_info_present_flag) {
1725     READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1726     READ_UINT32 (&nr, vps->time_scale, 32);
1727     READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1728 
1729     if (vps->poc_proportional_to_timing_flag)
1730       READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1731 
1732     READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1733     /* allowed range is
1734      * 0 to vps_num_layer_sets_minus1 + 1 */
1735     CHECK_ALLOWED_MAX (vps->num_hrd_parameters, vps->num_layer_sets_minus1 + 1);
1736 
1737     if (vps->num_hrd_parameters) {
1738       READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1739       /* allowed range is
1740        * ( vps_base_layer_internal_flag ? 0 : 1 ) to vps_num_layer_sets_minus1
1741        */
1742       CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, vps->num_layer_sets_minus1);
1743 
1744       if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1745               vps->cprms_present_flag, vps->max_sub_layers_minus1))
1746         goto error;
1747     }
1748 
1749     /* FIXME: VPS can have multiple hrd parameters, and therefore hrd_params
1750      * should be an array (like Garray). But it also requires new _clear()
1751      * method for free the array in GstH265VPS whenever gst_h265_parse_vps()
1752      * is called. Need to work for multi-layer related parsing supporting
1753      *
1754      * FIXME: Following code is just work around to find correct
1755      * vps_extension position */
1756 
1757     /* skip the first parsed one above */
1758     for (i = 1; i < vps->num_hrd_parameters; i++) {
1759       guint16 hrd_layer_set_idx;
1760       guint8 cprms_present_flag;
1761       GstH265HRDParams hrd_params;
1762 
1763       READ_UE_MAX (&nr, hrd_layer_set_idx, 1023);
1764       CHECK_ALLOWED_MAX (hrd_layer_set_idx, vps->num_layer_sets_minus1);
1765 
1766       /* need parsing if (i > 1) */
1767       READ_UINT8 (&nr, cprms_present_flag, 1);
1768 
1769       if (!gst_h265_parse_hrd_parameters (&hrd_params, &nr,
1770               cprms_present_flag, vps->max_sub_layers_minus1))
1771         goto error;
1772     }
1773   }
1774   READ_UINT8 (&nr, vps->vps_extension, 1);
1775   vps->valid = TRUE;
1776 
1777   return GST_H265_PARSER_OK;
1778 
1779 error:
1780   GST_WARNING ("error parsing \"Video parameter set\"");
1781   vps->valid = FALSE;
1782   return GST_H265_PARSER_ERROR;
1783 }
1784 
1785 /**
1786  * gst_h265_parser_parse_sps:
1787  * @parser: a #GstH265Parser
1788  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1789  * @sps: The #GstH265SPS to fill.
1790  * @parse_vui_params: Whether to parse the vui_params or not
1791  *
1792  * Parses @data, and fills the @sps structure.
1793  *
1794  * Returns: a #GstH265ParserResult
1795  */
1796 GstH265ParserResult
gst_h265_parser_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1797 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1798     GstH265SPS * sps, gboolean parse_vui_params)
1799 {
1800   GstH265ParserResult res =
1801       gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1802 
1803   if (res == GST_H265_PARSER_OK) {
1804     GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1805 
1806     parser->sps[sps->id] = *sps;
1807     parser->last_sps = &parser->sps[sps->id];
1808   }
1809 
1810   return res;
1811 }
1812 
1813 /**
1814  * gst_h265_parse_sps:
1815  * parser: The #GstH265Parser
1816  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1817  * @sps: The #GstH265SPS to fill.
1818  * @parse_vui_params: Whether to parse the vui_params or not
1819  *
1820  * Parses @data, and fills the @sps structure.
1821  *
1822  * Returns: a #GstH265ParserResult
1823  */
1824 GstH265ParserResult
gst_h265_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1825 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1826     GstH265SPS * sps, gboolean parse_vui_params)
1827 {
1828   NalReader nr;
1829   GstH265VPS *vps;
1830   guint8 vps_id;
1831   guint i;
1832   guint subwc[] = { 1, 2, 2, 1, 1 };
1833   guint subhc[] = { 1, 2, 1, 1, 1 };
1834   GstH265VUIParams *vui = NULL;
1835 
1836   GST_DEBUG ("parsing SPS");
1837 
1838   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1839       nalu->size - nalu->header_bytes);
1840 
1841   memset (sps, 0, sizeof (*sps));
1842 
1843   READ_UINT8 (&nr, vps_id, 4);
1844   vps = gst_h265_parser_get_vps (parser, vps_id);
1845   if (!vps) {
1846     GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1847         vps_id);
1848   }
1849   sps->vps = vps;
1850 
1851   READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1852   CHECK_ALLOWED (sps->max_sub_layers_minus1, 0, 6);
1853   READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1854 
1855   if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1856           sps->max_sub_layers_minus1))
1857     goto error;
1858 
1859   READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1860 
1861   READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1862   if (sps->chroma_format_idc == 3)
1863     READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1864 
1865   READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1866   READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1867 
1868   READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1869   if (sps->conformance_window_flag) {
1870     READ_UE (&nr, sps->conf_win_left_offset);
1871     READ_UE (&nr, sps->conf_win_right_offset);
1872     READ_UE (&nr, sps->conf_win_top_offset);
1873     READ_UE (&nr, sps->conf_win_bottom_offset);
1874   }
1875 
1876   READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1877   READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1878   READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1879 
1880   READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1881   for (i =
1882       (sps->sub_layer_ordering_info_present_flag ? 0 :
1883           sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1884     READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1885     READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1886         sps->max_dec_pic_buffering_minus1[i]);
1887     READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1888   }
1889   /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1890   if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1891     for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1892       sps->max_dec_pic_buffering_minus1[i] =
1893           sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1894       sps->max_num_reorder_pics[i] =
1895           sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1896       sps->max_latency_increase_plus1[i] =
1897           sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1898     }
1899   }
1900 
1901   /* The limits are calculted based on the profile_tier_level constraint
1902    * in Annex-A: CtbLog2SizeY = 4 to 6 */
1903   READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1904   READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1905   READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1906   READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1907   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1908   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1909 
1910   READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1911   if (sps->scaling_list_enabled_flag) {
1912     READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1913 
1914     if (sps->scaling_list_data_present_flag)
1915       if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1916         goto error;
1917   }
1918 
1919   READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1920   READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1921   READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1922 
1923   if (sps->pcm_enabled_flag) {
1924     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1925     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1926     READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1927     READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1928     READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1929   }
1930 
1931   READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1932   for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1933     if (!gst_h265_parser_parse_short_term_ref_pic_sets
1934         (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1935       goto error;
1936 
1937   READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1938   if (sps->long_term_ref_pics_present_flag) {
1939     READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1940     for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1941       READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1942           sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1943       READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1944     }
1945   }
1946 
1947   READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1948   READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1949   READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1950 
1951   if (sps->vui_parameters_present_flag && parse_vui_params) {
1952     if (!gst_h265_parse_vui_parameters (sps, &nr))
1953       goto error;
1954     vui = &sps->vui_params;
1955   }
1956 
1957   READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1958 
1959   if (sps->sps_extension_flag) {
1960     READ_UINT8 (&nr, sps->sps_range_extension_flag, 1);
1961     READ_UINT8 (&nr, sps->sps_multilayer_extension_flag, 1);
1962     READ_UINT8 (&nr, sps->sps_3d_extension_flag, 1);
1963     READ_UINT8 (&nr, sps->sps_scc_extension_flag, 1);
1964     READ_UINT8 (&nr, sps->sps_extension_4bits, 4);
1965   }
1966 
1967   if (sps->sps_range_extension_flag) {
1968     READ_UINT8 (&nr,
1969         sps->sps_extnsion_params.transform_skip_rotation_enabled_flag, 1);
1970     READ_UINT8 (&nr,
1971         sps->sps_extnsion_params.transform_skip_context_enabled_flag, 1);
1972     READ_UINT8 (&nr, sps->sps_extnsion_params.implicit_rdpcm_enabled_flag, 1);
1973     READ_UINT8 (&nr, sps->sps_extnsion_params.explicit_rdpcm_enabled_flag, 1);
1974     READ_UINT8 (&nr,
1975         sps->sps_extnsion_params.extended_precision_processing_flag, 1);
1976     READ_UINT8 (&nr, sps->sps_extnsion_params.intra_smoothing_disabled_flag, 1);
1977     READ_UINT8 (&nr,
1978         sps->sps_extnsion_params.high_precision_offsets_enabled_flag, 1);
1979     READ_UINT8 (&nr,
1980         sps->sps_extnsion_params.persistent_rice_adaptation_enabled_flag, 1);
1981     READ_UINT8 (&nr,
1982         sps->sps_extnsion_params.cabac_bypass_alignment_enabled_flag, 1);
1983   }
1984 
1985   if (sps->sps_multilayer_extension_flag) {
1986     GST_WARNING ("do not support multilayer extension, skip all"
1987         " remaining bits");
1988     goto done;
1989   }
1990   if (sps->sps_3d_extension_flag) {
1991     GST_WARNING ("do not support 3d extension, skip all remaining bits");
1992     goto done;
1993   }
1994 
1995   if (sps->sps_scc_extension_flag) {
1996     READ_UINT8 (&nr,
1997         sps->sps_scc_extension_params.sps_curr_pic_ref_enabled_flag, 1);
1998     READ_UINT8 (&nr, sps->sps_scc_extension_params.palette_mode_enabled_flag,
1999         1);
2000     if (sps->sps_scc_extension_params.palette_mode_enabled_flag) {
2001       READ_UE_MAX (&nr, sps->sps_scc_extension_params.palette_max_size, 64);
2002       READ_UE_MAX (&nr,
2003           sps->sps_scc_extension_params.delta_palette_max_predictor_size,
2004           128 - sps->sps_scc_extension_params.palette_max_size);
2005 
2006       READ_UINT8 (&nr,
2007           sps->sps_scc_extension_params.
2008           sps_palette_predictor_initializers_present_flag, 1);
2009       if (sps->sps_scc_extension_params.
2010           sps_palette_predictor_initializers_present_flag) {
2011         guint comp;
2012         READ_UE_MAX (&nr,
2013             sps->sps_scc_extension_params.
2014             sps_num_palette_predictor_initializer_minus1,
2015             sps->sps_scc_extension_params.palette_max_size +
2016             sps->sps_scc_extension_params.delta_palette_max_predictor_size - 1);
2017 
2018         for (comp = 0; comp < (sps->chroma_format_idc == 0 ? 1 : 3); comp++) {
2019           guint num_bits;
2020           guint num =
2021               sps->sps_scc_extension_params.
2022               sps_num_palette_predictor_initializer_minus1 + 1;
2023 
2024           num_bits = (comp == 0 ? sps->bit_depth_luma_minus8 + 8 :
2025               sps->bit_depth_chroma_minus8 + 8);
2026           for (i = 0; i < num; i++)
2027             READ_UINT32 (&nr,
2028                 sps->sps_scc_extension_params.sps_palette_predictor_initializer
2029                 [comp]
2030                 [i], num_bits);
2031         }
2032       }
2033     }
2034 
2035     READ_UINT8 (&nr,
2036         sps->sps_scc_extension_params.motion_vector_resolution_control_idc, 2);
2037     READ_UINT8 (&nr,
2038         sps->sps_scc_extension_params.intra_boundary_filtering_disabled_flag,
2039         1);
2040   }
2041 
2042 done:
2043   /* calculate ChromaArrayType */
2044   if (!sps->separate_colour_plane_flag)
2045     sps->chroma_array_type = sps->chroma_format_idc;
2046 
2047   /* Calculate  width and height */
2048   sps->width = sps->pic_width_in_luma_samples;
2049   sps->height = sps->pic_height_in_luma_samples;
2050   if (sps->width < 0 || sps->height < 0) {
2051     GST_WARNING ("invalid width/height in SPS");
2052     goto error;
2053   }
2054 
2055   if (sps->conformance_window_flag) {
2056     const guint crop_unit_x = subwc[sps->chroma_format_idc];
2057     const guint crop_unit_y = subhc[sps->chroma_format_idc];
2058 
2059     sps->crop_rect_width = sps->width -
2060         (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
2061     sps->crop_rect_height = sps->height -
2062         (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
2063     sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
2064     sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
2065 
2066     GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
2067         sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
2068   }
2069 
2070   sps->fps_num = 0;
2071   sps->fps_den = 1;
2072 
2073   if (vui && vui->timing_info_present_flag) {
2074     /* derive framerate for progressive stream if the pic_struct
2075      * syntax element is not present in picture timing SEI messages */
2076     /* Fixme: handle other cases also */
2077     if (parse_vui_params && vui->timing_info_present_flag
2078         && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
2079       sps->fps_num = vui->time_scale;
2080       sps->fps_den = vui->num_units_in_tick;
2081       GST_LOG ("framerate %d/%d in VUI", sps->fps_num, sps->fps_den);
2082     }
2083   } else if (vps && vps->timing_info_present_flag) {
2084     sps->fps_num = vps->time_scale;
2085     sps->fps_den = vps->num_units_in_tick;
2086     GST_LOG ("framerate %d/%d in VPS", sps->fps_num, sps->fps_den);
2087   } else {
2088     GST_LOG ("No VUI, unknown framerate");
2089   }
2090 
2091   sps->valid = TRUE;
2092 
2093   return GST_H265_PARSER_OK;
2094 
2095 error:
2096   GST_WARNING ("error parsing \"Sequence parameter set\"");
2097   sps->valid = FALSE;
2098   return GST_H265_PARSER_ERROR;
2099 }
2100 
2101 /**
2102  * gst_h265_parse_pps:
2103  * @parser: a #GstH265Parser
2104  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2105  * @pps: The #GstH265PPS to fill.
2106  *
2107  * Parses @data, and fills the @pps structure.
2108  *
2109  * Returns: a #GstH265ParserResult
2110  */
2111 GstH265ParserResult
gst_h265_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2112 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
2113     GstH265PPS * pps)
2114 {
2115   NalReader nr;
2116   GstH265SPS *sps;
2117   gint sps_id;
2118   gint qp_bd_offset;
2119   guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY, MaxBitDepthY, MaxBitDepthC;
2120   guint8 i;
2121 
2122   GST_DEBUG ("parsing PPS");
2123 
2124   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2125       nalu->size - nalu->header_bytes);
2126 
2127   memset (pps, 0, sizeof (*pps));
2128 
2129   READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
2130   READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
2131 
2132   sps = gst_h265_parser_get_sps (parser, sps_id);
2133   if (!sps) {
2134     GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
2135         sps_id);
2136     return GST_H265_PARSER_BROKEN_LINK;
2137   }
2138   pps->sps = sps;
2139   qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
2140 
2141   MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
2142   CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
2143   CtbSizeY = 1 << CtbLog2SizeY;
2144   pps->PicHeightInCtbsY =
2145       ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
2146   pps->PicWidthInCtbsY =
2147       ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
2148 
2149   /* set default values for fields that might not be present in the bitstream
2150      and have valid defaults */
2151   pps->uniform_spacing_flag = 1;
2152   pps->loop_filter_across_tiles_enabled_flag = 1;
2153 
2154   READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
2155   READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
2156   READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
2157   READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
2158   READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
2159 
2160   READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
2161   READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
2162   READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
2163 
2164   READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
2165   READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
2166 
2167   READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
2168   if (pps->cu_qp_delta_enabled_flag)
2169     READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
2170         sps->log2_diff_max_min_luma_coding_block_size);
2171 
2172   READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
2173   READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
2174 
2175   READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
2176   READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
2177   READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
2178   READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
2179   READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
2180   READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
2181 
2182   if (pps->tiles_enabled_flag) {
2183     READ_UE_ALLOWED (&nr,
2184         pps->num_tile_columns_minus1, 0, pps->PicWidthInCtbsY - 1);
2185     READ_UE_ALLOWED (&nr,
2186         pps->num_tile_rows_minus1, 0, pps->PicHeightInCtbsY - 1);
2187 
2188     if (pps->num_tile_columns_minus1 + 1 >
2189         G_N_ELEMENTS (pps->column_width_minus1)) {
2190       GST_WARNING ("Invalid \"num_tile_columns_minus1\" %d",
2191           pps->num_tile_columns_minus1);
2192       goto error;
2193     }
2194 
2195     if (pps->num_tile_rows_minus1 + 1 > G_N_ELEMENTS (pps->row_height_minus1)) {
2196       GST_WARNING ("Invalid \"num_tile_rows_minus1\" %d",
2197           pps->num_tile_rows_minus1);
2198       goto error;
2199     }
2200 
2201     READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
2202     /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
2203     if (pps->uniform_spacing_flag) {
2204       guint8 num_col = pps->num_tile_columns_minus1 + 1;
2205       guint8 num_row = pps->num_tile_rows_minus1 + 1;
2206       for (i = 0; i < num_col; i++) {
2207         pps->column_width_minus1[i] =
2208             ((i + 1) * pps->PicWidthInCtbsY / num_col
2209             - i * pps->PicWidthInCtbsY / num_col) - 1;
2210       }
2211       for (i = 0; i < num_row; i++) {
2212         pps->row_height_minus1[i] =
2213             ((i + 1) * pps->PicHeightInCtbsY / num_row
2214             - i * pps->PicHeightInCtbsY / num_row) - 1;
2215       }
2216     } else {
2217       pps->column_width_minus1[pps->num_tile_columns_minus1] =
2218           pps->PicWidthInCtbsY - 1;
2219       for (i = 0; i < pps->num_tile_columns_minus1; i++) {
2220         READ_UE (&nr, pps->column_width_minus1[i]);
2221         pps->column_width_minus1[pps->num_tile_columns_minus1] -=
2222             (pps->column_width_minus1[i] + 1);
2223       }
2224 
2225       pps->row_height_minus1[pps->num_tile_rows_minus1] =
2226           pps->PicHeightInCtbsY - 1;
2227       for (i = 0; i < pps->num_tile_rows_minus1; i++) {
2228         READ_UE (&nr, pps->row_height_minus1[i]);
2229         pps->row_height_minus1[pps->num_tile_rows_minus1] -=
2230             (pps->row_height_minus1[i] + 1);
2231       }
2232     }
2233     READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
2234   }
2235 
2236   READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
2237 
2238   READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
2239   if (pps->deblocking_filter_control_present_flag) {
2240     READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
2241 
2242     READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
2243     if (!pps->deblocking_filter_disabled_flag) {
2244       READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
2245       READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
2246     }
2247   }
2248 
2249   READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
2250   if (pps->scaling_list_data_present_flag)
2251     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
2252       goto error;
2253   if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
2254       && !pps->scaling_list_data_present_flag)
2255     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
2256       goto error;
2257 
2258   READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
2259   READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
2260   READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
2261   READ_UINT8 (&nr, pps->pps_extension_flag, 1);
2262 
2263   if (pps->pps_extension_flag) {
2264     READ_UINT8 (&nr, pps->pps_range_extension_flag, 1);
2265     READ_UINT8 (&nr, pps->pps_multilayer_extension_flag, 1);
2266     READ_UINT8 (&nr, pps->pps_3d_extension_flag, 1);
2267     READ_UINT8 (&nr, pps->pps_scc_extension_flag, 1);
2268     READ_UINT8 (&nr, pps->pps_extension_4bits, 4);
2269   }
2270 
2271   if (pps->pps_range_extension_flag) {
2272     if (pps->transform_skip_enabled_flag)
2273       READ_UE (&nr,
2274           pps->pps_extension_params.log2_max_transform_skip_block_size_minus2);
2275     READ_UINT8 (&nr,
2276         pps->pps_extension_params.cross_component_prediction_enabled_flag, 1);
2277     READ_UINT8 (&nr,
2278         pps->pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
2279     if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag) {
2280       READ_UE_MAX (&nr,
2281           pps->pps_extension_params.diff_cu_chroma_qp_offset_depth,
2282           sps->log2_diff_max_min_luma_coding_block_size);
2283       READ_UE_MAX (&nr,
2284           pps->pps_extension_params.chroma_qp_offset_list_len_minus1, 5);
2285       for (i = 0;
2286           i <= pps->pps_extension_params.chroma_qp_offset_list_len_minus1;
2287           i++) {
2288         READ_SE_ALLOWED (&nr, pps->pps_extension_params.cb_qp_offset_list[i],
2289             -12, 12);
2290         READ_SE_ALLOWED (&nr, pps->pps_extension_params.cr_qp_offset_list[i],
2291             -12, 12);
2292       }
2293     }
2294     MaxBitDepthY =
2295         sps->bit_depth_luma_minus8 > 2 ? sps->bit_depth_luma_minus8 - 2 : 0;
2296     MaxBitDepthC =
2297         sps->bit_depth_chroma_minus8 > 2 ? sps->bit_depth_chroma_minus8 - 2 : 0;
2298     READ_UE_ALLOWED (&nr, pps->pps_extension_params.log2_sao_offset_scale_luma,
2299         0, MaxBitDepthY);
2300     READ_UE_ALLOWED (&nr,
2301         pps->pps_extension_params.log2_sao_offset_scale_chroma, 0,
2302         MaxBitDepthC);
2303   }
2304 
2305   if (pps->pps_multilayer_extension_flag) {
2306     GST_WARNING ("do not support multilayer extension, skip all"
2307         " remaining bits");
2308     goto done;
2309   }
2310   if (pps->pps_3d_extension_flag) {
2311     GST_WARNING ("do not support 3d extension, skip all remaining bits");
2312     goto done;
2313   }
2314 
2315   if (pps->pps_scc_extension_flag) {
2316     READ_UINT8 (&nr,
2317         pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag, 1);
2318     READ_UINT8 (&nr,
2319         pps->pps_scc_extension_params.
2320         residual_adaptive_colour_transform_enabled_flag, 1);
2321     if (pps->pps_scc_extension_params.
2322         residual_adaptive_colour_transform_enabled_flag) {
2323       READ_UINT8 (&nr,
2324           pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag,
2325           1);
2326       READ_SE_ALLOWED (&nr,
2327           pps->pps_scc_extension_params.pps_act_y_qp_offset_plus5, -7, 17);
2328       READ_SE_ALLOWED (&nr,
2329           pps->pps_scc_extension_params.pps_act_cb_qp_offset_plus5, -7, 17);
2330       READ_SE_ALLOWED (&nr,
2331           pps->pps_scc_extension_params.pps_act_cr_qp_offset_plus3, -9, 15);
2332     }
2333 
2334     READ_UINT8 (&nr,
2335         pps->pps_scc_extension_params.
2336         pps_palette_predictor_initializers_present_flag, 1);
2337     if (pps->pps_scc_extension_params.
2338         pps_palette_predictor_initializers_present_flag) {
2339       READ_UE_MAX (&nr,
2340           pps->pps_scc_extension_params.pps_num_palette_predictor_initializer,
2341           sps->sps_scc_extension_params.palette_max_size +
2342           sps->sps_scc_extension_params.delta_palette_max_predictor_size);
2343       if (pps->pps_scc_extension_params.pps_num_palette_predictor_initializer >
2344           0) {
2345         guint comp;
2346 
2347         READ_UINT8 (&nr, pps->pps_scc_extension_params.monochrome_palette_flag,
2348             1);
2349         /* It is a requirement of bitstream conformance that the value of
2350            luma_bit_depth_entry_minus8 shall be equal to the value of
2351            bit_depth_luma_minus8 */
2352         READ_UE_ALLOWED (&nr,
2353             pps->pps_scc_extension_params.luma_bit_depth_entry_minus8,
2354             sps->bit_depth_luma_minus8, sps->bit_depth_luma_minus8);
2355         if (!pps->pps_scc_extension_params.monochrome_palette_flag) {
2356           /* It is a requirement of bitstream conformance that the value
2357              of chroma_bit_depth_entry_minus8 shall be equal to the value
2358              of bit_depth_chroma_minus8. */
2359           READ_UE_ALLOWED (&nr,
2360               pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8,
2361               sps->bit_depth_chroma_minus8, sps->bit_depth_chroma_minus8);
2362         }
2363 
2364         for (comp = 0; comp <
2365             (pps->pps_scc_extension_params.monochrome_palette_flag ? 1 : 3);
2366             comp++) {
2367           guint num_bits;
2368           guint num =
2369               pps->pps_scc_extension_params.
2370               pps_num_palette_predictor_initializer;
2371 
2372           num_bits = (comp == 0 ?
2373               pps->pps_scc_extension_params.luma_bit_depth_entry_minus8 + 8 :
2374               pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8 + 8);
2375           for (i = 0; i < num; i++)
2376             READ_UINT32 (&nr,
2377                 pps->pps_scc_extension_params.pps_palette_predictor_initializer
2378                 [comp][i], num_bits);
2379         }
2380       }
2381     }
2382   }
2383 
2384 done:
2385   pps->valid = TRUE;
2386   return GST_H265_PARSER_OK;
2387 
2388 error:
2389   GST_WARNING ("error parsing \"Picture parameter set\"");
2390   pps->valid = FALSE;
2391   return GST_H265_PARSER_ERROR;
2392 }
2393 
2394 /**
2395  * gst_h265_parser_parse_pps:
2396  * @parser: a #GstH265Parser
2397  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2398  * @pps: The #GstH265PPS to fill.
2399  *
2400  * Parses @data, and fills the @pps structure.
2401  *
2402  * Returns: a #GstH265ParserResult
2403  */
2404 GstH265ParserResult
gst_h265_parser_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2405 gst_h265_parser_parse_pps (GstH265Parser * parser,
2406     GstH265NalUnit * nalu, GstH265PPS * pps)
2407 {
2408   GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
2409   if (res == GST_H265_PARSER_OK) {
2410     GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
2411 
2412     parser->pps[pps->id] = *pps;
2413     parser->last_pps = &parser->pps[pps->id];
2414   }
2415 
2416   return res;
2417 }
2418 
2419 /**
2420  * gst_h265_parser_parse_slice_hdr:
2421  * @parser: a #GstH265Parser
2422  * @nalu: The `GST_H265_NAL_SLICE` #GstH265NalUnit to parse
2423  * @slice: The #GstH265SliceHdr to fill.
2424  *
2425  * Parses @data, and fills the @slice structure.
2426  * The resulting @slice_hdr structure shall be deallocated with
2427  * gst_h265_slice_hdr_free() when it is no longer needed
2428  *
2429  * Returns: a #GstH265ParserResult
2430  */
2431 GstH265ParserResult
gst_h265_parser_parse_slice_hdr(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SliceHdr * slice)2432 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
2433     GstH265NalUnit * nalu, GstH265SliceHdr * slice)
2434 {
2435   NalReader nr;
2436   gint pps_id;
2437   GstH265PPS *pps;
2438   GstH265SPS *sps;
2439   guint i;
2440   GstH265ShortTermRefPicSet *stRPS = NULL;
2441   guint32 UsedByCurrPicLt[16];
2442   guint32 PicSizeInCtbsY;
2443   gint NumPocTotalCurr = 0;
2444 
2445   memset (slice, 0, sizeof (*slice));
2446 
2447   if (!nalu->size) {
2448     GST_DEBUG ("Invalid Nal Unit");
2449     return GST_H265_PARSER_ERROR;
2450   }
2451 
2452   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2453       nalu->size - nalu->header_bytes);
2454 
2455   GST_DEBUG ("parsing \"Slice header\", slice type");
2456 
2457   READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
2458 
2459   if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type))
2460     READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
2461 
2462   READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
2463   pps = gst_h265_parser_get_pps (parser, pps_id);
2464   if (!pps) {
2465     GST_WARNING
2466         ("couldn't find associated picture parameter set with id: %d", pps_id);
2467     return GST_H265_PARSER_BROKEN_LINK;
2468   }
2469 
2470   slice->pps = pps;
2471   sps = pps->sps;
2472   if (!sps) {
2473     GST_WARNING
2474         ("couldn't find associated sequence parameter set with id: %d",
2475         pps->id);
2476     return GST_H265_PARSER_BROKEN_LINK;
2477   }
2478 
2479   PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
2480   /* set default values for fields that might not be present in the bitstream
2481    * and have valid defaults */
2482   slice->pic_output_flag = 1;
2483   slice->collocated_from_l0_flag = 1;
2484   slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
2485   slice->beta_offset_div2 = pps->beta_offset_div2;
2486   slice->tc_offset_div2 = pps->tc_offset_div2;
2487   slice->loop_filter_across_slices_enabled_flag =
2488       pps->loop_filter_across_slices_enabled_flag;
2489 
2490   if (!slice->first_slice_segment_in_pic_flag) {
2491     const guint n = ceil_log2 (PicSizeInCtbsY);
2492 
2493     if (pps->dependent_slice_segments_enabled_flag)
2494       READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
2495     /* sice_segment_address parsing */
2496     READ_UINT32 (&nr, slice->segment_address, n);
2497   }
2498 
2499   if (!slice->dependent_slice_segment_flag) {
2500     for (i = 0; i < pps->num_extra_slice_header_bits; i++)
2501       nal_reader_skip (&nr, 1);
2502     READ_UE_MAX (&nr, slice->type, 63);
2503 
2504 
2505     if (pps->output_flag_present_flag)
2506       READ_UINT8 (&nr, slice->pic_output_flag, 1);
2507     if (sps->separate_colour_plane_flag == 1)
2508       READ_UINT8 (&nr, slice->colour_plane_id, 2);
2509 
2510     if (!GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
2511       READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
2512           (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2513 
2514       READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
2515       if (!slice->short_term_ref_pic_set_sps_flag) {
2516         guint pos = nal_reader_get_pos (&nr);
2517         if (!gst_h265_parser_parse_short_term_ref_pic_sets
2518             (&slice->short_term_ref_pic_sets, &nr,
2519                 sps->num_short_term_ref_pic_sets, sps))
2520           goto error;
2521 
2522         slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
2523       } else if (sps->num_short_term_ref_pic_sets > 1) {
2524         const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
2525         READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
2526         CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
2527             sps->num_short_term_ref_pic_sets - 1);
2528       }
2529 
2530       if (sps->long_term_ref_pics_present_flag) {
2531         guint32 limit;
2532 
2533         if (sps->num_long_term_ref_pics_sps > 0)
2534           READ_UE_MAX (&nr, slice->num_long_term_sps,
2535               sps->num_long_term_ref_pics_sps);
2536 
2537         READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2538         limit = slice->num_long_term_sps + slice->num_long_term_pics;
2539         for (i = 0; i < limit; i++) {
2540           if (i < slice->num_long_term_sps) {
2541             if (sps->num_long_term_ref_pics_sps > 1) {
2542               const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2543               READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2544             }
2545           } else {
2546             READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2547                 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2548             READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2549           }
2550 
2551           /* calculate UsedByCurrPicLt */
2552           if (i < slice->num_long_term_sps)
2553             UsedByCurrPicLt[i] =
2554                 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2555           else
2556             UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2557           READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2558           if (slice->delta_poc_msb_present_flag[i])
2559             READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2560         }
2561       }
2562       if (sps->temporal_mvp_enabled_flag)
2563         READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2564     }
2565 
2566     if (sps->sample_adaptive_offset_enabled_flag) {
2567       READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2568       if (sps->chroma_array_type)
2569         READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2570     }
2571 
2572     if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2573       READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2574 
2575       if (slice->num_ref_idx_active_override_flag) {
2576         READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2577         if (GST_H265_IS_B_SLICE (slice))
2578           READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2579       } else {
2580         /*set default values */
2581         slice->num_ref_idx_l0_active_minus1 =
2582             pps->num_ref_idx_l0_default_active_minus1;
2583         slice->num_ref_idx_l1_active_minus1 =
2584             pps->num_ref_idx_l1_default_active_minus1;
2585       }
2586 
2587       /* calculate NumPocTotalCurr */
2588       if (slice->short_term_ref_pic_set_sps_flag)
2589         stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2590       else
2591         stRPS = &slice->short_term_ref_pic_sets;
2592 
2593       for (i = 0; i < stRPS->NumNegativePics; i++)
2594         if (stRPS->UsedByCurrPicS0[i])
2595           NumPocTotalCurr++;
2596       for (i = 0; i < stRPS->NumPositivePics; i++)
2597         if (stRPS->UsedByCurrPicS1[i])
2598           NumPocTotalCurr++;
2599       for (i = 0;
2600           i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2601         if (UsedByCurrPicLt[i])
2602           NumPocTotalCurr++;
2603       slice->NumPocTotalCurr = NumPocTotalCurr;
2604 
2605       if (pps->lists_modification_present_flag) {
2606         if (NumPocTotalCurr > 1)
2607           if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2608                   NumPocTotalCurr))
2609             goto error;
2610       }
2611 
2612       if (GST_H265_IS_B_SLICE (slice))
2613         READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2614       if (pps->cabac_init_present_flag)
2615         READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2616       if (slice->temporal_mvp_enabled_flag) {
2617         if (GST_H265_IS_B_SLICE (slice))
2618           READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2619 
2620         if ((slice->collocated_from_l0_flag
2621                 && slice->num_ref_idx_l0_active_minus1 > 0)
2622             || (!slice->collocated_from_l0_flag
2623                 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2624 
2625           /*fixme: add optimization */
2626           if ((GST_H265_IS_P_SLICE (slice))
2627               || ((GST_H265_IS_B_SLICE (slice))
2628                   && (slice->collocated_from_l0_flag))) {
2629             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2630                 slice->num_ref_idx_l0_active_minus1);
2631           } else if ((GST_H265_IS_B_SLICE (slice))
2632               && (!slice->collocated_from_l0_flag)) {
2633             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2634                 slice->num_ref_idx_l1_active_minus1);
2635           }
2636         }
2637       }
2638       if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2639           (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2640         if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2641           goto error;
2642       READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2643 
2644       if (sps->sps_scc_extension_params.motion_vector_resolution_control_idc
2645           == 2)
2646         READ_UINT8 (&nr, slice->use_integer_mv_flag, 1);
2647     }
2648 
2649     READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2650     if (pps->slice_chroma_qp_offsets_present_flag) {
2651       READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2652       READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2653     }
2654 
2655     if (pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag) {
2656       READ_SE_ALLOWED (&nr, slice->slice_act_y_qp_offset, -12, 12);
2657       READ_SE_ALLOWED (&nr, slice->slice_act_cb_qp_offset, -12, 12);
2658       READ_SE_ALLOWED (&nr, slice->slice_act_cr_qp_offset, -12, 12);
2659     }
2660 
2661     if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag)
2662       READ_UINT8 (&nr, slice->cu_chroma_qp_offset_enabled_flag, 1);
2663 
2664     if (pps->deblocking_filter_override_enabled_flag)
2665       READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2666     if (slice->deblocking_filter_override_flag) {
2667       READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2668       if (!slice->deblocking_filter_disabled_flag) {
2669         READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2670         READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2671       }
2672     }
2673 
2674     if (pps->loop_filter_across_slices_enabled_flag &&
2675         (slice->sao_luma_flag || slice->sao_chroma_flag ||
2676             !slice->deblocking_filter_disabled_flag))
2677       READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2678   }
2679 
2680   if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2681     guint32 offset_max;
2682 
2683     if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2684       offset_max = pps->PicHeightInCtbsY - 1;
2685     else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2686       offset_max =
2687           (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2688           1;
2689     else
2690       offset_max =
2691           (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2692 
2693     READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2694     if (slice->num_entry_point_offsets > 0) {
2695       READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2696       slice->entry_point_offset_minus1 =
2697           g_new0 (guint32, slice->num_entry_point_offsets);
2698       for (i = 0; i < slice->num_entry_point_offsets; i++)
2699         READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2700             (slice->offset_len_minus1 + 1));
2701     }
2702   }
2703 
2704   if (pps->slice_segment_header_extension_present_flag) {
2705     guint16 slice_segment_header_extension_length;
2706     READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2707     for (i = 0; i < slice_segment_header_extension_length; i++)
2708       if (!nal_reader_skip (&nr, 8))
2709         goto error;
2710   }
2711 
2712   /* Skip the byte alignment bits */
2713   if (!nal_reader_skip (&nr, 1))
2714     goto error;
2715   while (!nal_reader_is_byte_aligned (&nr)) {
2716     if (!nal_reader_skip (&nr, 1))
2717       goto error;
2718   }
2719 
2720   slice->header_size = nal_reader_get_pos (&nr);
2721   slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2722 
2723   return GST_H265_PARSER_OK;
2724 
2725 error:
2726   GST_WARNING ("error parsing \"Slice header\"");
2727 
2728   gst_h265_slice_hdr_free (slice);
2729 
2730   return GST_H265_PARSER_ERROR;
2731 }
2732 
2733 static gboolean
nal_reader_has_more_data_in_payload(NalReader * nr,guint32 payload_start_pos_bit,guint32 payloadSize)2734 nal_reader_has_more_data_in_payload (NalReader * nr,
2735     guint32 payload_start_pos_bit, guint32 payloadSize)
2736 {
2737   if (nal_reader_is_byte_aligned (nr) &&
2738       (nal_reader_get_pos (nr) >= (payload_start_pos_bit + 8 * payloadSize)))
2739     return FALSE;
2740 
2741   return TRUE;
2742 }
2743 
2744 static GstH265ParserResult
gst_h265_parser_parse_sei_message(GstH265Parser * parser,guint8 nal_type,NalReader * nr,GstH265SEIMessage * sei)2745 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2746     guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2747 {
2748   guint32 payloadSize;
2749   guint8 payload_type_byte, payload_size_byte;
2750   guint remaining, payload_size;
2751   guint32 payload_start_pos_bit;
2752   GstH265ParserResult res = GST_H265_PARSER_OK;
2753 
2754   GST_DEBUG ("parsing \"Sei message\"");
2755 
2756   memset (sei, 0, sizeof (*sei));
2757 
2758   do {
2759     READ_UINT8 (nr, payload_type_byte, 8);
2760     sei->payloadType += payload_type_byte;
2761   } while (payload_type_byte == 0xff);
2762   payloadSize = 0;
2763   do {
2764     READ_UINT8 (nr, payload_size_byte, 8);
2765     payloadSize += payload_size_byte;
2766   }
2767   while (payload_size_byte == 0xff);
2768 
2769   remaining = nal_reader_get_remaining (nr);
2770   payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
2771 
2772   payload_start_pos_bit = nal_reader_get_pos (nr);
2773   GST_DEBUG
2774       ("SEI message received: payloadType  %u, payloadSize = %u bits",
2775       sei->payloadType, payload_size);
2776 
2777   if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2778     switch (sei->payloadType) {
2779       case GST_H265_SEI_BUF_PERIOD:
2780         /* size not set; might depend on emulation_prevention_three_byte */
2781         res = gst_h265_parser_parse_buffering_period (parser,
2782             &sei->payload.buffering_period, nr);
2783         break;
2784       case GST_H265_SEI_PIC_TIMING:
2785         /* size not set; might depend on emulation_prevention_three_byte */
2786         res = gst_h265_parser_parse_pic_timing (parser,
2787             &sei->payload.pic_timing, nr);
2788         break;
2789       case GST_H265_SEI_REGISTERED_USER_DATA:
2790         res = gst_h265_parser_parse_registered_user_data (parser,
2791             &sei->payload.registered_user_data, nr, payload_size >> 3);
2792         break;
2793       case GST_H265_SEI_RECOVERY_POINT:
2794         res = gst_h265_parser_parse_recovery_point (parser,
2795             &sei->payload.recovery_point, nr);
2796         break;
2797       case GST_H265_SEI_TIME_CODE:
2798         res = gst_h265_parser_parse_time_code (parser,
2799             &sei->payload.time_code, nr);
2800         break;
2801       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
2802         res = gst_h265_parser_parse_mastering_display_colour_volume (parser,
2803             &sei->payload.mastering_display_colour_volume, nr);
2804         break;
2805       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
2806         res = gst_h265_parser_parse_content_light_level_info (parser,
2807             &sei->payload.content_light_level, nr);
2808         break;
2809       default:
2810         /* Just consume payloadSize bytes, which does not account for
2811            emulation prevention bytes */
2812         if (!nal_reader_skip_long (nr, payload_size))
2813           goto error;
2814         res = GST_H265_PARSER_OK;
2815         break;
2816     }
2817   } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2818     switch (sei->payloadType) {
2819       default:
2820         /* Just consume payloadSize bytes, which does not account for
2821            emulation prevention bytes */
2822         if (!nal_reader_skip_long (nr, payload_size))
2823           goto error;
2824         res = GST_H265_PARSER_OK;
2825         break;
2826     }
2827   }
2828 
2829   /* Not parsing the reserved_payload_extension, but it shouldn't be
2830    * an issue because of 1: There shall not be any reserved_payload_extension
2831    * present in bitstreams conforming to the specification.2. Even though
2832    * it is present, the size will be less than total PayloadSize since the
2833    * size of reserved_payload_extension is supposed to be
2834    * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2835    * the current implementation will still skip all unnecessary bits correctly.
2836    * In theory, we can have a more optimized implementation by skipping the
2837    * data left in PayLoadSize without out individually checking for each bits,
2838    * since the totoal size will be always less than payloadSize*/
2839   while (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
2840           payloadSize)) {
2841     /* Skip the byte alignment bits */
2842     if (!nal_reader_skip (nr, 1))
2843       goto error;
2844     while (!nal_reader_is_byte_aligned (nr)) {
2845       if (!nal_reader_skip (nr, 1))
2846         goto error;
2847     }
2848   }
2849 
2850   return res;
2851 
2852 error:
2853   GST_WARNING ("error parsing \"Sei message\"");
2854   return GST_H265_PARSER_ERROR;
2855 }
2856 
2857 /**
2858  * gst_h265_slice_hdr_copy:
2859  * @dst_slice: The destination #GstH265SliceHdr to copy into
2860  * @src_slice: The source #GstH265SliceHdr to copy from
2861  *
2862  * Copies @src_slice into @dst_slice
2863  *
2864  * Returns: %TRUE if everything went fine, %FALSE otherwise
2865  */
2866 gboolean
gst_h265_slice_hdr_copy(GstH265SliceHdr * dst_slice,const GstH265SliceHdr * src_slice)2867 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2868     const GstH265SliceHdr * src_slice)
2869 {
2870   guint i;
2871 
2872   g_return_val_if_fail (dst_slice != NULL, FALSE);
2873   g_return_val_if_fail (src_slice != NULL, FALSE);
2874 
2875   gst_h265_slice_hdr_free (dst_slice);
2876 
2877   *dst_slice = *src_slice;
2878 
2879   if (dst_slice->num_entry_point_offsets > 0) {
2880     dst_slice->entry_point_offset_minus1 =
2881         g_new0 (guint32, dst_slice->num_entry_point_offsets);
2882     for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2883       dst_slice->entry_point_offset_minus1[i] =
2884           src_slice->entry_point_offset_minus1[i];
2885   }
2886 
2887   return TRUE;
2888 }
2889 
2890 /**
2891  * gst_h265_slice_hdr_free:
2892  * slice_hdr: The #GstH265SliceHdr to free
2893  *
2894  * Frees @slice_hdr fields.
2895  */
2896 void
gst_h265_slice_hdr_free(GstH265SliceHdr * slice_hdr)2897 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2898 {
2899   g_return_if_fail (slice_hdr != NULL);
2900 
2901   if (slice_hdr->num_entry_point_offsets > 0)
2902     g_free (slice_hdr->entry_point_offset_minus1);
2903   slice_hdr->entry_point_offset_minus1 = 0;
2904 }
2905 
2906 /**
2907  * gst_h265_sei_copy:
2908  * @dst_sei: The destination #GstH265SEIMessage to copy into
2909  * @src_sei: The source #GstH265SEIMessage to copy from
2910  *
2911  * Copies @src_sei into @dst_sei
2912  *
2913  * Returns: %TRUE if everything went fine, %FALSE otherwise
2914  */
2915 gboolean
gst_h265_sei_copy(GstH265SEIMessage * dst_sei,const GstH265SEIMessage * src_sei)2916 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2917     const GstH265SEIMessage * src_sei)
2918 {
2919   guint i;
2920 
2921   g_return_val_if_fail (dst_sei != NULL, FALSE);
2922   g_return_val_if_fail (src_sei != NULL, FALSE);
2923 
2924   gst_h265_sei_free (dst_sei);
2925 
2926   *dst_sei = *src_sei;
2927 
2928   if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2929     GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2930     const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2931 
2932     if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2933       dst_pic_timing->num_nalus_in_du_minus1 =
2934           g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2935       dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2936           g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2937 
2938       for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2939         dst_pic_timing->num_nalus_in_du_minus1[i] =
2940             src_pic_timing->num_nalus_in_du_minus1[i];
2941         dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2942             src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2943       }
2944     }
2945   } else if (dst_sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2946     GstH265RegisteredUserData *dst_rud = &dst_sei->payload.registered_user_data;
2947     const GstH265RegisteredUserData *src_rud =
2948         &src_sei->payload.registered_user_data;
2949 
2950     if (src_rud->size) {
2951       dst_rud->data = g_malloc (src_rud->size);
2952       memcpy ((guint8 *) dst_rud->data, src_rud->data, src_rud->size);
2953     }
2954   }
2955 
2956   return TRUE;
2957 }
2958 
2959 /**
2960  * gst_h265_sei_free:
2961  * sei: The #GstH265SEIMessage to free
2962  *
2963  * Frees @sei fields.
2964  */
2965 void
gst_h265_sei_free(GstH265SEIMessage * sei)2966 gst_h265_sei_free (GstH265SEIMessage * sei)
2967 {
2968   g_return_if_fail (sei != NULL);
2969 
2970   if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2971     GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2972     if (pic_timing->num_decoding_units_minus1 > 0) {
2973       g_free (pic_timing->num_nalus_in_du_minus1);
2974       g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2975     }
2976     pic_timing->num_nalus_in_du_minus1 = 0;
2977     pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2978   } else if (sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2979     GstH265RegisteredUserData *rud = &sei->payload.registered_user_data;
2980     g_free ((guint8 *) rud->data);
2981     rud->data = NULL;
2982   }
2983 }
2984 
2985 /**
2986  * gst_h265_parser_parse_sei:
2987  * @nalparser: a #GstH265Parser
2988  * @nalu: The `GST_H265_NAL_*_SEI` #GstH265NalUnit to parse
2989  * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2990  *
2991  * Parses @data, create and fills the @messages array.
2992  *
2993  * Returns: a #GstH265ParserResult
2994  */
2995 GstH265ParserResult
gst_h265_parser_parse_sei(GstH265Parser * nalparser,GstH265NalUnit * nalu,GArray ** messages)2996 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2997     GArray ** messages)
2998 {
2999   NalReader nr;
3000   GstH265SEIMessage sei;
3001   GstH265ParserResult res;
3002 
3003   GST_DEBUG ("parsing SEI nal");
3004   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
3005       nalu->size - nalu->header_bytes);
3006   *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
3007   g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
3008 
3009   do {
3010     res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
3011     if (res == GST_H265_PARSER_OK)
3012       g_array_append_val (*messages, sei);
3013     else
3014       break;
3015   } while (nal_reader_has_more_data (&nr));
3016 
3017   return res;
3018 }
3019 
3020 /**
3021  * gst_h265_parser_update_vps:
3022  * @parser: a #GstH265Parser
3023  * @vps: (transfer none): a #GstH265VPS.
3024  *
3025  * Replace internal Video Parameter Set struct corresponding to id of @vps
3026  * with @vps. @nalparser will mark @vps as last parsed vps.
3027  *
3028  * Returns: a #GstH265ParserResult
3029  *
3030  * Since: 1.18
3031  */
3032 GstH265ParserResult
gst_h265_parser_update_vps(GstH265Parser * parser,GstH265VPS * vps)3033 gst_h265_parser_update_vps (GstH265Parser * parser, GstH265VPS * vps)
3034 {
3035   g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3036   g_return_val_if_fail (vps != NULL, GST_H265_PARSER_ERROR);
3037   g_return_val_if_fail (vps->id < GST_H265_MAX_VPS_COUNT,
3038       GST_H265_PARSER_ERROR);
3039 
3040   if (!vps->valid) {
3041     GST_WARNING ("Cannot update with invalid VPS");
3042     return GST_H265_PARSER_ERROR;
3043   }
3044 
3045   GST_DEBUG ("Updating video parameter set with id: %d", vps->id);
3046 
3047   parser->vps[vps->id] = *vps;
3048   parser->last_vps = &parser->vps[vps->id];
3049 
3050   return GST_H265_PARSER_OK;
3051 }
3052 
3053 /**
3054  * gst_h265_parser_update_sps:
3055  * @parser: a #GstH265Parser
3056  * @sps: (transfer none): a #GstH265SPS.
3057  *
3058  * Replace internal Sequence Parameter Set struct corresponding to id of @sps
3059  * with @sps. @nalparser will mark @sps as last parsed sps.
3060  *
3061  * Returns: a #GstH265ParserResult
3062  *
3063  * Since: 1.18
3064  */
3065 GstH265ParserResult
gst_h265_parser_update_sps(GstH265Parser * parser,GstH265SPS * sps)3066 gst_h265_parser_update_sps (GstH265Parser * parser, GstH265SPS * sps)
3067 {
3068   g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3069   g_return_val_if_fail (sps != NULL, GST_H265_PARSER_ERROR);
3070   g_return_val_if_fail (sps->id < GST_H265_MAX_SPS_COUNT,
3071       GST_H265_PARSER_ERROR);
3072 
3073   if (!sps->valid) {
3074     GST_WARNING ("Cannot update with invalid SPS");
3075     return GST_H265_PARSER_ERROR;
3076   }
3077 
3078   if (sps->vps) {
3079     GstH265VPS *vps = gst_h265_parser_get_vps (parser, sps->vps->id);
3080     if (!vps || vps != sps->vps) {
3081       GST_WARNING ("Linked VPS is not identical to internal VPS");
3082       return GST_H265_PARSER_BROKEN_LINK;
3083     }
3084   }
3085 
3086   GST_DEBUG ("Updating sequence parameter set with id: %d", sps->id);
3087 
3088   parser->sps[sps->id] = *sps;
3089   parser->last_sps = &parser->sps[sps->id];
3090 
3091   return GST_H265_PARSER_OK;
3092 }
3093 
3094 /**
3095  * gst_h265_parser_update_pps:
3096  * @parser: a #GstH265Parser
3097  * @pps: (transfer none): a #GstH265PPS.
3098  *
3099  * Replace internal Sequence Parameter Set struct corresponding to id of @pps
3100  * with @pps. @nalparser will mark @pps as last parsed sps.
3101  *
3102  * Returns: a #GstH265ParserResult
3103  *
3104  * Since: 1.18
3105  */
3106 GstH265ParserResult
gst_h265_parser_update_pps(GstH265Parser * parser,GstH265PPS * pps)3107 gst_h265_parser_update_pps (GstH265Parser * parser, GstH265PPS * pps)
3108 {
3109   GstH265SPS *sps;
3110 
3111   g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3112   g_return_val_if_fail (pps != NULL, GST_H265_PARSER_ERROR);
3113   g_return_val_if_fail (pps->id < GST_H265_MAX_PPS_COUNT,
3114       GST_H265_PARSER_ERROR);
3115 
3116   if (!pps->valid) {
3117     GST_WARNING ("Cannot update with invalid PPS");
3118     return GST_H265_PARSER_ERROR;
3119   }
3120 
3121   if (!pps->sps) {
3122     GST_WARNING ("No linked SPS struct");
3123     return GST_H265_PARSER_BROKEN_LINK;
3124   }
3125 
3126   sps = gst_h265_parser_get_sps (parser, pps->sps->id);
3127   if (!sps || sps != pps->sps) {
3128     GST_WARNING ("Linked SPS is not identical to internal SPS");
3129     return GST_H265_PARSER_BROKEN_LINK;
3130   }
3131 
3132   GST_DEBUG ("Updating picture parameter set with id: %d", pps->id);
3133 
3134   parser->pps[pps->id] = *pps;
3135   parser->last_pps = &parser->pps[pps->id];
3136 
3137   return GST_H265_PARSER_OK;
3138 }
3139 
3140 /**
3141  * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
3142  * @out_quant: (out): The resulting quantization matrix
3143  * @quant: The source quantization matrix
3144  *
3145  * Converts quantization matrix @quant from raster scan order to
3146  * zigzag scan order and store the resulting factors into @out_quant.
3147  *
3148  * Note: it is an error to pass the same table in both @quant and
3149  * @out_quant arguments.
3150  *
3151  * Since: 1.6
3152  */
3153 void
gst_h265_quant_matrix_4x4_get_zigzag_from_raster(guint8 out_quant[16],const guint8 quant[16])3154 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
3155     const guint8 quant[16])
3156 {
3157   guint i;
3158 
3159   g_return_if_fail (out_quant != quant);
3160 
3161   for (i = 0; i < 16; i++)
3162     out_quant[i] = quant[zigzag_4x4[i]];
3163 }
3164 
3165 /**
3166  * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
3167  * @out_quant: (out): The resulting quantization matrix
3168  * @quant: The source quantization matrix
3169  *
3170  * Converts quantization matrix @quant from zigzag scan order to
3171  * raster scan order and store the resulting factors into @out_quant.
3172  *
3173  * Note: it is an error to pass the same table in both @quant and
3174  * @out_quant arguments.
3175  *
3176  * Since: 1.6
3177  */
3178 void
gst_h265_quant_matrix_4x4_get_raster_from_zigzag(guint8 out_quant[16],const guint8 quant[16])3179 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
3180     const guint8 quant[16])
3181 {
3182   guint i;
3183 
3184   g_return_if_fail (out_quant != quant);
3185 
3186   for (i = 0; i < 16; i++)
3187     out_quant[zigzag_4x4[i]] = quant[i];
3188 }
3189 
3190 /**
3191  * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
3192  * @out_quant: (out): The resulting quantization matrix
3193  * @quant: The source quantization matrix
3194  *
3195  * Converts quantization matrix @quant from raster scan order to
3196  * zigzag scan order and store the resulting factors into @out_quant.
3197  *
3198  * Note: it is an error to pass the same table in both @quant and
3199  * @out_quant arguments.
3200  *
3201  * Since: 1.6
3202  */
3203 void
gst_h265_quant_matrix_8x8_get_zigzag_from_raster(guint8 out_quant[64],const guint8 quant[64])3204 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
3205     const guint8 quant[64])
3206 {
3207   guint i;
3208 
3209   g_return_if_fail (out_quant != quant);
3210 
3211   for (i = 0; i < 64; i++)
3212     out_quant[i] = quant[zigzag_8x8[i]];
3213 }
3214 
3215 /**
3216  * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
3217  * @out_quant: (out): The resulting quantization matrix
3218  * @quant: The source quantization matrix
3219  *
3220  * Converts quantization matrix @quant from zigzag scan order to
3221  * raster scan order and store the resulting factors into @out_quant.
3222  *
3223  * Note: it is an error to pass the same table in both @quant and
3224  * @out_quant arguments.
3225  *
3226  * Since: 1.6
3227  */
3228 void
gst_h265_quant_matrix_8x8_get_raster_from_zigzag(guint8 out_quant[64],const guint8 quant[64])3229 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
3230     const guint8 quant[64])
3231 {
3232   guint i;
3233 
3234   g_return_if_fail (out_quant != quant);
3235 
3236   for (i = 0; i < 64; i++)
3237     out_quant[zigzag_8x8[i]] = quant[i];
3238 }
3239 
3240 /**
3241  * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
3242  * @out_quant: (out): The resulting quantization matrix
3243  * @quant: The source quantization matrix
3244  *
3245  * Converts quantization matrix @quant from raster scan order to
3246  * uprightdiagonal scan order and store the resulting factors
3247  * into @out_quant.
3248  *
3249  * Note: it is an error to pass the same table in both @quant and
3250  * @out_quant arguments.
3251  *
3252  * Since: 1.6
3253  */
3254 void
gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster(guint8 out_quant[16],const guint8 quant[16])3255 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
3256     const guint8 quant[16])
3257 {
3258   guint i;
3259 
3260   g_return_if_fail (out_quant != quant);
3261 
3262   for (i = 0; i < 16; i++)
3263     out_quant[i] = quant[uprightdiagonal_4x4[i]];
3264 }
3265 
3266 /**
3267  * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
3268  * @out_quant: (out): The resulting quantization matrix
3269  * @quant: The source quantization matrix
3270  *
3271  * Converts quantization matrix @quant from uprightdiagonal scan order to
3272  * raster scan order and store the resulting factors into @out_quant.
3273  *
3274  * Note: it is an error to pass the same table in both @quant and
3275  * @out_quant arguments.
3276  *
3277  * Since: 1.6
3278  */
3279 void
gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal(guint8 out_quant[16],const guint8 quant[16])3280 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
3281     const guint8 quant[16])
3282 {
3283   guint i;
3284 
3285   g_return_if_fail (out_quant != quant);
3286 
3287   for (i = 0; i < 16; i++)
3288     out_quant[uprightdiagonal_4x4[i]] = quant[i];
3289 }
3290 
3291 /**
3292  * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
3293  * @out_quant: (out): The resulting quantization matrix
3294  * @quant: The source quantization matrix
3295  *
3296  * Converts quantization matrix @quant from raster scan order to
3297  * uprightdiagonal scan order and store the resulting factors
3298  * into @out_quant.
3299  *
3300  * Note: it is an error to pass the same table in both @quant and
3301  * @out_quant arguments.
3302  *
3303  * Since: 1.6
3304  */
3305 void
gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster(guint8 out_quant[64],const guint8 quant[64])3306 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
3307     const guint8 quant[64])
3308 {
3309   guint i;
3310 
3311   g_return_if_fail (out_quant != quant);
3312 
3313   for (i = 0; i < 64; i++)
3314     out_quant[i] = quant[uprightdiagonal_8x8[i]];
3315 }
3316 
3317 /**
3318  * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
3319  * @out_quant: (out): The resulting quantization matrix
3320  * @quant: The source quantization matrix
3321  *
3322  * Converts quantization matrix @quant from uprightdiagonal scan order to
3323  * raster scan order and store the resulting factors into @out_quant.
3324  *
3325  * Note: it is an error to pass the same table in both @quant and
3326  * @out_quant arguments.
3327  *
3328  * Since: 1.6
3329  */
3330 void
gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal(guint8 out_quant[64],const guint8 quant[64])3331 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
3332     const guint8 quant[64])
3333 {
3334   guint i;
3335 
3336   g_return_if_fail (out_quant != quant);
3337 
3338   for (i = 0; i < 64; i++)
3339     out_quant[uprightdiagonal_8x8[i]] = quant[i];
3340 }
3341 
3342 typedef struct
3343 {
3344   GstH265Profile profile;
3345 
3346   guint8 max_14bit_constraint_flag;
3347   guint8 max_12bit_constraint_flag;
3348   guint8 max_10bit_constraint_flag;
3349   guint8 max_8bit_constraint_flag;
3350   guint8 max_422chroma_constraint_flag;
3351   guint8 max_420chroma_constraint_flag;
3352   guint8 max_monochrome_constraint_flag;
3353   guint8 intra_constraint_flag;
3354   guint8 one_picture_only_constraint_flag;
3355   gboolean lower_bit_rate_constraint_flag_set;
3356 
3357   /* Tie breaker if more than one profiles are matching */
3358   guint priority;
3359 } H265ExtensionProfile;
3360 
3361 typedef struct
3362 {
3363   H265ExtensionProfile *profile;
3364   guint extra_constraints;
3365 } H265ExtensionProfileMatch;
3366 
3367 static gint
sort_fre_profile_matches(H265ExtensionProfileMatch * a,H265ExtensionProfileMatch * b)3368 sort_fre_profile_matches (H265ExtensionProfileMatch * a,
3369     H265ExtensionProfileMatch * b)
3370 {
3371   gint d;
3372 
3373   d = a->extra_constraints - b->extra_constraints;
3374   if (d)
3375     return d;
3376 
3377   return b->profile->priority - a->profile->priority;
3378 }
3379 
3380 static GstH265Profile
get_extension_profile(H265ExtensionProfile * profiles,guint num,const GstH265ProfileTierLevel * ptl)3381 get_extension_profile (H265ExtensionProfile * profiles, guint num,
3382     const GstH265ProfileTierLevel * ptl)
3383 {
3384   GstH265Profile result = GST_H265_PROFILE_INVALID;
3385   guint i;
3386   GList *matches = NULL;
3387 
3388   for (i = 0; i < num; i++) {
3389     H265ExtensionProfile p = profiles[i];
3390     guint extra_constraints = 0;
3391     H265ExtensionProfileMatch *m;
3392 
3393     /* Filter out all the profiles having constraints not satisfied by @ptl.
3394      * Then pick the one having the least extra constraints. This allow us
3395      * to match the closest profile if bitstream contains not standard
3396      * constraints. */
3397     if (p.max_14bit_constraint_flag != ptl->max_14bit_constraint_flag) {
3398       if (p.max_14bit_constraint_flag)
3399         continue;
3400       extra_constraints++;
3401     }
3402 
3403     if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
3404       if (p.max_12bit_constraint_flag)
3405         continue;
3406       extra_constraints++;
3407     }
3408 
3409     if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
3410       if (p.max_10bit_constraint_flag)
3411         continue;
3412       extra_constraints++;
3413     }
3414 
3415     if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
3416       if (p.max_8bit_constraint_flag)
3417         continue;
3418       extra_constraints++;
3419     }
3420 
3421     if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
3422       if (p.max_422chroma_constraint_flag)
3423         continue;
3424       extra_constraints++;
3425     }
3426 
3427     if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
3428       if (p.max_420chroma_constraint_flag)
3429         continue;
3430       extra_constraints++;
3431     }
3432 
3433     if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
3434       if (p.max_monochrome_constraint_flag)
3435         continue;
3436       extra_constraints++;
3437     }
3438 
3439     if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
3440       if (p.intra_constraint_flag)
3441         continue;
3442       extra_constraints++;
3443     }
3444 
3445     if (p.one_picture_only_constraint_flag !=
3446         ptl->one_picture_only_constraint_flag) {
3447       if (p.one_picture_only_constraint_flag)
3448         continue;
3449       extra_constraints++;
3450     }
3451 
3452     if (p.lower_bit_rate_constraint_flag_set
3453         && !ptl->lower_bit_rate_constraint_flag)
3454       continue;
3455 
3456     if (extra_constraints == 0) {
3457       result = p.profile;
3458       break;
3459     }
3460 
3461     m = g_new0 (H265ExtensionProfileMatch, 1);
3462     m->profile = &profiles[i];
3463     m->extra_constraints = extra_constraints;
3464     matches = g_list_prepend (matches, m);
3465   }
3466 
3467   if (result == GST_H265_PROFILE_INVALID && matches) {
3468     H265ExtensionProfileMatch *m;
3469 
3470     matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
3471     m = matches->data;
3472     result = m->profile->profile;
3473     GST_INFO ("Fail to find the profile matches all extensions bits,"
3474         " select the closest %s with %d bit diff",
3475         gst_h265_profile_to_string (result), m->extra_constraints);
3476   }
3477 
3478   if (matches)
3479     g_list_free_full (matches, g_free);
3480 
3481   return result;
3482 }
3483 
3484 static GstH265Profile
get_format_range_extension_profile(const GstH265ProfileTierLevel * ptl)3485 get_format_range_extension_profile (const GstH265ProfileTierLevel * ptl)
3486 {
3487   /* Profile idc: GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
3488      See Table A.2 for the definition of those formats */
3489   static H265ExtensionProfile profiles[] = {
3490     {GST_H265_PROFILE_MONOCHROME,
3491         0, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3492     {GST_H265_PROFILE_MONOCHROME_10,
3493         0, 1, 1, 0, 1, 1, 1, 0, 0, TRUE, 1},
3494     {GST_H265_PROFILE_MONOCHROME_12,
3495         0, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3496     {GST_H265_PROFILE_MONOCHROME_16,
3497         0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 3},
3498     {GST_H265_PROFILE_MAIN_12,
3499         0, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 4},
3500     {GST_H265_PROFILE_MAIN_422_10,
3501         0, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 5},
3502     {GST_H265_PROFILE_MAIN_422_12,
3503         0, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 6},
3504     {GST_H265_PROFILE_MAIN_444,
3505         0, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 7},
3506     {GST_H265_PROFILE_MAIN_444_10,
3507         0, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 8},
3508     {GST_H265_PROFILE_MAIN_444_12,
3509         0, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 9},
3510     {GST_H265_PROFILE_MAIN_INTRA,
3511         0, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 10},
3512     {GST_H265_PROFILE_MAIN_10_INTRA,
3513         0, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 11},
3514     {GST_H265_PROFILE_MAIN_12_INTRA,
3515         0, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 12},
3516     {GST_H265_PROFILE_MAIN_422_10_INTRA,
3517         0, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 13},
3518     {GST_H265_PROFILE_MAIN_422_12_INTRA,
3519         0, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 14},
3520     {GST_H265_PROFILE_MAIN_444_INTRA,
3521         0, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 15},
3522     {GST_H265_PROFILE_MAIN_444_10_INTRA,
3523         0, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 16},
3524     {GST_H265_PROFILE_MAIN_444_12_INTRA,
3525         0, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
3526     {GST_H265_PROFILE_MAIN_444_16_INTRA,
3527         0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 18},
3528     {GST_H265_PROFILE_MAIN_444_STILL_PICTURE,
3529         0, 1, 1, 1, 0, 0, 0, 1, 1, FALSE, 19},
3530     {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE,
3531         0, 0, 0, 0, 0, 0, 0, 1, 1, FALSE, 20},
3532   };
3533 
3534   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3535 }
3536 
3537 static GstH265Profile
get_3d_profile(const GstH265ProfileTierLevel * ptl)3538 get_3d_profile (const GstH265ProfileTierLevel * ptl)
3539 {
3540   /* profile idc: GST_H265_PROFILE_IDC_3D_MAIN */
3541   static H265ExtensionProfile profiles[] = {
3542     {GST_H265_PROFILE_3D_MAIN,
3543         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3544   };
3545 
3546   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3547 }
3548 
3549 static GstH265Profile
get_multiview_profile(const GstH265ProfileTierLevel * ptl)3550 get_multiview_profile (const GstH265ProfileTierLevel * ptl)
3551 {
3552   static H265ExtensionProfile profiles[] = {
3553     {GST_H265_PROFILE_MULTIVIEW_MAIN,
3554         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3555   };
3556 
3557   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3558 }
3559 
3560 static GstH265Profile
get_scalable_profile(const GstH265ProfileTierLevel * ptl)3561 get_scalable_profile (const GstH265ProfileTierLevel * ptl)
3562 {
3563   static H265ExtensionProfile profiles[] = {
3564     {GST_H265_PROFILE_SCALABLE_MAIN,
3565         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3566     {GST_H265_PROFILE_SCALABLE_MAIN_10,
3567         0, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3568   };
3569 
3570   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3571 }
3572 
3573 static GstH265Profile
get_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3574 get_high_throughput_profile (const GstH265ProfileTierLevel * ptl)
3575 {
3576   static H265ExtensionProfile profiles[] = {
3577     {GST_H265_PROFILE_HIGH_THROUGHPUT_444,
3578         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3579     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10,
3580         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3581     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14,
3582         1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3583     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
3584         0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 3},
3585   };
3586 
3587   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3588 }
3589 
3590 static GstH265Profile
get_screen_content_coding_extensions_profile(const GstH265ProfileTierLevel * ptl)3591 get_screen_content_coding_extensions_profile (const GstH265ProfileTierLevel *
3592     ptl)
3593 {
3594   static H265ExtensionProfile profiles[] = {
3595     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN,
3596         1, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3597     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10,
3598         1, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3599     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
3600         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 2},
3601     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10,
3602         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 3},
3603   };
3604 
3605   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3606 }
3607 
3608 static GstH265Profile
get_scalable_format_range_extensions_profile(const GstH265ProfileTierLevel * ptl)3609 get_scalable_format_range_extensions_profile (const GstH265ProfileTierLevel *
3610     ptl)
3611 {
3612   static H265ExtensionProfile profiles[] = {
3613     {GST_H265_PROFILE_SCALABLE_MONOCHROME,
3614         1, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3615     {GST_H265_PROFILE_SCALABLE_MONOCHROME_12,
3616         1, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 1},
3617     {GST_H265_PROFILE_SCALABLE_MONOCHROME_16,
3618         0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3619     {GST_H265_PROFILE_SCALABLE_MAIN_444,
3620         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 3},
3621   };
3622 
3623   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3624 }
3625 
3626 static GstH265Profile
get_screen_content_coding_extensions_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3627     get_screen_content_coding_extensions_high_throughput_profile
3628     (const GstH265ProfileTierLevel * ptl)
3629 {
3630   static H265ExtensionProfile profiles[] = {
3631     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
3632         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3633     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
3634         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3635     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
3636         1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3637   };
3638 
3639   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3640 }
3641 
3642 static inline void
append_profile(GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * idx,GstH265Profile profile)3643 append_profile (GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * idx,
3644     GstH265Profile profile)
3645 {
3646   if (profile == GST_H265_PROFILE_INVALID)
3647     return;
3648   profiles[*idx] = profile;
3649   (*idx)++;
3650 }
3651 
3652 /* *INDENT-OFF* */
3653 struct h265_profiles_map
3654 {
3655   GstH265ProfileIDC profile_idc;
3656   GstH265Profile (*get_profile) (const GstH265ProfileTierLevel *);
3657   GstH265Profile profile;
3658 };
3659 /* *INDENT-ON* */
3660 
3661 static const struct h265_profiles_map profiles_map[] = {
3662   /* keep profile check in asc order */
3663   {GST_H265_PROFILE_IDC_MAIN, NULL, GST_H265_PROFILE_MAIN},
3664   {GST_H265_PROFILE_IDC_MAIN_10, NULL, GST_H265_PROFILE_MAIN_10},
3665   {GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE, NULL,
3666       GST_H265_PROFILE_MAIN_STILL_PICTURE},
3667   {GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3668       get_format_range_extension_profile, GST_H265_PROFILE_INVALID},
3669   {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT, get_high_throughput_profile,
3670       GST_H265_PROFILE_INVALID},
3671   {GST_H265_PROFILE_IDC_MULTIVIEW_MAIN, get_multiview_profile,
3672       GST_H265_PROFILE_INVALID},
3673   {GST_H265_PROFILE_IDC_SCALABLE_MAIN, get_scalable_profile,
3674       GST_H265_PROFILE_INVALID},
3675   {GST_H265_PROFILE_IDC_3D_MAIN, get_3d_profile, GST_H265_PROFILE_INVALID},
3676   {GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3677         get_screen_content_coding_extensions_profile,
3678       GST_H265_PROFILE_INVALID},
3679   {GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3680         get_scalable_format_range_extensions_profile,
3681       GST_H265_PROFILE_INVALID},
3682   {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION,
3683         get_screen_content_coding_extensions_high_throughput_profile,
3684       GST_H265_PROFILE_INVALID},
3685 };
3686 
3687 static void
gst_h265_profile_tier_level_get_profiles(const GstH265ProfileTierLevel * ptl,GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * len)3688 gst_h265_profile_tier_level_get_profiles (const GstH265ProfileTierLevel * ptl,
3689     GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * len)
3690 {
3691   guint i = 0, j;
3692 
3693   /* First add profile idc */
3694   for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3695     if (ptl->profile_idc == profiles_map[j].profile_idc) {
3696       if (profiles_map[j].get_profile)
3697         append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3698       else
3699         profiles[i++] = profiles_map[j].profile;
3700       break;
3701     }
3702   }
3703 
3704   /* Later add compatibility flags */
3705   for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3706     if (i > 0 && ptl->profile_idc == profiles_map[j].profile_idc)
3707       continue;
3708     if (ptl->profile_compatibility_flag[profiles_map[j].profile_idc]) {
3709       if (profiles_map[j].get_profile)
3710         append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3711       else
3712         profiles[i++] = profiles_map[j].profile;
3713     }
3714   }
3715 
3716   *len = i;
3717 }
3718 
3719 /**
3720  * gst_h265_profile_tier_level_get_profile:
3721  * @ptl: a #GstH265ProfileTierLevel
3722  *
3723  * Return the H265 profile defined in @ptl.
3724  *
3725  * Returns: a #GstH265Profile
3726  * Since: 1.14
3727  */
3728 GstH265Profile
gst_h265_profile_tier_level_get_profile(const GstH265ProfileTierLevel * ptl)3729 gst_h265_profile_tier_level_get_profile (const GstH265ProfileTierLevel * ptl)
3730 {
3731   guint len = 0;
3732   GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
3733 
3734   gst_h265_profile_tier_level_get_profiles (ptl, profiles, &len);
3735 
3736   if (len > 0)
3737     return profiles[0];
3738 
3739   return GST_H265_PROFILE_INVALID;
3740 }
3741 
3742 /**
3743  * gst_h265_profile_to_string:
3744  * @profile: a #GstH265Profile
3745  *
3746  * Returns the descriptive name for the #GstH265Profile.
3747  *
3748  * Returns: (nullable): the name for @profile or %NULL on error
3749  *
3750  * Since: 1.18
3751  */
3752 const gchar *
gst_h265_profile_to_string(GstH265Profile profile)3753 gst_h265_profile_to_string (GstH265Profile profile)
3754 {
3755   guint i;
3756 
3757   if (profile == GST_H265_PROFILE_INVALID || profile == GST_H265_PROFILE_MAX)
3758     return NULL;
3759 
3760   for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3761     if (profile == h265_profiles[i].profile)
3762       return h265_profiles[i].name;
3763   }
3764 
3765   return NULL;
3766 }
3767 
3768 /**
3769  * gst_h265_profile_from_string:
3770  * @string: the descriptive name for #GstH265Profile
3771  *
3772  * Returns a #GstH265Profile for the @string.
3773  *
3774  * Returns: the #GstH265Profile of @string or %GST_H265_PROFILE_INVALID on error
3775  *
3776  * Since: 1.18
3777  */
3778 GstH265Profile
gst_h265_profile_from_string(const gchar * string)3779 gst_h265_profile_from_string (const gchar * string)
3780 {
3781   guint i;
3782 
3783   if (string == NULL)
3784     return GST_H265_PROFILE_INVALID;
3785 
3786   for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3787     if (g_strcmp0 (string, h265_profiles[i].name) == 0) {
3788       return h265_profiles[i].profile;
3789     }
3790   }
3791 
3792   return GST_H265_PROFILE_INVALID;
3793 }
3794 
3795 static gboolean
gst_h265_write_sei_registered_user_data(NalWriter * nw,GstH265RegisteredUserData * rud)3796 gst_h265_write_sei_registered_user_data (NalWriter * nw,
3797     GstH265RegisteredUserData * rud)
3798 {
3799   WRITE_UINT8 (nw, rud->country_code, 8);
3800   if (rud->country_code == 0xff)
3801     WRITE_UINT8 (nw, rud->country_code_extension, 8);
3802 
3803   WRITE_BYTES (nw, rud->data, rud->size);
3804 
3805   return TRUE;
3806 
3807 error:
3808   return FALSE;
3809 }
3810 
3811 static gboolean
gst_h265_write_sei_time_code(NalWriter * nw,GstH265TimeCode * tc)3812 gst_h265_write_sei_time_code (NalWriter * nw, GstH265TimeCode * tc)
3813 {
3814   gint i;
3815 
3816   WRITE_UINT8 (nw, tc->num_clock_ts, 2);
3817 
3818   for (i = 0; i < tc->num_clock_ts; i++) {
3819     WRITE_UINT8 (nw, tc->clock_timestamp_flag[i], 1);
3820     if (tc->clock_timestamp_flag[i]) {
3821       WRITE_UINT8 (nw, tc->units_field_based_flag[i], 1);
3822       WRITE_UINT8 (nw, tc->counting_type[i], 5);
3823       WRITE_UINT8 (nw, tc->full_timestamp_flag[i], 1);
3824       WRITE_UINT8 (nw, tc->discontinuity_flag[i], 1);
3825       WRITE_UINT8 (nw, tc->cnt_dropped_flag[i], 1);
3826       WRITE_UINT16 (nw, tc->n_frames[i], 9);
3827 
3828       if (tc->full_timestamp_flag[i]) {
3829         WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3830         WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3831         WRITE_UINT8 (nw, tc->hours_value[i], 5);
3832       } else {
3833         WRITE_UINT8 (nw, tc->seconds_flag[i], 1);
3834         if (tc->seconds_flag[i]) {
3835           WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3836           WRITE_UINT8 (nw, tc->minutes_flag[i], 1);
3837           if (tc->minutes_flag[i]) {
3838             WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3839             WRITE_UINT8 (nw, tc->hours_flag[i], 1);
3840             if (tc->hours_flag[i]) {
3841               WRITE_UINT8 (nw, tc->hours_value[i], 5);
3842             }
3843           }
3844         }
3845       }
3846     }
3847 
3848     WRITE_UINT8 (nw, tc->time_offset_length[i], 5);
3849 
3850     if (tc->time_offset_length[i] > 0)
3851       WRITE_UINT8 (nw, tc->time_offset_value[i], tc->time_offset_length[i]);
3852   }
3853 
3854   return TRUE;
3855 
3856 error:
3857   return FALSE;
3858 }
3859 
3860 static gboolean
gst_h265_write_sei_mastering_display_colour_volume(NalWriter * nw,GstH265MasteringDisplayColourVolume * mdcv)3861 gst_h265_write_sei_mastering_display_colour_volume (NalWriter * nw,
3862     GstH265MasteringDisplayColourVolume * mdcv)
3863 {
3864   gint i;
3865 
3866   for (i = 0; i < 3; i++) {
3867     WRITE_UINT16 (nw, mdcv->display_primaries_x[i], 16);
3868     WRITE_UINT16 (nw, mdcv->display_primaries_y[i], 16);
3869   }
3870 
3871   WRITE_UINT16 (nw, mdcv->white_point_x, 16);
3872   WRITE_UINT16 (nw, mdcv->white_point_y, 16);
3873   WRITE_UINT32 (nw, mdcv->max_display_mastering_luminance, 32);
3874   WRITE_UINT32 (nw, mdcv->min_display_mastering_luminance, 32);
3875 
3876   return TRUE;
3877 
3878 error:
3879   return FALSE;
3880 }
3881 
3882 static gboolean
gst_h265_write_sei_content_light_level_info(NalWriter * nw,GstH265ContentLightLevel * cll)3883 gst_h265_write_sei_content_light_level_info (NalWriter * nw,
3884     GstH265ContentLightLevel * cll)
3885 {
3886   WRITE_UINT16 (nw, cll->max_content_light_level, 16);
3887   WRITE_UINT16 (nw, cll->max_pic_average_light_level, 16);
3888 
3889   return TRUE;
3890 
3891 error:
3892   return FALSE;
3893 }
3894 
3895 static GstMemory *
gst_h265_create_sei_memory_internal(guint8 layer_id,guint8 temporal_id_plus1,guint nal_prefix_size,gboolean packetized,GArray * messages)3896 gst_h265_create_sei_memory_internal (guint8 layer_id, guint8 temporal_id_plus1,
3897     guint nal_prefix_size, gboolean packetized, GArray * messages)
3898 {
3899   NalWriter nw;
3900   gint i;
3901   gboolean have_written_data = FALSE;
3902 
3903   nal_writer_init (&nw, nal_prefix_size, packetized);
3904 
3905   if (messages->len == 0)
3906     goto error;
3907 
3908   GST_DEBUG ("Create SEI nal from array, len: %d", messages->len);
3909 
3910   /* nal header */
3911   /* forbidden_zero_bit */
3912   WRITE_UINT8 (&nw, 0, 1);
3913   /* nal_unit_type */
3914   WRITE_UINT8 (&nw, GST_H265_NAL_PREFIX_SEI, 6);
3915   /* nuh_layer_id */
3916   WRITE_UINT8 (&nw, layer_id, 6);
3917   /* nuh_temporal_id_plus1 */
3918   WRITE_UINT8 (&nw, temporal_id_plus1, 3);
3919 
3920   for (i = 0; i < messages->len; i++) {
3921     GstH265SEIMessage *msg = &g_array_index (messages, GstH265SEIMessage, i);
3922     guint32 payload_size_data = 0;
3923     guint32 payload_size_in_bits = 0;
3924     guint32 payload_type_data = msg->payloadType;
3925     gboolean need_align = FALSE;
3926 
3927     switch (payload_type_data) {
3928       case GST_H265_SEI_REGISTERED_USER_DATA:{
3929         GstH265RegisteredUserData *rud = &msg->payload.registered_user_data;
3930 
3931         /* itu_t_t35_country_code: 8 bits */
3932         payload_size_data = 1;
3933         if (rud->country_code == 0xff) {
3934           /* itu_t_t35_country_code_extension_byte */
3935           payload_size_data++;
3936         }
3937 
3938         payload_size_data += rud->size;
3939         break;
3940       }
3941       case GST_H265_SEI_TIME_CODE:{
3942         gint j;
3943         GstH265TimeCode *tc = &msg->payload.time_code;
3944         /* num_clock_ts: 2 bits */
3945         payload_size_in_bits = 2;
3946         for (j = 0; j < tc->num_clock_ts; j++) {
3947           /* clock_timestamp_flag: 1 bit */
3948           payload_size_in_bits += 1;
3949 
3950           if (tc->clock_timestamp_flag[j]) {
3951             /* units_field_based_flag: 1 bit
3952              * counting_type: 5 bits
3953              * full_timestamp_flag: 1 bit
3954              * discontinuity_flag: 1 bit
3955              * cnt_dropped_flag: 1 bit
3956              * n_frames: 9 bit
3957              */
3958             payload_size_in_bits += 18;
3959 
3960             if (tc->full_timestamp_flag[j]) {
3961               /* seconds_value: 6 bits
3962                * minutes_value: 6 bits
3963                * hours_value: 5 bits
3964                */
3965               payload_size_in_bits += 17;
3966             } else {
3967               /* seconds_flag: 1 bit */
3968               payload_size_in_bits += 1;
3969 
3970               if (tc->seconds_flag[j]) {
3971                 /* seconds_value: 6 bits
3972                  * minutes_flag: 1 bit
3973                  */
3974                 payload_size_in_bits += 7;
3975 
3976                 if (tc->minutes_flag[j]) {
3977                   /* minutes_value: 6 bits
3978                    * hours_flag: 1 bit
3979                    */
3980                   payload_size_in_bits += 7;
3981                   if (tc->hours_flag[j]) {
3982                     /* hours_value: 5 bits */
3983                     payload_size_in_bits += 5;
3984                   }
3985                 }
3986               }
3987             }
3988 
3989             /* time_offset_length: 5bits
3990              * time_offset_value: time_offset_length bits
3991              */
3992             payload_size_in_bits += (5 + tc->time_offset_length[j]);
3993           }
3994         }
3995 
3996         payload_size_data = payload_size_in_bits >> 3;
3997 
3998         if ((payload_size_in_bits & 0x7) != 0) {
3999           GST_INFO ("Bits for Time Code SEI is not byte aligned");
4000           payload_size_data++;
4001           need_align = TRUE;
4002         }
4003         break;
4004       }
4005       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4006         /* x, y 16 bits per RGB channel
4007          * x, y 16 bits white point
4008          * max, min luminance 32 bits
4009          *
4010          * (2 * 2 * 3) + (2 * 2) + (4 * 2) = 24 bytes
4011          */
4012         payload_size_data = 24;
4013         break;
4014       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4015         /* maxCLL and maxFALL per 16 bits
4016          *
4017          * 2 * 2 = 4 bytes
4018          */
4019         payload_size_data = 4;
4020         break;
4021       default:
4022         break;
4023     }
4024 
4025     if (payload_size_data == 0) {
4026       GST_FIXME ("Unsupported SEI type %d", msg->payloadType);
4027       continue;
4028     }
4029 
4030     /* write payload type bytes */
4031     while (payload_type_data >= 0xff) {
4032       WRITE_UINT8 (&nw, 0xff, 8);
4033       payload_type_data -= 0xff;
4034     }
4035     WRITE_UINT8 (&nw, payload_type_data, 8);
4036 
4037     /* write payload size bytes */
4038     while (payload_size_data >= 0xff) {
4039       WRITE_UINT8 (&nw, 0xff, 8);
4040       payload_size_data -= 0xff;
4041     }
4042     WRITE_UINT8 (&nw, payload_size_data, 8);
4043 
4044     switch (msg->payloadType) {
4045       case GST_H265_SEI_REGISTERED_USER_DATA:
4046         GST_DEBUG ("Writing \"Registered user data\" done");
4047         if (!gst_h265_write_sei_registered_user_data (&nw,
4048                 &msg->payload.registered_user_data)) {
4049           GST_WARNING ("Failed to write \"Registered user data\"");
4050           goto error;
4051         }
4052         have_written_data = TRUE;
4053         break;
4054       case GST_H265_SEI_TIME_CODE:
4055         GST_DEBUG ("Wrtiting \"Time code\"");
4056         if (!gst_h265_write_sei_time_code (&nw, &msg->payload.time_code)) {
4057           GST_WARNING ("Failed to write \"Time code\"");
4058           goto error;
4059         }
4060         have_written_data = TRUE;
4061         break;
4062       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4063         GST_DEBUG ("Wrtiting \"Mastering display colour volume\"");
4064         if (!gst_h265_write_sei_mastering_display_colour_volume (&nw,
4065                 &msg->payload.mastering_display_colour_volume)) {
4066           GST_WARNING ("Failed to write \"Mastering display colour volume\"");
4067           goto error;
4068         }
4069         have_written_data = TRUE;
4070         break;
4071       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4072         GST_DEBUG ("Writing \"Content light level\" done");
4073         if (!gst_h265_write_sei_content_light_level_info (&nw,
4074                 &msg->payload.content_light_level)) {
4075           GST_WARNING ("Failed to write \"Content light level\"");
4076           goto error;
4077         }
4078         have_written_data = TRUE;
4079         break;
4080       default:
4081         break;
4082     }
4083 
4084     if (need_align && !nal_writer_do_rbsp_trailing_bits (&nw)) {
4085       GST_WARNING ("Cannot insert traling bits");
4086       goto error;
4087     }
4088   }
4089 
4090   if (!have_written_data) {
4091     GST_WARNING ("No written sei data");
4092     goto error;
4093   }
4094 
4095   if (!nal_writer_do_rbsp_trailing_bits (&nw)) {
4096     GST_WARNING ("Failed to insert rbsp trailing bits");
4097     goto error;
4098   }
4099 
4100   return nal_writer_reset_and_get_memory (&nw);
4101 
4102 error:
4103   nal_writer_reset (&nw);
4104 
4105   return NULL;
4106 }
4107 
4108 /**
4109  * gst_h265_create_sei_memory:
4110  * @layer_id: a nal unit layer id
4111  * @temporal_id_plus1: a nal unit temporal identifier
4112  * @start_code_prefix_length: a length of start code prefix, must be 3 or 4
4113  * @messages: (transfer none): a GArray of #GstH265SEIMessage
4114  *
4115  * Creates raw byte-stream format (a.k.a Annex B type) SEI nal unit data
4116  * from @messages
4117  *
4118  * Returns: a #GstMemory containing a PREFIX SEI nal unit
4119  *
4120  * Since: 1.18
4121  */
4122 GstMemory *
gst_h265_create_sei_memory(guint8 layer_id,guint8 temporal_id_plus1,guint8 start_code_prefix_length,GArray * messages)4123 gst_h265_create_sei_memory (guint8 layer_id, guint8 temporal_id_plus1,
4124     guint8 start_code_prefix_length, GArray * messages)
4125 {
4126   g_return_val_if_fail (start_code_prefix_length == 3
4127       || start_code_prefix_length == 4, NULL);
4128   g_return_val_if_fail (messages != NULL, NULL);
4129   g_return_val_if_fail (messages->len > 0, NULL);
4130 
4131   return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4132       start_code_prefix_length, FALSE, messages);
4133 }
4134 
4135 /**
4136  * gst_h265_create_sei_memory_hevc:
4137  * @layer_id: a nal unit layer id
4138  * @temporal_id_plus1: a nal unit temporal identifier
4139  * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4140  * @messages: (transfer none): a GArray of #GstH265SEIMessage
4141  *
4142  * Creates raw packetized format SEI nal unit data from @messages
4143  *
4144  * Returns: a #GstMemory containing a PREFIX SEI nal unit
4145  *
4146  * Since: 1.18
4147  */
4148 GstMemory *
gst_h265_create_sei_memory_hevc(guint8 layer_id,guint8 temporal_id_plus1,guint8 nal_length_size,GArray * messages)4149 gst_h265_create_sei_memory_hevc (guint8 layer_id, guint8 temporal_id_plus1,
4150     guint8 nal_length_size, GArray * messages)
4151 {
4152   return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4153       nal_length_size, TRUE, messages);
4154 }
4155 
4156 static GstBuffer *
gst_h265_parser_insert_sei_internal(GstH265Parser * parser,guint8 nal_prefix_size,gboolean packetized,GstBuffer * au,GstMemory * sei)4157 gst_h265_parser_insert_sei_internal (GstH265Parser * parser,
4158     guint8 nal_prefix_size, gboolean packetized, GstBuffer * au,
4159     GstMemory * sei)
4160 {
4161   GstH265NalUnit nalu;
4162   GstH265NalUnit sei_nalu;
4163   GstMapInfo info;
4164   GstMapInfo sei_info;
4165   GstH265ParserResult pres;
4166   guint offset = 0;
4167   GstBuffer *new_buffer = NULL;
4168   GstMemory *new_mem = NULL;
4169 
4170   /* all SEI payload types supported by us need to have the identical
4171    * temporal id to that of slice. Parse SEI first and we will
4172    * update it if it's required */
4173   if (!gst_memory_map (sei, &sei_info, GST_MAP_READ)) {
4174     GST_ERROR ("Cannot map sei memory");
4175     return NULL;
4176   }
4177 
4178   if (packetized) {
4179     pres = gst_h265_parser_identify_nalu_hevc (parser,
4180         sei_info.data, 0, sei_info.size, nal_prefix_size, &sei_nalu);
4181   } else {
4182     pres = gst_h265_parser_identify_nalu (parser,
4183         sei_info.data, 0, sei_info.size, &sei_nalu);
4184   }
4185   gst_memory_unmap (sei, &sei_info);
4186   if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4187     GST_DEBUG ("Failed to identify sei nal unit, ret: %d", pres);
4188     return NULL;
4189   }
4190 
4191   if (!gst_buffer_map (au, &info, GST_MAP_READ)) {
4192     GST_ERROR ("Cannot map au buffer");
4193     return NULL;
4194   }
4195 
4196   /* Find the offset of the first slice */
4197   do {
4198     if (packetized) {
4199       pres = gst_h265_parser_identify_nalu_hevc (parser,
4200           info.data, offset, info.size, nal_prefix_size, &nalu);
4201     } else {
4202       pres = gst_h265_parser_identify_nalu (parser,
4203           info.data, offset, info.size, &nalu);
4204     }
4205 
4206     if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4207       GST_DEBUG ("Failed to identify nal unit, ret: %d", pres);
4208       gst_buffer_unmap (au, &info);
4209 
4210       return NULL;
4211     }
4212 
4213     if (nalu.type <= GST_H265_NAL_SLICE_RASL_R
4214         || (nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP
4215             && nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)) {
4216       GST_DEBUG ("Found slice nal type %d at offset %d", nalu.type,
4217           nalu.sc_offset);
4218       break;
4219     }
4220 
4221     offset = nalu.offset + nalu.size;
4222   } while (pres == GST_H265_PARSER_OK);
4223   gst_buffer_unmap (au, &info);
4224 
4225   /* found the best position now, create new buffer */
4226   new_buffer = gst_buffer_new ();
4227 
4228   /* copy all metadata */
4229   if (!gst_buffer_copy_into (new_buffer, au, GST_BUFFER_COPY_METADATA, 0, -1)) {
4230     GST_ERROR ("Failed to copy metadata into new buffer");
4231     gst_clear_buffer (&new_buffer);
4232     goto out;
4233   }
4234 
4235   /* copy non-slice nal */
4236   if (nalu.sc_offset > 0) {
4237     if (!gst_buffer_copy_into (new_buffer, au,
4238             GST_BUFFER_COPY_MEMORY, 0, nalu.sc_offset)) {
4239       GST_ERROR ("Failed to copy buffer");
4240       gst_clear_buffer (&new_buffer);
4241       goto out;
4242     }
4243   }
4244 
4245   /* check whether we need to update temporal id and layer id.
4246    * If it's not matched to slice nalu, update it.
4247    */
4248   if (sei_nalu.layer_id != nalu.layer_id || sei_nalu.temporal_id_plus1 !=
4249       nalu.temporal_id_plus1) {
4250     guint16 nalu_header;
4251     guint16 layer_id_temporal_id = 0;
4252     new_mem = gst_memory_copy (sei, 0, -1);
4253 
4254     if (!gst_memory_map (new_mem, &sei_info, GST_MAP_READWRITE)) {
4255       GST_ERROR ("Failed to map new sei memory");
4256       gst_memory_unref (new_mem);
4257       gst_clear_buffer (&new_buffer);
4258       goto out;
4259     }
4260 
4261     nalu_header = GST_READ_UINT16_BE (sei_info.data + sei_nalu.offset);
4262 
4263     /* clear bits 7 ~ 15
4264      * NOTE:
4265      * bit 0: forbidden_zero_bit
4266      * bits 1 ~ 6: nalu type */
4267     nalu_header &= 0xfe00;
4268 
4269     layer_id_temporal_id = ((nalu.layer_id << 3) & 0x1f8);
4270     layer_id_temporal_id |= (nalu.temporal_id_plus1 & 0x7);
4271 
4272     nalu_header |= layer_id_temporal_id;
4273     GST_WRITE_UINT16_BE (sei_info.data + sei_nalu.offset, nalu_header);
4274     gst_memory_unmap (new_mem, &sei_info);
4275   } else {
4276     new_mem = gst_memory_ref (sei);
4277   }
4278 
4279   /* insert sei */
4280   gst_buffer_append_memory (new_buffer, new_mem);
4281 
4282   /* copy the rest */
4283   if (!gst_buffer_copy_into (new_buffer, au,
4284           GST_BUFFER_COPY_MEMORY, nalu.sc_offset, -1)) {
4285     GST_ERROR ("Failed to copy buffer");
4286     gst_clear_buffer (&new_buffer);
4287     goto out;
4288   }
4289 
4290 out:
4291   return new_buffer;
4292 }
4293 
4294 /**
4295  * gst_h265_parser_insert_sei:
4296  * @parser: a #GstH265Parser
4297  * @au: (transfer none): a #GstBuffer containing AU data
4298  * @sei: (transfer none): a #GstMemory containing a SEI nal
4299  *
4300  * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4301  * The validation for completeness of @au and @sei is caller's responsibility.
4302  * Both @au and @sei must be byte-stream formatted
4303  *
4304  * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4305  *   if cannot figure out proper position to insert a @sei
4306  *
4307  * Since: 1.18
4308  */
4309 GstBuffer *
gst_h265_parser_insert_sei(GstH265Parser * parser,GstBuffer * au,GstMemory * sei)4310 gst_h265_parser_insert_sei (GstH265Parser * parser, GstBuffer * au,
4311     GstMemory * sei)
4312 {
4313   g_return_val_if_fail (parser != NULL, NULL);
4314   g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4315   g_return_val_if_fail (sei != NULL, NULL);
4316 
4317   /* the size of start code prefix (3 or 4) is not matter since it will be
4318    * scanned */
4319   return gst_h265_parser_insert_sei_internal (parser, 4, FALSE, au, sei);
4320 }
4321 
4322 /**
4323  * gst_h265_parser_insert_sei_hevc:
4324  * @parser: a #GstH265Parser
4325  * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4326  * @au: (transfer none): a #GstBuffer containing AU data
4327  * @sei: (transfer none): a #GstMemory containing a SEI nal
4328  *
4329  * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4330  * The validation for completeness of @au and @sei is caller's responsibility.
4331  * Nal prefix type of both @au and @sei must be packetized, and
4332  * also the size of nal length field must be identical to @nal_length_size
4333  *
4334  * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4335  *   if cannot figure out proper position to insert a @sei
4336  *
4337  * Since: 1.18
4338  */
4339 GstBuffer *
gst_h265_parser_insert_sei_hevc(GstH265Parser * parser,guint8 nal_length_size,GstBuffer * au,GstMemory * sei)4340 gst_h265_parser_insert_sei_hevc (GstH265Parser * parser, guint8 nal_length_size,
4341     GstBuffer * au, GstMemory * sei)
4342 {
4343   g_return_val_if_fail (parser != NULL, NULL);
4344   g_return_val_if_fail (nal_length_size > 0 && nal_length_size < 5, NULL);
4345   g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4346   g_return_val_if_fail (sei != NULL, NULL);
4347 
4348   return gst_h265_parser_insert_sei_internal (parser, nal_length_size, TRUE,
4349       au, sei);
4350 }
4351 
4352 /**
4353  * gst_h265_get_profile_from_sps:
4354  * @sps: a #GstH265SPS
4355  *
4356  * Return the H265 profile from @sps.
4357  *
4358  * Returns: a #GstH265Profile
4359  * Since: 1.20
4360  */
4361 GstH265Profile
gst_h265_get_profile_from_sps(GstH265SPS * sps)4362 gst_h265_get_profile_from_sps (GstH265SPS * sps)
4363 {
4364   GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
4365   GstH265ProfileTierLevel tmp_ptl;
4366   guint i, len = 0;
4367   guint chroma_format_idc, bit_depth_luma, bit_depth_chroma;
4368 
4369   g_return_val_if_fail (sps != NULL, GST_H265_PROFILE_INVALID);
4370 
4371   tmp_ptl = sps->profile_tier_level;
4372   chroma_format_idc = sps->chroma_format_idc;
4373   bit_depth_luma = sps->bit_depth_luma_minus8 + 8;
4374   bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
4375 
4376   gst_h265_profile_tier_level_get_profiles (&sps->profile_tier_level, profiles,
4377       &len);
4378 
4379   for (i = 0; i < len && i < G_N_ELEMENTS (profiles); i++) {
4380     switch (profiles[i]) {
4381       case GST_H265_PROFILE_INVALID:
4382         break;
4383       case GST_H265_PROFILE_MAIN:
4384       case GST_H265_PROFILE_MAIN_STILL_PICTURE:
4385         /* A.3.2 or A.3.5 */
4386         if (chroma_format_idc == 1
4387             && bit_depth_luma == 8 && bit_depth_chroma == 8)
4388           return profiles[i];
4389         break;
4390       case GST_H265_PROFILE_MAIN_10:
4391         /* A.3.3 */
4392         if (chroma_format_idc == 1
4393             && bit_depth_luma >= 8 && bit_depth_luma <= 10
4394             && bit_depth_chroma >= 8 && bit_depth_chroma <= 10)
4395           return profiles[i];
4396         break;
4397       default:
4398         return profiles[i];
4399     }
4400   }
4401 
4402   /* Invalid profile: */
4403   /* Set the conformance indicators based on chroma_format_idc / bit_depth */
4404   switch (chroma_format_idc) {
4405     case 0:
4406       tmp_ptl.max_monochrome_constraint_flag = 1;
4407       tmp_ptl.max_420chroma_constraint_flag = 1;
4408       tmp_ptl.max_422chroma_constraint_flag = 1;
4409       break;
4410 
4411     case 1:
4412       tmp_ptl.max_monochrome_constraint_flag = 0;
4413       tmp_ptl.max_420chroma_constraint_flag = 1;
4414       tmp_ptl.max_422chroma_constraint_flag = 1;
4415       break;
4416 
4417     case 2:
4418       tmp_ptl.max_monochrome_constraint_flag = 0;
4419       tmp_ptl.max_420chroma_constraint_flag = 0;
4420       tmp_ptl.max_422chroma_constraint_flag = 1;
4421       break;
4422 
4423     case 3:
4424       tmp_ptl.max_monochrome_constraint_flag = 0;
4425       tmp_ptl.max_420chroma_constraint_flag = 0;
4426       tmp_ptl.max_422chroma_constraint_flag = 0;
4427       break;
4428 
4429     default:
4430       g_assert_not_reached ();
4431       break;
4432   }
4433 
4434   tmp_ptl.max_8bit_constraint_flag = 1;
4435   tmp_ptl.max_10bit_constraint_flag = 1;
4436   tmp_ptl.max_12bit_constraint_flag = 1;
4437   tmp_ptl.max_14bit_constraint_flag = 1;
4438 
4439   if (bit_depth_luma > 8 || bit_depth_chroma > 8)
4440     tmp_ptl.max_8bit_constraint_flag = 0;
4441 
4442   if (bit_depth_luma > 10 || bit_depth_chroma > 10)
4443     tmp_ptl.max_10bit_constraint_flag = 0;
4444 
4445   if (bit_depth_luma > 12 || bit_depth_chroma > 12)
4446     tmp_ptl.max_12bit_constraint_flag = 0;
4447 
4448   if (tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
4449       || tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
4450       || tmp_ptl.profile_idc ==
4451       GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION
4452       || tmp_ptl.profile_idc ==
4453       GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION
4454       || tmp_ptl.profile_compatibility_flag[5]
4455       || tmp_ptl.profile_compatibility_flag[9]
4456       || tmp_ptl.profile_compatibility_flag[10]
4457       || tmp_ptl.profile_compatibility_flag[11]) {
4458     if (bit_depth_luma > 14 || bit_depth_chroma > 14)
4459       tmp_ptl.max_14bit_constraint_flag = 0;
4460   } else {
4461     tmp_ptl.max_14bit_constraint_flag = 0;
4462   }
4463 
4464   /* first profile of the synthetic ptl */
4465   return gst_h265_profile_tier_level_get_profile (&tmp_ptl);
4466 }
4467