• 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   READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
1674 
1675   /* skip reserved_0xffff_16bits */
1676   if (!nal_reader_skip (&nr, 16))
1677     goto error;
1678 
1679   if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
1680           vps->max_sub_layers_minus1))
1681     goto error;
1682 
1683   READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);
1684 
1685   for (i =
1686       (vps->sub_layer_ordering_info_present_flag ? 0 :
1687           vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
1688     READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
1689     READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
1690         vps->max_dec_pic_buffering_minus1[i]);
1691     READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1692   }
1693   /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
1694   if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
1695     for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
1696       vps->max_dec_pic_buffering_minus1[i] =
1697           vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
1698       vps->max_num_reorder_pics[i] =
1699           vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
1700       vps->max_latency_increase_plus1[i] =
1701           vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
1702     }
1703   }
1704 
1705   READ_UINT8 (&nr, vps->max_layer_id, 6);
1706   /* shall allow 63 */
1707   CHECK_ALLOWED_MAX (vps->max_layer_id, 63);
1708 
1709   READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
1710   /* allowed range is 0 to 1023 */
1711   CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 1023);
1712 
1713   for (i = 1; i <= vps->num_layer_sets_minus1; i++) {
1714     for (j = 0; j <= vps->max_layer_id; j++) {
1715       /* layer_id_included_flag[i][j] */
1716       /* FIXME: need to parse this when we can support parsing multi-layer info. */
1717       nal_reader_skip (&nr, 1);
1718     }
1719   }
1720 
1721   READ_UINT8 (&nr, vps->timing_info_present_flag, 1);
1722 
1723   if (vps->timing_info_present_flag) {
1724     READ_UINT32 (&nr, vps->num_units_in_tick, 32);
1725     READ_UINT32 (&nr, vps->time_scale, 32);
1726     READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);
1727 
1728     if (vps->poc_proportional_to_timing_flag)
1729       READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);
1730 
1731     READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
1732     /* allowed range is
1733      * 0 to vps_num_layer_sets_minus1 + 1 */
1734     CHECK_ALLOWED_MAX (vps->num_hrd_parameters, vps->num_layer_sets_minus1 + 1);
1735 
1736     if (vps->num_hrd_parameters) {
1737       READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
1738       /* allowed range is
1739        * ( vps_base_layer_internal_flag ? 0 : 1 ) to vps_num_layer_sets_minus1
1740        */
1741       CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, vps->num_layer_sets_minus1);
1742 
1743       if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
1744               vps->cprms_present_flag, vps->max_sub_layers_minus1))
1745         goto error;
1746     }
1747 
1748     /* FIXME: VPS can have multiple hrd parameters, and therefore hrd_params
1749      * should be an array (like Garray). But it also requires new _clear()
1750      * method for free the array in GstH265VPS whenever gst_h265_parse_vps()
1751      * is called. Need to work for multi-layer related parsing supporting
1752      *
1753      * FIXME: Following code is just work around to find correct
1754      * vps_extension position */
1755 
1756     /* skip the first parsed one above */
1757     for (i = 1; i < vps->num_hrd_parameters; i++) {
1758       guint16 hrd_layer_set_idx;
1759       guint8 cprms_present_flag;
1760       GstH265HRDParams hrd_params;
1761 
1762       READ_UE_MAX (&nr, hrd_layer_set_idx, 1023);
1763       CHECK_ALLOWED_MAX (hrd_layer_set_idx, vps->num_layer_sets_minus1);
1764 
1765       /* need parsing if (i > 1) */
1766       READ_UINT8 (&nr, cprms_present_flag, 1);
1767 
1768       if (!gst_h265_parse_hrd_parameters (&hrd_params, &nr,
1769               cprms_present_flag, vps->max_sub_layers_minus1))
1770         goto error;
1771     }
1772   }
1773   READ_UINT8 (&nr, vps->vps_extension, 1);
1774   vps->valid = TRUE;
1775 
1776   return GST_H265_PARSER_OK;
1777 
1778 error:
1779   GST_WARNING ("error parsing \"Video parameter set\"");
1780   vps->valid = FALSE;
1781   return GST_H265_PARSER_ERROR;
1782 }
1783 
1784 /**
1785  * gst_h265_parser_parse_sps:
1786  * @parser: a #GstH265Parser
1787  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1788  * @sps: The #GstH265SPS to fill.
1789  * @parse_vui_params: Whether to parse the vui_params or not
1790  *
1791  * Parses @data, and fills the @sps structure.
1792  *
1793  * Returns: a #GstH265ParserResult
1794  */
1795 GstH265ParserResult
gst_h265_parser_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1796 gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1797     GstH265SPS * sps, gboolean parse_vui_params)
1798 {
1799   GstH265ParserResult res =
1800       gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);
1801 
1802   if (res == GST_H265_PARSER_OK) {
1803     GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1804 
1805     parser->sps[sps->id] = *sps;
1806     parser->last_sps = &parser->sps[sps->id];
1807   }
1808 
1809   return res;
1810 }
1811 
1812 /**
1813  * gst_h265_parse_sps:
1814  * parser: The #GstH265Parser
1815  * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
1816  * @sps: The #GstH265SPS to fill.
1817  * @parse_vui_params: Whether to parse the vui_params or not
1818  *
1819  * Parses @data, and fills the @sps structure.
1820  *
1821  * Returns: a #GstH265ParserResult
1822  */
1823 GstH265ParserResult
gst_h265_parse_sps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SPS * sps,gboolean parse_vui_params)1824 gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
1825     GstH265SPS * sps, gboolean parse_vui_params)
1826 {
1827   NalReader nr;
1828   GstH265VPS *vps;
1829   guint8 vps_id;
1830   guint i;
1831   guint subwc[] = { 1, 2, 2, 1, 1 };
1832   guint subhc[] = { 1, 2, 1, 1, 1 };
1833   GstH265VUIParams *vui = NULL;
1834 
1835   GST_DEBUG ("parsing SPS");
1836 
1837   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1838       nalu->size - nalu->header_bytes);
1839 
1840   memset (sps, 0, sizeof (*sps));
1841 
1842   READ_UINT8 (&nr, vps_id, 4);
1843   vps = gst_h265_parser_get_vps (parser, vps_id);
1844   if (!vps) {
1845     GST_DEBUG ("couldn't find associated video parameter set with id: %d",
1846         vps_id);
1847   }
1848   sps->vps = vps;
1849 
1850   READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
1851   READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
1852 
1853   if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
1854           sps->max_sub_layers_minus1))
1855     goto error;
1856 
1857   READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);
1858 
1859   READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
1860   if (sps->chroma_format_idc == 3)
1861     READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1862 
1863   READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
1864   READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);
1865 
1866   READ_UINT8 (&nr, sps->conformance_window_flag, 1);
1867   if (sps->conformance_window_flag) {
1868     READ_UE (&nr, sps->conf_win_left_offset);
1869     READ_UE (&nr, sps->conf_win_right_offset);
1870     READ_UE (&nr, sps->conf_win_top_offset);
1871     READ_UE (&nr, sps->conf_win_bottom_offset);
1872   }
1873 
1874   READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
1875   READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
1876   READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1877 
1878   READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
1879   for (i =
1880       (sps->sub_layer_ordering_info_present_flag ? 0 :
1881           sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
1882     READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
1883     READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
1884         sps->max_dec_pic_buffering_minus1[i]);
1885     READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
1886   }
1887   /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
1888   if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
1889     for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
1890       sps->max_dec_pic_buffering_minus1[i] =
1891           sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
1892       sps->max_num_reorder_pics[i] =
1893           sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
1894       sps->max_latency_increase_plus1[i] =
1895           sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
1896     }
1897   }
1898 
1899   /* The limits are calculted based on the profile_tier_level constraint
1900    * in Annex-A: CtbLog2SizeY = 4 to 6 */
1901   READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
1902   READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
1903   READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
1904   READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
1905   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
1906   READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);
1907 
1908   READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
1909   if (sps->scaling_list_enabled_flag) {
1910     READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);
1911 
1912     if (sps->scaling_list_data_present_flag)
1913       if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
1914         goto error;
1915   }
1916 
1917   READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
1918   READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
1919   READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);
1920 
1921   if (sps->pcm_enabled_flag) {
1922     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
1923     READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
1924     READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
1925     READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
1926     READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
1927   }
1928 
1929   READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
1930   for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
1931     if (!gst_h265_parser_parse_short_term_ref_pic_sets
1932         (&sps->short_term_ref_pic_set[i], &nr, i, sps))
1933       goto error;
1934 
1935   READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
1936   if (sps->long_term_ref_pics_present_flag) {
1937     READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
1938     for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
1939       READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
1940           sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1941       READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
1942     }
1943   }
1944 
1945   READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
1946   READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
1947   READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1948 
1949   if (sps->vui_parameters_present_flag && parse_vui_params) {
1950     if (!gst_h265_parse_vui_parameters (sps, &nr))
1951       goto error;
1952     vui = &sps->vui_params;
1953   }
1954 
1955   READ_UINT8 (&nr, sps->sps_extension_flag, 1);
1956 
1957   if (sps->sps_extension_flag) {
1958     READ_UINT8 (&nr, sps->sps_range_extension_flag, 1);
1959     READ_UINT8 (&nr, sps->sps_multilayer_extension_flag, 1);
1960     READ_UINT8 (&nr, sps->sps_3d_extension_flag, 1);
1961     READ_UINT8 (&nr, sps->sps_scc_extension_flag, 1);
1962     READ_UINT8 (&nr, sps->sps_extension_4bits, 4);
1963   }
1964 
1965   if (sps->sps_range_extension_flag) {
1966     READ_UINT8 (&nr,
1967         sps->sps_extnsion_params.transform_skip_rotation_enabled_flag, 1);
1968     READ_UINT8 (&nr,
1969         sps->sps_extnsion_params.transform_skip_context_enabled_flag, 1);
1970     READ_UINT8 (&nr, sps->sps_extnsion_params.implicit_rdpcm_enabled_flag, 1);
1971     READ_UINT8 (&nr, sps->sps_extnsion_params.explicit_rdpcm_enabled_flag, 1);
1972     READ_UINT8 (&nr,
1973         sps->sps_extnsion_params.extended_precision_processing_flag, 1);
1974     READ_UINT8 (&nr, sps->sps_extnsion_params.intra_smoothing_disabled_flag, 1);
1975     READ_UINT8 (&nr,
1976         sps->sps_extnsion_params.high_precision_offsets_enabled_flag, 1);
1977     READ_UINT8 (&nr,
1978         sps->sps_extnsion_params.persistent_rice_adaptation_enabled_flag, 1);
1979     READ_UINT8 (&nr,
1980         sps->sps_extnsion_params.cabac_bypass_alignment_enabled_flag, 1);
1981   }
1982 
1983   if (sps->sps_multilayer_extension_flag) {
1984     GST_WARNING ("do not support multilayer extension, skip all"
1985         " remaining bits");
1986     goto done;
1987   }
1988   if (sps->sps_3d_extension_flag) {
1989     GST_WARNING ("do not support 3d extension, skip all remaining bits");
1990     goto done;
1991   }
1992 
1993   if (sps->sps_scc_extension_flag) {
1994     READ_UINT8 (&nr,
1995         sps->sps_scc_extension_params.sps_curr_pic_ref_enabled_flag, 1);
1996     READ_UINT8 (&nr, sps->sps_scc_extension_params.palette_mode_enabled_flag,
1997         1);
1998     if (sps->sps_scc_extension_params.palette_mode_enabled_flag) {
1999       READ_UE_MAX (&nr, sps->sps_scc_extension_params.palette_max_size, 64);
2000       READ_UE_MAX (&nr,
2001           sps->sps_scc_extension_params.delta_palette_max_predictor_size,
2002           128 - sps->sps_scc_extension_params.palette_max_size);
2003 
2004       READ_UINT8 (&nr,
2005           sps->sps_scc_extension_params.
2006           sps_palette_predictor_initializers_present_flag, 1);
2007       if (sps->sps_scc_extension_params.
2008           sps_palette_predictor_initializers_present_flag) {
2009         guint comp;
2010         READ_UE_MAX (&nr,
2011             sps->sps_scc_extension_params.
2012             sps_num_palette_predictor_initializer_minus1,
2013             sps->sps_scc_extension_params.palette_max_size +
2014             sps->sps_scc_extension_params.delta_palette_max_predictor_size - 1);
2015 
2016         for (comp = 0; comp < (sps->chroma_format_idc == 0 ? 1 : 3); comp++) {
2017           guint num_bits;
2018           guint num =
2019               sps->sps_scc_extension_params.
2020               sps_num_palette_predictor_initializer_minus1 + 1;
2021 
2022           num_bits = (comp == 0 ? sps->bit_depth_luma_minus8 + 8 :
2023               sps->bit_depth_chroma_minus8 + 8);
2024           for (i = 0; i < num; i++)
2025             READ_UINT32 (&nr,
2026                 sps->sps_scc_extension_params.sps_palette_predictor_initializer
2027                 [comp]
2028                 [i], num_bits);
2029         }
2030       }
2031     }
2032 
2033     READ_UINT8 (&nr,
2034         sps->sps_scc_extension_params.motion_vector_resolution_control_idc, 2);
2035     READ_UINT8 (&nr,
2036         sps->sps_scc_extension_params.intra_boundary_filtering_disabled_flag,
2037         1);
2038   }
2039 
2040 done:
2041   /* calculate ChromaArrayType */
2042   if (!sps->separate_colour_plane_flag)
2043     sps->chroma_array_type = sps->chroma_format_idc;
2044 
2045   /* Calculate  width and height */
2046   sps->width = sps->pic_width_in_luma_samples;
2047   sps->height = sps->pic_height_in_luma_samples;
2048   if (sps->width < 0 || sps->height < 0) {
2049     GST_WARNING ("invalid width/height in SPS");
2050     goto error;
2051   }
2052 
2053   if (sps->conformance_window_flag) {
2054     const guint crop_unit_x = subwc[sps->chroma_format_idc];
2055     const guint crop_unit_y = subhc[sps->chroma_format_idc];
2056 
2057     sps->crop_rect_width = sps->width -
2058         (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
2059     sps->crop_rect_height = sps->height -
2060         (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
2061     sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
2062     sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
2063 
2064     GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
2065         sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
2066   }
2067 
2068   sps->fps_num = 0;
2069   sps->fps_den = 1;
2070 
2071   if (vui && vui->timing_info_present_flag) {
2072     /* derive framerate for progressive stream if the pic_struct
2073      * syntax element is not present in picture timing SEI messages */
2074     /* Fixme: handle other cases also */
2075     if (parse_vui_params && vui->timing_info_present_flag
2076         && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
2077       sps->fps_num = vui->time_scale;
2078       sps->fps_den = vui->num_units_in_tick;
2079       GST_LOG ("framerate %d/%d in VUI", sps->fps_num, sps->fps_den);
2080     }
2081   } else if (vps && vps->timing_info_present_flag) {
2082     sps->fps_num = vps->time_scale;
2083     sps->fps_den = vps->num_units_in_tick;
2084     GST_LOG ("framerate %d/%d in VPS", sps->fps_num, sps->fps_den);
2085   } else {
2086     GST_LOG ("No VUI, unknown framerate");
2087   }
2088 
2089   sps->valid = TRUE;
2090 
2091   return GST_H265_PARSER_OK;
2092 
2093 error:
2094   GST_WARNING ("error parsing \"Sequence parameter set\"");
2095   sps->valid = FALSE;
2096   return GST_H265_PARSER_ERROR;
2097 }
2098 
2099 /**
2100  * gst_h265_parse_pps:
2101  * @parser: a #GstH265Parser
2102  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2103  * @pps: The #GstH265PPS to fill.
2104  *
2105  * Parses @data, and fills the @pps structure.
2106  *
2107  * Returns: a #GstH265ParserResult
2108  */
2109 GstH265ParserResult
gst_h265_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2110 gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
2111     GstH265PPS * pps)
2112 {
2113   NalReader nr;
2114   GstH265SPS *sps;
2115   gint sps_id;
2116   gint qp_bd_offset;
2117   guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY, MaxBitDepthY, MaxBitDepthC;
2118   guint8 i;
2119 
2120   GST_DEBUG ("parsing PPS");
2121 
2122   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2123       nalu->size - nalu->header_bytes);
2124 
2125   memset (pps, 0, sizeof (*pps));
2126 
2127   READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
2128   READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
2129 
2130   sps = gst_h265_parser_get_sps (parser, sps_id);
2131   if (!sps) {
2132     GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
2133         sps_id);
2134     return GST_H265_PARSER_BROKEN_LINK;
2135   }
2136   pps->sps = sps;
2137   qp_bd_offset = 6 * sps->bit_depth_luma_minus8;
2138 
2139   MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
2140   CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
2141   CtbSizeY = 1 << CtbLog2SizeY;
2142   pps->PicHeightInCtbsY =
2143       ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
2144   pps->PicWidthInCtbsY =
2145       ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);
2146 
2147   /* set default values for fields that might not be present in the bitstream
2148      and have valid defaults */
2149   pps->uniform_spacing_flag = 1;
2150   pps->loop_filter_across_tiles_enabled_flag = 1;
2151 
2152   READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
2153   READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
2154   READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
2155   READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
2156   READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);
2157 
2158   READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
2159   READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
2160   READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);
2161 
2162   READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
2163   READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);
2164 
2165   READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
2166   if (pps->cu_qp_delta_enabled_flag)
2167     READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
2168         sps->log2_diff_max_min_luma_coding_block_size);
2169 
2170   READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
2171   READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);
2172 
2173   READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
2174   READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
2175   READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
2176   READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
2177   READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
2178   READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
2179 
2180   if (pps->tiles_enabled_flag) {
2181     READ_UE_ALLOWED (&nr,
2182         pps->num_tile_columns_minus1, 0, pps->PicWidthInCtbsY - 1);
2183     READ_UE_ALLOWED (&nr,
2184         pps->num_tile_rows_minus1, 0, pps->PicHeightInCtbsY - 1);
2185 
2186     if (pps->num_tile_columns_minus1 + 1 >
2187         G_N_ELEMENTS (pps->column_width_minus1)) {
2188       GST_WARNING ("Invalid \"num_tile_columns_minus1\" %d",
2189           pps->num_tile_columns_minus1);
2190       goto error;
2191     }
2192 
2193     if (pps->num_tile_rows_minus1 + 1 > G_N_ELEMENTS (pps->row_height_minus1)) {
2194       GST_WARNING ("Invalid \"num_tile_rows_minus1\" %d",
2195           pps->num_tile_rows_minus1);
2196       goto error;
2197     }
2198 
2199     READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
2200     /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
2201     if (pps->uniform_spacing_flag) {
2202       guint8 num_col = pps->num_tile_columns_minus1 + 1;
2203       guint8 num_row = pps->num_tile_rows_minus1 + 1;
2204       for (i = 0; i < num_col; i++) {
2205         pps->column_width_minus1[i] =
2206             ((i + 1) * pps->PicWidthInCtbsY / num_col
2207             - i * pps->PicWidthInCtbsY / num_col) - 1;
2208       }
2209       for (i = 0; i < num_row; i++) {
2210         pps->row_height_minus1[i] =
2211             ((i + 1) * pps->PicHeightInCtbsY / num_row
2212             - i * pps->PicHeightInCtbsY / num_row) - 1;
2213       }
2214     } else {
2215       pps->column_width_minus1[pps->num_tile_columns_minus1] =
2216           pps->PicWidthInCtbsY - 1;
2217       for (i = 0; i < pps->num_tile_columns_minus1; i++) {
2218         READ_UE (&nr, pps->column_width_minus1[i]);
2219         pps->column_width_minus1[pps->num_tile_columns_minus1] -=
2220             (pps->column_width_minus1[i] + 1);
2221       }
2222 
2223       pps->row_height_minus1[pps->num_tile_rows_minus1] =
2224           pps->PicHeightInCtbsY - 1;
2225       for (i = 0; i < pps->num_tile_rows_minus1; i++) {
2226         READ_UE (&nr, pps->row_height_minus1[i]);
2227         pps->row_height_minus1[pps->num_tile_rows_minus1] -=
2228             (pps->row_height_minus1[i] + 1);
2229       }
2230     }
2231     READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
2232   }
2233 
2234   READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);
2235 
2236   READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
2237   if (pps->deblocking_filter_control_present_flag) {
2238     READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);
2239 
2240     READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
2241     if (!pps->deblocking_filter_disabled_flag) {
2242       READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
2243       READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
2244     }
2245   }
2246 
2247   READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
2248   if (pps->scaling_list_data_present_flag)
2249     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
2250       goto error;
2251   if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
2252       && !pps->scaling_list_data_present_flag)
2253     if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
2254       goto error;
2255 
2256   READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
2257   READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
2258   READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
2259   READ_UINT8 (&nr, pps->pps_extension_flag, 1);
2260 
2261   if (pps->pps_extension_flag) {
2262     READ_UINT8 (&nr, pps->pps_range_extension_flag, 1);
2263     READ_UINT8 (&nr, pps->pps_multilayer_extension_flag, 1);
2264     READ_UINT8 (&nr, pps->pps_3d_extension_flag, 1);
2265     READ_UINT8 (&nr, pps->pps_scc_extension_flag, 1);
2266     READ_UINT8 (&nr, pps->pps_extension_4bits, 4);
2267   }
2268 
2269   if (pps->pps_range_extension_flag) {
2270     if (pps->transform_skip_enabled_flag)
2271       READ_UE (&nr,
2272           pps->pps_extension_params.log2_max_transform_skip_block_size_minus2);
2273     READ_UINT8 (&nr,
2274         pps->pps_extension_params.cross_component_prediction_enabled_flag, 1);
2275     READ_UINT8 (&nr,
2276         pps->pps_extension_params.chroma_qp_offset_list_enabled_flag, 1);
2277     if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag) {
2278       READ_UE_MAX (&nr,
2279           pps->pps_extension_params.diff_cu_chroma_qp_offset_depth,
2280           sps->log2_diff_max_min_luma_coding_block_size);
2281       READ_UE_MAX (&nr,
2282           pps->pps_extension_params.chroma_qp_offset_list_len_minus1, 5);
2283       for (i = 0;
2284           i <= pps->pps_extension_params.chroma_qp_offset_list_len_minus1;
2285           i++) {
2286         READ_SE_ALLOWED (&nr, pps->pps_extension_params.cb_qp_offset_list[i],
2287             -12, 12);
2288         READ_SE_ALLOWED (&nr, pps->pps_extension_params.cr_qp_offset_list[i],
2289             -12, 12);
2290       }
2291     }
2292     MaxBitDepthY =
2293         sps->bit_depth_luma_minus8 > 2 ? sps->bit_depth_luma_minus8 - 2 : 0;
2294     MaxBitDepthC =
2295         sps->bit_depth_chroma_minus8 > 2 ? sps->bit_depth_chroma_minus8 - 2 : 0;
2296     READ_UE_ALLOWED (&nr, pps->pps_extension_params.log2_sao_offset_scale_luma,
2297         0, MaxBitDepthY);
2298     READ_UE_ALLOWED (&nr,
2299         pps->pps_extension_params.log2_sao_offset_scale_chroma, 0,
2300         MaxBitDepthC);
2301   }
2302 
2303   if (pps->pps_multilayer_extension_flag) {
2304     GST_WARNING ("do not support multilayer extension, skip all"
2305         " remaining bits");
2306     goto done;
2307   }
2308   if (pps->pps_3d_extension_flag) {
2309     GST_WARNING ("do not support 3d extension, skip all remaining bits");
2310     goto done;
2311   }
2312 
2313   if (pps->pps_scc_extension_flag) {
2314     READ_UINT8 (&nr,
2315         pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag, 1);
2316     READ_UINT8 (&nr,
2317         pps->pps_scc_extension_params.
2318         residual_adaptive_colour_transform_enabled_flag, 1);
2319     if (pps->pps_scc_extension_params.
2320         residual_adaptive_colour_transform_enabled_flag) {
2321       READ_UINT8 (&nr,
2322           pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag,
2323           1);
2324       READ_SE_ALLOWED (&nr,
2325           pps->pps_scc_extension_params.pps_act_y_qp_offset_plus5, -7, 17);
2326       READ_SE_ALLOWED (&nr,
2327           pps->pps_scc_extension_params.pps_act_cb_qp_offset_plus5, -7, 17);
2328       READ_SE_ALLOWED (&nr,
2329           pps->pps_scc_extension_params.pps_act_cr_qp_offset_plus3, -9, 15);
2330     }
2331 
2332     READ_UINT8 (&nr,
2333         pps->pps_scc_extension_params.
2334         pps_palette_predictor_initializers_present_flag, 1);
2335     if (pps->pps_scc_extension_params.
2336         pps_palette_predictor_initializers_present_flag) {
2337       READ_UE_MAX (&nr,
2338           pps->pps_scc_extension_params.pps_num_palette_predictor_initializer,
2339           sps->sps_scc_extension_params.palette_max_size +
2340           sps->sps_scc_extension_params.delta_palette_max_predictor_size);
2341       if (pps->pps_scc_extension_params.pps_num_palette_predictor_initializer >
2342           0) {
2343         guint comp;
2344 
2345         READ_UINT8 (&nr, pps->pps_scc_extension_params.monochrome_palette_flag,
2346             1);
2347         /* It is a requirement of bitstream conformance that the value of
2348            luma_bit_depth_entry_minus8 shall be equal to the value of
2349            bit_depth_luma_minus8 */
2350         READ_UE_ALLOWED (&nr,
2351             pps->pps_scc_extension_params.luma_bit_depth_entry_minus8,
2352             sps->bit_depth_luma_minus8, sps->bit_depth_luma_minus8);
2353         if (!pps->pps_scc_extension_params.monochrome_palette_flag) {
2354           /* It is a requirement of bitstream conformance that the value
2355              of chroma_bit_depth_entry_minus8 shall be equal to the value
2356              of bit_depth_chroma_minus8. */
2357           READ_UE_ALLOWED (&nr,
2358               pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8,
2359               sps->bit_depth_chroma_minus8, sps->bit_depth_chroma_minus8);
2360         }
2361 
2362         for (comp = 0; comp <
2363             (pps->pps_scc_extension_params.monochrome_palette_flag ? 1 : 3);
2364             comp++) {
2365           guint num_bits;
2366           guint num =
2367               pps->pps_scc_extension_params.
2368               pps_num_palette_predictor_initializer;
2369 
2370           num_bits = (comp == 0 ?
2371               pps->pps_scc_extension_params.luma_bit_depth_entry_minus8 + 8 :
2372               pps->pps_scc_extension_params.chroma_bit_depth_entry_minus8 + 8);
2373           for (i = 0; i < num; i++)
2374             READ_UINT32 (&nr,
2375                 pps->pps_scc_extension_params.pps_palette_predictor_initializer
2376                 [comp][i], num_bits);
2377         }
2378       }
2379     }
2380   }
2381 
2382 done:
2383   pps->valid = TRUE;
2384   return GST_H265_PARSER_OK;
2385 
2386 error:
2387   GST_WARNING ("error parsing \"Picture parameter set\"");
2388   pps->valid = FALSE;
2389   return GST_H265_PARSER_ERROR;
2390 }
2391 
2392 /**
2393  * gst_h265_parser_parse_pps:
2394  * @parser: a #GstH265Parser
2395  * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
2396  * @pps: The #GstH265PPS to fill.
2397  *
2398  * Parses @data, and fills the @pps structure.
2399  *
2400  * Returns: a #GstH265ParserResult
2401  */
2402 GstH265ParserResult
gst_h265_parser_parse_pps(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265PPS * pps)2403 gst_h265_parser_parse_pps (GstH265Parser * parser,
2404     GstH265NalUnit * nalu, GstH265PPS * pps)
2405 {
2406   GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
2407   if (res == GST_H265_PARSER_OK) {
2408     GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
2409 
2410     parser->pps[pps->id] = *pps;
2411     parser->last_pps = &parser->pps[pps->id];
2412   }
2413 
2414   return res;
2415 }
2416 
2417 /**
2418  * gst_h265_parser_parse_slice_hdr:
2419  * @parser: a #GstH265Parser
2420  * @nalu: The `GST_H265_NAL_SLICE` #GstH265NalUnit to parse
2421  * @slice: The #GstH265SliceHdr to fill.
2422  *
2423  * Parses @data, and fills the @slice structure.
2424  * The resulting @slice_hdr structure shall be deallocated with
2425  * gst_h265_slice_hdr_free() when it is no longer needed
2426  *
2427  * Returns: a #GstH265ParserResult
2428  */
2429 GstH265ParserResult
gst_h265_parser_parse_slice_hdr(GstH265Parser * parser,GstH265NalUnit * nalu,GstH265SliceHdr * slice)2430 gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
2431     GstH265NalUnit * nalu, GstH265SliceHdr * slice)
2432 {
2433   NalReader nr;
2434   gint pps_id;
2435   GstH265PPS *pps;
2436   GstH265SPS *sps;
2437   guint i;
2438   GstH265ShortTermRefPicSet *stRPS = NULL;
2439   guint32 UsedByCurrPicLt[16];
2440   guint32 PicSizeInCtbsY;
2441   gint NumPocTotalCurr = 0;
2442 
2443   memset (slice, 0, sizeof (*slice));
2444 
2445   if (!nalu->size) {
2446     GST_DEBUG ("Invalid Nal Unit");
2447     return GST_H265_PARSER_ERROR;
2448   }
2449 
2450   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2451       nalu->size - nalu->header_bytes);
2452 
2453   GST_DEBUG ("parsing \"Slice header\", slice type");
2454 
2455   READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);
2456 
2457   if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type))
2458     READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);
2459 
2460   READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
2461   pps = gst_h265_parser_get_pps (parser, pps_id);
2462   if (!pps) {
2463     GST_WARNING
2464         ("couldn't find associated picture parameter set with id: %d", pps_id);
2465     return GST_H265_PARSER_BROKEN_LINK;
2466   }
2467 
2468   slice->pps = pps;
2469   sps = pps->sps;
2470   if (!sps) {
2471     GST_WARNING
2472         ("couldn't find associated sequence parameter set with id: %d",
2473         pps->id);
2474     return GST_H265_PARSER_BROKEN_LINK;
2475   }
2476 
2477   PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
2478   /* set default values for fields that might not be present in the bitstream
2479    * and have valid defaults */
2480   slice->pic_output_flag = 1;
2481   slice->collocated_from_l0_flag = 1;
2482   slice->deblocking_filter_disabled_flag = pps->deblocking_filter_disabled_flag;
2483   slice->beta_offset_div2 = pps->beta_offset_div2;
2484   slice->tc_offset_div2 = pps->tc_offset_div2;
2485   slice->loop_filter_across_slices_enabled_flag =
2486       pps->loop_filter_across_slices_enabled_flag;
2487 
2488   if (!slice->first_slice_segment_in_pic_flag) {
2489     const guint n = ceil_log2 (PicSizeInCtbsY);
2490 
2491     if (pps->dependent_slice_segments_enabled_flag)
2492       READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
2493     /* sice_segment_address parsing */
2494     READ_UINT32 (&nr, slice->segment_address, n);
2495   }
2496 
2497   if (!slice->dependent_slice_segment_flag) {
2498     for (i = 0; i < pps->num_extra_slice_header_bits; i++)
2499       nal_reader_skip (&nr, 1);
2500     READ_UE_MAX (&nr, slice->type, 63);
2501 
2502 
2503     if (pps->output_flag_present_flag)
2504       READ_UINT8 (&nr, slice->pic_output_flag, 1);
2505     if (sps->separate_colour_plane_flag == 1)
2506       READ_UINT8 (&nr, slice->colour_plane_id, 2);
2507 
2508     if (!GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
2509       READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
2510           (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2511 
2512       READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
2513       if (!slice->short_term_ref_pic_set_sps_flag) {
2514         guint pos = nal_reader_get_pos (&nr);
2515         if (!gst_h265_parser_parse_short_term_ref_pic_sets
2516             (&slice->short_term_ref_pic_sets, &nr,
2517                 sps->num_short_term_ref_pic_sets, sps))
2518           goto error;
2519 
2520         slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
2521       } else if (sps->num_short_term_ref_pic_sets > 1) {
2522         const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
2523         READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
2524         CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
2525             sps->num_short_term_ref_pic_sets - 1);
2526       }
2527 
2528       if (sps->long_term_ref_pics_present_flag) {
2529         guint32 limit;
2530 
2531         if (sps->num_long_term_ref_pics_sps > 0)
2532           READ_UE_MAX (&nr, slice->num_long_term_sps,
2533               sps->num_long_term_ref_pics_sps);
2534 
2535         READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
2536         limit = slice->num_long_term_sps + slice->num_long_term_pics;
2537         for (i = 0; i < limit; i++) {
2538           if (i < slice->num_long_term_sps) {
2539             if (sps->num_long_term_ref_pics_sps > 1) {
2540               const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
2541               READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
2542             }
2543           } else {
2544             READ_UINT32 (&nr, slice->poc_lsb_lt[i],
2545                 (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
2546             READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
2547           }
2548 
2549           /* calculate UsedByCurrPicLt */
2550           if (i < slice->num_long_term_sps)
2551             UsedByCurrPicLt[i] =
2552                 sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
2553           else
2554             UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
2555           READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
2556           if (slice->delta_poc_msb_present_flag[i])
2557             READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
2558         }
2559       }
2560       if (sps->temporal_mvp_enabled_flag)
2561         READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
2562     }
2563 
2564     if (sps->sample_adaptive_offset_enabled_flag) {
2565       READ_UINT8 (&nr, slice->sao_luma_flag, 1);
2566       if (sps->chroma_array_type)
2567         READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
2568     }
2569 
2570     if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
2571       READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2572 
2573       if (slice->num_ref_idx_active_override_flag) {
2574         READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
2575         if (GST_H265_IS_B_SLICE (slice))
2576           READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
2577       } else {
2578         /*set default values */
2579         slice->num_ref_idx_l0_active_minus1 =
2580             pps->num_ref_idx_l0_default_active_minus1;
2581         slice->num_ref_idx_l1_active_minus1 =
2582             pps->num_ref_idx_l1_default_active_minus1;
2583       }
2584 
2585       /* calculate NumPocTotalCurr */
2586       if (slice->short_term_ref_pic_set_sps_flag)
2587         stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
2588       else
2589         stRPS = &slice->short_term_ref_pic_sets;
2590 
2591       for (i = 0; i < stRPS->NumNegativePics; i++)
2592         if (stRPS->UsedByCurrPicS0[i])
2593           NumPocTotalCurr++;
2594       for (i = 0; i < stRPS->NumPositivePics; i++)
2595         if (stRPS->UsedByCurrPicS1[i])
2596           NumPocTotalCurr++;
2597       for (i = 0;
2598           i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
2599         if (UsedByCurrPicLt[i])
2600           NumPocTotalCurr++;
2601       slice->NumPocTotalCurr = NumPocTotalCurr;
2602 
2603       if (pps->lists_modification_present_flag) {
2604         if (NumPocTotalCurr > 1)
2605           if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
2606                   NumPocTotalCurr))
2607             goto error;
2608       }
2609 
2610       if (GST_H265_IS_B_SLICE (slice))
2611         READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
2612       if (pps->cabac_init_present_flag)
2613         READ_UINT8 (&nr, slice->cabac_init_flag, 1);
2614       if (slice->temporal_mvp_enabled_flag) {
2615         if (GST_H265_IS_B_SLICE (slice))
2616           READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);
2617 
2618         if ((slice->collocated_from_l0_flag
2619                 && slice->num_ref_idx_l0_active_minus1 > 0)
2620             || (!slice->collocated_from_l0_flag
2621                 && slice->num_ref_idx_l1_active_minus1 > 0)) {
2622 
2623           /*fixme: add optimization */
2624           if ((GST_H265_IS_P_SLICE (slice))
2625               || ((GST_H265_IS_B_SLICE (slice))
2626                   && (slice->collocated_from_l0_flag))) {
2627             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2628                 slice->num_ref_idx_l0_active_minus1);
2629           } else if ((GST_H265_IS_B_SLICE (slice))
2630               && (!slice->collocated_from_l0_flag)) {
2631             READ_UE_MAX (&nr, slice->collocated_ref_idx,
2632                 slice->num_ref_idx_l1_active_minus1);
2633           }
2634         }
2635       }
2636       if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
2637           (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
2638         if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
2639           goto error;
2640       READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
2641 
2642       if (sps->sps_scc_extension_params.motion_vector_resolution_control_idc
2643           == 2)
2644         READ_UINT8 (&nr, slice->use_integer_mv_flag, 1);
2645     }
2646 
2647     READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
2648     if (pps->slice_chroma_qp_offsets_present_flag) {
2649       READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
2650       READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
2651     }
2652 
2653     if (pps->pps_scc_extension_params.pps_slice_act_qp_offsets_present_flag) {
2654       READ_SE_ALLOWED (&nr, slice->slice_act_y_qp_offset, -12, 12);
2655       READ_SE_ALLOWED (&nr, slice->slice_act_cb_qp_offset, -12, 12);
2656       READ_SE_ALLOWED (&nr, slice->slice_act_cr_qp_offset, -12, 12);
2657     }
2658 
2659     if (pps->pps_extension_params.chroma_qp_offset_list_enabled_flag)
2660       READ_UINT8 (&nr, slice->cu_chroma_qp_offset_enabled_flag, 1);
2661 
2662     if (pps->deblocking_filter_override_enabled_flag)
2663       READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
2664     if (slice->deblocking_filter_override_flag) {
2665       READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
2666       if (!slice->deblocking_filter_disabled_flag) {
2667         READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
2668         READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
2669       }
2670     }
2671 
2672     if (pps->loop_filter_across_slices_enabled_flag &&
2673         (slice->sao_luma_flag || slice->sao_chroma_flag ||
2674             !slice->deblocking_filter_disabled_flag))
2675       READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
2676   }
2677 
2678   if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
2679     guint32 offset_max;
2680 
2681     if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
2682       offset_max = pps->PicHeightInCtbsY - 1;
2683     else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
2684       offset_max =
2685           (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
2686           1;
2687     else
2688       offset_max =
2689           (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;
2690 
2691     READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
2692     if (slice->num_entry_point_offsets > 0) {
2693       READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
2694       slice->entry_point_offset_minus1 =
2695           g_new0 (guint32, slice->num_entry_point_offsets);
2696       for (i = 0; i < slice->num_entry_point_offsets; i++)
2697         READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
2698             (slice->offset_len_minus1 + 1));
2699     }
2700   }
2701 
2702   if (pps->slice_segment_header_extension_present_flag) {
2703     guint16 slice_segment_header_extension_length;
2704     READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
2705     for (i = 0; i < slice_segment_header_extension_length; i++)
2706       if (!nal_reader_skip (&nr, 8))
2707         goto error;
2708   }
2709 
2710   /* Skip the byte alignment bits */
2711   if (!nal_reader_skip (&nr, 1))
2712     goto error;
2713   while (!nal_reader_is_byte_aligned (&nr)) {
2714     if (!nal_reader_skip (&nr, 1))
2715       goto error;
2716   }
2717 
2718   slice->header_size = nal_reader_get_pos (&nr);
2719   slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2720 
2721   return GST_H265_PARSER_OK;
2722 
2723 error:
2724   GST_WARNING ("error parsing \"Slice header\"");
2725 
2726   gst_h265_slice_hdr_free (slice);
2727 
2728   return GST_H265_PARSER_ERROR;
2729 }
2730 
2731 static gboolean
nal_reader_has_more_data_in_payload(NalReader * nr,guint32 payload_start_pos_bit,guint32 payloadSize)2732 nal_reader_has_more_data_in_payload (NalReader * nr,
2733     guint32 payload_start_pos_bit, guint32 payloadSize)
2734 {
2735   if (nal_reader_is_byte_aligned (nr) &&
2736       (nal_reader_get_pos (nr) >= (payload_start_pos_bit + 8 * payloadSize)))
2737     return FALSE;
2738 
2739   return TRUE;
2740 }
2741 
2742 static GstH265ParserResult
gst_h265_parser_parse_sei_message(GstH265Parser * parser,guint8 nal_type,NalReader * nr,GstH265SEIMessage * sei)2743 gst_h265_parser_parse_sei_message (GstH265Parser * parser,
2744     guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
2745 {
2746   guint32 payloadSize;
2747   guint8 payload_type_byte, payload_size_byte;
2748   guint remaining, payload_size;
2749   guint32 payload_start_pos_bit;
2750   GstH265ParserResult res = GST_H265_PARSER_OK;
2751 
2752   GST_DEBUG ("parsing \"Sei message\"");
2753 
2754   memset (sei, 0, sizeof (*sei));
2755 
2756   do {
2757     READ_UINT8 (nr, payload_type_byte, 8);
2758     sei->payloadType += payload_type_byte;
2759   } while (payload_type_byte == 0xff);
2760   payloadSize = 0;
2761   do {
2762     READ_UINT8 (nr, payload_size_byte, 8);
2763     payloadSize += payload_size_byte;
2764   }
2765   while (payload_size_byte == 0xff);
2766 
2767   remaining = nal_reader_get_remaining (nr);
2768   payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
2769 
2770   payload_start_pos_bit = nal_reader_get_pos (nr);
2771   GST_DEBUG
2772       ("SEI message received: payloadType  %u, payloadSize = %u bits",
2773       sei->payloadType, payload_size);
2774 
2775   if (nal_type == GST_H265_NAL_PREFIX_SEI) {
2776     switch (sei->payloadType) {
2777       case GST_H265_SEI_BUF_PERIOD:
2778         /* size not set; might depend on emulation_prevention_three_byte */
2779         res = gst_h265_parser_parse_buffering_period (parser,
2780             &sei->payload.buffering_period, nr);
2781         break;
2782       case GST_H265_SEI_PIC_TIMING:
2783         /* size not set; might depend on emulation_prevention_three_byte */
2784         res = gst_h265_parser_parse_pic_timing (parser,
2785             &sei->payload.pic_timing, nr);
2786         break;
2787       case GST_H265_SEI_REGISTERED_USER_DATA:
2788         res = gst_h265_parser_parse_registered_user_data (parser,
2789             &sei->payload.registered_user_data, nr, payload_size >> 3);
2790         break;
2791       case GST_H265_SEI_RECOVERY_POINT:
2792         res = gst_h265_parser_parse_recovery_point (parser,
2793             &sei->payload.recovery_point, nr);
2794         break;
2795       case GST_H265_SEI_TIME_CODE:
2796         res = gst_h265_parser_parse_time_code (parser,
2797             &sei->payload.time_code, nr);
2798         break;
2799       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
2800         res = gst_h265_parser_parse_mastering_display_colour_volume (parser,
2801             &sei->payload.mastering_display_colour_volume, nr);
2802         break;
2803       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
2804         res = gst_h265_parser_parse_content_light_level_info (parser,
2805             &sei->payload.content_light_level, nr);
2806         break;
2807       default:
2808         /* Just consume payloadSize bytes, which does not account for
2809            emulation prevention bytes */
2810         if (!nal_reader_skip_long (nr, payload_size))
2811           goto error;
2812         res = GST_H265_PARSER_OK;
2813         break;
2814     }
2815   } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
2816     switch (sei->payloadType) {
2817       default:
2818         /* Just consume payloadSize bytes, which does not account for
2819            emulation prevention bytes */
2820         if (!nal_reader_skip_long (nr, payload_size))
2821           goto error;
2822         res = GST_H265_PARSER_OK;
2823         break;
2824     }
2825   }
2826 
2827   /* Not parsing the reserved_payload_extension, but it shouldn't be
2828    * an issue because of 1: There shall not be any reserved_payload_extension
2829    * present in bitstreams conforming to the specification.2. Even though
2830    * it is present, the size will be less than total PayloadSize since the
2831    * size of reserved_payload_extension is supposed to be
2832    * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
2833    * the current implementation will still skip all unnecessary bits correctly.
2834    * In theory, we can have a more optimized implementation by skipping the
2835    * data left in PayLoadSize without out individually checking for each bits,
2836    * since the totoal size will be always less than payloadSize*/
2837   while (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
2838           payloadSize)) {
2839     /* Skip the byte alignment bits */
2840     if (!nal_reader_skip (nr, 1))
2841       goto error;
2842     while (!nal_reader_is_byte_aligned (nr)) {
2843       if (!nal_reader_skip (nr, 1))
2844         goto error;
2845     }
2846   }
2847 
2848   return res;
2849 
2850 error:
2851   GST_WARNING ("error parsing \"Sei message\"");
2852   return GST_H265_PARSER_ERROR;
2853 }
2854 
2855 /**
2856  * gst_h265_slice_hdr_copy:
2857  * @dst_slice: The destination #GstH265SliceHdr to copy into
2858  * @src_slice: The source #GstH265SliceHdr to copy from
2859  *
2860  * Copies @src_slice into @dst_slice
2861  *
2862  * Returns: %TRUE if everything went fine, %FALSE otherwise
2863  */
2864 gboolean
gst_h265_slice_hdr_copy(GstH265SliceHdr * dst_slice,const GstH265SliceHdr * src_slice)2865 gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
2866     const GstH265SliceHdr * src_slice)
2867 {
2868   guint i;
2869 
2870   g_return_val_if_fail (dst_slice != NULL, FALSE);
2871   g_return_val_if_fail (src_slice != NULL, FALSE);
2872 
2873   gst_h265_slice_hdr_free (dst_slice);
2874 
2875   *dst_slice = *src_slice;
2876 
2877   if (dst_slice->num_entry_point_offsets > 0) {
2878     dst_slice->entry_point_offset_minus1 =
2879         g_new0 (guint32, dst_slice->num_entry_point_offsets);
2880     for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
2881       dst_slice->entry_point_offset_minus1[i] =
2882           src_slice->entry_point_offset_minus1[i];
2883   }
2884 
2885   return TRUE;
2886 }
2887 
2888 /**
2889  * gst_h265_slice_hdr_free:
2890  * slice_hdr: The #GstH265SliceHdr to free
2891  *
2892  * Frees @slice_hdr fields.
2893  */
2894 void
gst_h265_slice_hdr_free(GstH265SliceHdr * slice_hdr)2895 gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
2896 {
2897   g_return_if_fail (slice_hdr != NULL);
2898 
2899   if (slice_hdr->num_entry_point_offsets > 0)
2900     g_free (slice_hdr->entry_point_offset_minus1);
2901   slice_hdr->entry_point_offset_minus1 = 0;
2902 }
2903 
2904 /**
2905  * gst_h265_sei_copy:
2906  * @dst_sei: The destination #GstH265SEIMessage to copy into
2907  * @src_sei: The source #GstH265SEIMessage to copy from
2908  *
2909  * Copies @src_sei into @dst_sei
2910  *
2911  * Returns: %TRUE if everything went fine, %FALSE otherwise
2912  */
2913 gboolean
gst_h265_sei_copy(GstH265SEIMessage * dst_sei,const GstH265SEIMessage * src_sei)2914 gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
2915     const GstH265SEIMessage * src_sei)
2916 {
2917   guint i;
2918 
2919   g_return_val_if_fail (dst_sei != NULL, FALSE);
2920   g_return_val_if_fail (src_sei != NULL, FALSE);
2921 
2922   gst_h265_sei_free (dst_sei);
2923 
2924   *dst_sei = *src_sei;
2925 
2926   if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2927     GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
2928     const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;
2929 
2930     if (dst_pic_timing->num_decoding_units_minus1 > 0) {
2931       dst_pic_timing->num_nalus_in_du_minus1 =
2932           g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
2933       dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
2934           g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));
2935 
2936       for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
2937         dst_pic_timing->num_nalus_in_du_minus1[i] =
2938             src_pic_timing->num_nalus_in_du_minus1[i];
2939         dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
2940             src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
2941       }
2942     }
2943   } else if (dst_sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2944     GstH265RegisteredUserData *dst_rud = &dst_sei->payload.registered_user_data;
2945     const GstH265RegisteredUserData *src_rud =
2946         &src_sei->payload.registered_user_data;
2947 
2948     if (src_rud->size) {
2949       dst_rud->data = g_malloc (src_rud->size);
2950       memcpy ((guint8 *) dst_rud->data, src_rud->data, src_rud->size);
2951     }
2952   }
2953 
2954   return TRUE;
2955 }
2956 
2957 /**
2958  * gst_h265_sei_free:
2959  * sei: The #GstH265SEIMessage to free
2960  *
2961  * Frees @sei fields.
2962  */
2963 void
gst_h265_sei_free(GstH265SEIMessage * sei)2964 gst_h265_sei_free (GstH265SEIMessage * sei)
2965 {
2966   g_return_if_fail (sei != NULL);
2967 
2968   if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
2969     GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
2970     if (pic_timing->num_decoding_units_minus1 > 0) {
2971       g_free (pic_timing->num_nalus_in_du_minus1);
2972       g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
2973     }
2974     pic_timing->num_nalus_in_du_minus1 = 0;
2975     pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
2976   } else if (sei->payloadType == GST_H265_SEI_REGISTERED_USER_DATA) {
2977     GstH265RegisteredUserData *rud = &sei->payload.registered_user_data;
2978     g_free ((guint8 *) rud->data);
2979     rud->data = NULL;
2980   }
2981 }
2982 
2983 /**
2984  * gst_h265_parser_parse_sei:
2985  * @nalparser: a #GstH265Parser
2986  * @nalu: The `GST_H265_NAL_*_SEI` #GstH265NalUnit to parse
2987  * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
2988  *
2989  * Parses @data, create and fills the @messages array.
2990  *
2991  * Returns: a #GstH265ParserResult
2992  */
2993 GstH265ParserResult
gst_h265_parser_parse_sei(GstH265Parser * nalparser,GstH265NalUnit * nalu,GArray ** messages)2994 gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
2995     GArray ** messages)
2996 {
2997   NalReader nr;
2998   GstH265SEIMessage sei;
2999   GstH265ParserResult res;
3000 
3001   GST_DEBUG ("parsing SEI nal");
3002   nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
3003       nalu->size - nalu->header_bytes);
3004   *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
3005   g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
3006 
3007   do {
3008     res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
3009     if (res == GST_H265_PARSER_OK)
3010       g_array_append_val (*messages, sei);
3011     else
3012       break;
3013   } while (nal_reader_has_more_data (&nr));
3014 
3015   return res;
3016 }
3017 
3018 /**
3019  * gst_h265_parser_update_vps:
3020  * @parser: a #GstH265Parser
3021  * @vps: (transfer none): a #GstH265VPS.
3022  *
3023  * Replace internal Video Parameter Set struct corresponding to id of @vps
3024  * with @vps. @nalparser will mark @vps as last parsed vps.
3025  *
3026  * Returns: a #GstH265ParserResult
3027  *
3028  * Since: 1.18
3029  */
3030 GstH265ParserResult
gst_h265_parser_update_vps(GstH265Parser * parser,GstH265VPS * vps)3031 gst_h265_parser_update_vps (GstH265Parser * parser, GstH265VPS * vps)
3032 {
3033   g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3034   g_return_val_if_fail (vps != NULL, GST_H265_PARSER_ERROR);
3035   g_return_val_if_fail (vps->id < GST_H265_MAX_VPS_COUNT,
3036       GST_H265_PARSER_ERROR);
3037 
3038   if (!vps->valid) {
3039     GST_WARNING ("Cannot update with invalid VPS");
3040     return GST_H265_PARSER_ERROR;
3041   }
3042 
3043   GST_DEBUG ("Updating video parameter set with id: %d", vps->id);
3044 
3045   parser->vps[vps->id] = *vps;
3046   parser->last_vps = &parser->vps[vps->id];
3047 
3048   return GST_H265_PARSER_OK;
3049 }
3050 
3051 /**
3052  * gst_h265_parser_update_sps:
3053  * @parser: a #GstH265Parser
3054  * @sps: (transfer none): a #GstH265SPS.
3055  *
3056  * Replace internal Sequence Parameter Set struct corresponding to id of @sps
3057  * with @sps. @nalparser will mark @sps as last parsed sps.
3058  *
3059  * Returns: a #GstH265ParserResult
3060  *
3061  * Since: 1.18
3062  */
3063 GstH265ParserResult
gst_h265_parser_update_sps(GstH265Parser * parser,GstH265SPS * sps)3064 gst_h265_parser_update_sps (GstH265Parser * parser, GstH265SPS * sps)
3065 {
3066   g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3067   g_return_val_if_fail (sps != NULL, GST_H265_PARSER_ERROR);
3068   g_return_val_if_fail (sps->id < GST_H265_MAX_SPS_COUNT,
3069       GST_H265_PARSER_ERROR);
3070 
3071   if (!sps->valid) {
3072     GST_WARNING ("Cannot update with invalid SPS");
3073     return GST_H265_PARSER_ERROR;
3074   }
3075 
3076   if (sps->vps) {
3077     GstH265VPS *vps = gst_h265_parser_get_vps (parser, sps->vps->id);
3078     if (!vps || vps != sps->vps) {
3079       GST_WARNING ("Linked VPS is not identical to internal VPS");
3080       return GST_H265_PARSER_BROKEN_LINK;
3081     }
3082   }
3083 
3084   GST_DEBUG ("Updating sequence parameter set with id: %d", sps->id);
3085 
3086   parser->sps[sps->id] = *sps;
3087   parser->last_sps = &parser->sps[sps->id];
3088 
3089   return GST_H265_PARSER_OK;
3090 }
3091 
3092 /**
3093  * gst_h265_parser_update_pps:
3094  * @parser: a #GstH265Parser
3095  * @pps: (transfer none): a #GstH265PPS.
3096  *
3097  * Replace internal Sequence Parameter Set struct corresponding to id of @pps
3098  * with @pps. @nalparser will mark @pps as last parsed sps.
3099  *
3100  * Returns: a #GstH265ParserResult
3101  *
3102  * Since: 1.18
3103  */
3104 GstH265ParserResult
gst_h265_parser_update_pps(GstH265Parser * parser,GstH265PPS * pps)3105 gst_h265_parser_update_pps (GstH265Parser * parser, GstH265PPS * pps)
3106 {
3107   GstH265SPS *sps;
3108 
3109   g_return_val_if_fail (parser != NULL, GST_H265_PARSER_ERROR);
3110   g_return_val_if_fail (pps != NULL, GST_H265_PARSER_ERROR);
3111   g_return_val_if_fail (pps->id < GST_H265_MAX_PPS_COUNT,
3112       GST_H265_PARSER_ERROR);
3113 
3114   if (!pps->valid) {
3115     GST_WARNING ("Cannot update with invalid PPS");
3116     return GST_H265_PARSER_ERROR;
3117   }
3118 
3119   if (!pps->sps) {
3120     GST_WARNING ("No linked SPS struct");
3121     return GST_H265_PARSER_BROKEN_LINK;
3122   }
3123 
3124   sps = gst_h265_parser_get_sps (parser, pps->sps->id);
3125   if (!sps || sps != pps->sps) {
3126     GST_WARNING ("Linked SPS is not identical to internal SPS");
3127     return GST_H265_PARSER_BROKEN_LINK;
3128   }
3129 
3130   GST_DEBUG ("Updating picture parameter set with id: %d", pps->id);
3131 
3132   parser->pps[pps->id] = *pps;
3133   parser->last_pps = &parser->pps[pps->id];
3134 
3135   return GST_H265_PARSER_OK;
3136 }
3137 
3138 /**
3139  * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
3140  * @out_quant: (out): The resulting quantization matrix
3141  * @quant: The source quantization matrix
3142  *
3143  * Converts quantization matrix @quant from raster scan order to
3144  * zigzag scan order and store the resulting factors into @out_quant.
3145  *
3146  * Note: it is an error to pass the same table in both @quant and
3147  * @out_quant arguments.
3148  *
3149  * Since: 1.6
3150  */
3151 void
gst_h265_quant_matrix_4x4_get_zigzag_from_raster(guint8 out_quant[16],const guint8 quant[16])3152 gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
3153     const guint8 quant[16])
3154 {
3155   guint i;
3156 
3157   g_return_if_fail (out_quant != quant);
3158 
3159   for (i = 0; i < 16; i++)
3160     out_quant[i] = quant[zigzag_4x4[i]];
3161 }
3162 
3163 /**
3164  * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
3165  * @out_quant: (out): The resulting quantization matrix
3166  * @quant: The source quantization matrix
3167  *
3168  * Converts quantization matrix @quant from zigzag scan order to
3169  * raster scan order and store the resulting factors into @out_quant.
3170  *
3171  * Note: it is an error to pass the same table in both @quant and
3172  * @out_quant arguments.
3173  *
3174  * Since: 1.6
3175  */
3176 void
gst_h265_quant_matrix_4x4_get_raster_from_zigzag(guint8 out_quant[16],const guint8 quant[16])3177 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
3178     const guint8 quant[16])
3179 {
3180   guint i;
3181 
3182   g_return_if_fail (out_quant != quant);
3183 
3184   for (i = 0; i < 16; i++)
3185     out_quant[zigzag_4x4[i]] = quant[i];
3186 }
3187 
3188 /**
3189  * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
3190  * @out_quant: (out): The resulting quantization matrix
3191  * @quant: The source quantization matrix
3192  *
3193  * Converts quantization matrix @quant from raster scan order to
3194  * zigzag scan order and store the resulting factors into @out_quant.
3195  *
3196  * Note: it is an error to pass the same table in both @quant and
3197  * @out_quant arguments.
3198  *
3199  * Since: 1.6
3200  */
3201 void
gst_h265_quant_matrix_8x8_get_zigzag_from_raster(guint8 out_quant[64],const guint8 quant[64])3202 gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
3203     const guint8 quant[64])
3204 {
3205   guint i;
3206 
3207   g_return_if_fail (out_quant != quant);
3208 
3209   for (i = 0; i < 64; i++)
3210     out_quant[i] = quant[zigzag_8x8[i]];
3211 }
3212 
3213 /**
3214  * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
3215  * @out_quant: (out): The resulting quantization matrix
3216  * @quant: The source quantization matrix
3217  *
3218  * Converts quantization matrix @quant from zigzag scan order to
3219  * raster scan order and store the resulting factors into @out_quant.
3220  *
3221  * Note: it is an error to pass the same table in both @quant and
3222  * @out_quant arguments.
3223  *
3224  * Since: 1.6
3225  */
3226 void
gst_h265_quant_matrix_8x8_get_raster_from_zigzag(guint8 out_quant[64],const guint8 quant[64])3227 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
3228     const guint8 quant[64])
3229 {
3230   guint i;
3231 
3232   g_return_if_fail (out_quant != quant);
3233 
3234   for (i = 0; i < 64; i++)
3235     out_quant[zigzag_8x8[i]] = quant[i];
3236 }
3237 
3238 /**
3239  * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
3240  * @out_quant: (out): The resulting quantization matrix
3241  * @quant: The source quantization matrix
3242  *
3243  * Converts quantization matrix @quant from raster scan order to
3244  * uprightdiagonal scan order and store the resulting factors
3245  * into @out_quant.
3246  *
3247  * Note: it is an error to pass the same table in both @quant and
3248  * @out_quant arguments.
3249  *
3250  * Since: 1.6
3251  */
3252 void
gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster(guint8 out_quant[16],const guint8 quant[16])3253 gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
3254     const guint8 quant[16])
3255 {
3256   guint i;
3257 
3258   g_return_if_fail (out_quant != quant);
3259 
3260   for (i = 0; i < 16; i++)
3261     out_quant[i] = quant[uprightdiagonal_4x4[i]];
3262 }
3263 
3264 /**
3265  * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
3266  * @out_quant: (out): The resulting quantization matrix
3267  * @quant: The source quantization matrix
3268  *
3269  * Converts quantization matrix @quant from uprightdiagonal scan order to
3270  * raster scan order and store the resulting factors into @out_quant.
3271  *
3272  * Note: it is an error to pass the same table in both @quant and
3273  * @out_quant arguments.
3274  *
3275  * Since: 1.6
3276  */
3277 void
gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal(guint8 out_quant[16],const guint8 quant[16])3278 gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
3279     const guint8 quant[16])
3280 {
3281   guint i;
3282 
3283   g_return_if_fail (out_quant != quant);
3284 
3285   for (i = 0; i < 16; i++)
3286     out_quant[uprightdiagonal_4x4[i]] = quant[i];
3287 }
3288 
3289 /**
3290  * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
3291  * @out_quant: (out): The resulting quantization matrix
3292  * @quant: The source quantization matrix
3293  *
3294  * Converts quantization matrix @quant from raster scan order to
3295  * uprightdiagonal scan order and store the resulting factors
3296  * into @out_quant.
3297  *
3298  * Note: it is an error to pass the same table in both @quant and
3299  * @out_quant arguments.
3300  *
3301  * Since: 1.6
3302  */
3303 void
gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster(guint8 out_quant[64],const guint8 quant[64])3304 gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
3305     const guint8 quant[64])
3306 {
3307   guint i;
3308 
3309   g_return_if_fail (out_quant != quant);
3310 
3311   for (i = 0; i < 64; i++)
3312     out_quant[i] = quant[uprightdiagonal_8x8[i]];
3313 }
3314 
3315 /**
3316  * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
3317  * @out_quant: (out): The resulting quantization matrix
3318  * @quant: The source quantization matrix
3319  *
3320  * Converts quantization matrix @quant from uprightdiagonal scan order to
3321  * raster scan order and store the resulting factors into @out_quant.
3322  *
3323  * Note: it is an error to pass the same table in both @quant and
3324  * @out_quant arguments.
3325  *
3326  * Since: 1.6
3327  */
3328 void
gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal(guint8 out_quant[64],const guint8 quant[64])3329 gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
3330     const guint8 quant[64])
3331 {
3332   guint i;
3333 
3334   g_return_if_fail (out_quant != quant);
3335 
3336   for (i = 0; i < 64; i++)
3337     out_quant[uprightdiagonal_8x8[i]] = quant[i];
3338 }
3339 
3340 typedef struct
3341 {
3342   GstH265Profile profile;
3343 
3344   guint8 max_14bit_constraint_flag;
3345   guint8 max_12bit_constraint_flag;
3346   guint8 max_10bit_constraint_flag;
3347   guint8 max_8bit_constraint_flag;
3348   guint8 max_422chroma_constraint_flag;
3349   guint8 max_420chroma_constraint_flag;
3350   guint8 max_monochrome_constraint_flag;
3351   guint8 intra_constraint_flag;
3352   guint8 one_picture_only_constraint_flag;
3353   gboolean lower_bit_rate_constraint_flag_set;
3354 
3355   /* Tie breaker if more than one profiles are matching */
3356   guint priority;
3357 } H265ExtensionProfile;
3358 
3359 typedef struct
3360 {
3361   H265ExtensionProfile *profile;
3362   guint extra_constraints;
3363 } H265ExtensionProfileMatch;
3364 
3365 static gint
sort_fre_profile_matches(H265ExtensionProfileMatch * a,H265ExtensionProfileMatch * b)3366 sort_fre_profile_matches (H265ExtensionProfileMatch * a,
3367     H265ExtensionProfileMatch * b)
3368 {
3369   gint d;
3370 
3371   d = a->extra_constraints - b->extra_constraints;
3372   if (d)
3373     return d;
3374 
3375   return b->profile->priority - a->profile->priority;
3376 }
3377 
3378 static GstH265Profile
get_extension_profile(H265ExtensionProfile * profiles,guint num,const GstH265ProfileTierLevel * ptl)3379 get_extension_profile (H265ExtensionProfile * profiles, guint num,
3380     const GstH265ProfileTierLevel * ptl)
3381 {
3382   GstH265Profile result = GST_H265_PROFILE_INVALID;
3383   guint i;
3384   GList *matches = NULL;
3385 
3386   for (i = 0; i < num; i++) {
3387     H265ExtensionProfile p = profiles[i];
3388     guint extra_constraints = 0;
3389     H265ExtensionProfileMatch *m;
3390 
3391     /* Filter out all the profiles having constraints not satisfied by @ptl.
3392      * Then pick the one having the least extra constraints. This allow us
3393      * to match the closest profile if bitstream contains not standard
3394      * constraints. */
3395     if (p.max_14bit_constraint_flag != ptl->max_14bit_constraint_flag) {
3396       if (p.max_14bit_constraint_flag)
3397         continue;
3398       extra_constraints++;
3399     }
3400 
3401     if (p.max_12bit_constraint_flag != ptl->max_12bit_constraint_flag) {
3402       if (p.max_12bit_constraint_flag)
3403         continue;
3404       extra_constraints++;
3405     }
3406 
3407     if (p.max_10bit_constraint_flag != ptl->max_10bit_constraint_flag) {
3408       if (p.max_10bit_constraint_flag)
3409         continue;
3410       extra_constraints++;
3411     }
3412 
3413     if (p.max_8bit_constraint_flag != ptl->max_8bit_constraint_flag) {
3414       if (p.max_8bit_constraint_flag)
3415         continue;
3416       extra_constraints++;
3417     }
3418 
3419     if (p.max_422chroma_constraint_flag != ptl->max_422chroma_constraint_flag) {
3420       if (p.max_422chroma_constraint_flag)
3421         continue;
3422       extra_constraints++;
3423     }
3424 
3425     if (p.max_420chroma_constraint_flag != ptl->max_420chroma_constraint_flag) {
3426       if (p.max_420chroma_constraint_flag)
3427         continue;
3428       extra_constraints++;
3429     }
3430 
3431     if (p.max_monochrome_constraint_flag != ptl->max_monochrome_constraint_flag) {
3432       if (p.max_monochrome_constraint_flag)
3433         continue;
3434       extra_constraints++;
3435     }
3436 
3437     if (p.intra_constraint_flag != ptl->intra_constraint_flag) {
3438       if (p.intra_constraint_flag)
3439         continue;
3440       extra_constraints++;
3441     }
3442 
3443     if (p.one_picture_only_constraint_flag !=
3444         ptl->one_picture_only_constraint_flag) {
3445       if (p.one_picture_only_constraint_flag)
3446         continue;
3447       extra_constraints++;
3448     }
3449 
3450     if (p.lower_bit_rate_constraint_flag_set
3451         && !ptl->lower_bit_rate_constraint_flag)
3452       continue;
3453 
3454     if (extra_constraints == 0) {
3455       result = p.profile;
3456       break;
3457     }
3458 
3459     m = g_new0 (H265ExtensionProfileMatch, 1);
3460     m->profile = &profiles[i];
3461     m->extra_constraints = extra_constraints;
3462     matches = g_list_prepend (matches, m);
3463   }
3464 
3465   if (result == GST_H265_PROFILE_INVALID && matches) {
3466     H265ExtensionProfileMatch *m;
3467 
3468     matches = g_list_sort (matches, (GCompareFunc) sort_fre_profile_matches);
3469     m = matches->data;
3470     result = m->profile->profile;
3471     GST_INFO ("Fail to find the profile matches all extensions bits,"
3472         " select the closest %s with %d bit diff",
3473         gst_h265_profile_to_string (result), m->extra_constraints);
3474   }
3475 
3476   if (matches)
3477     g_list_free_full (matches, g_free);
3478 
3479   return result;
3480 }
3481 
3482 static GstH265Profile
get_format_range_extension_profile(const GstH265ProfileTierLevel * ptl)3483 get_format_range_extension_profile (const GstH265ProfileTierLevel * ptl)
3484 {
3485   /* Profile idc: GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION
3486      See Table A.2 for the definition of those formats */
3487   static H265ExtensionProfile profiles[] = {
3488     {GST_H265_PROFILE_MONOCHROME,
3489         0, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3490     {GST_H265_PROFILE_MONOCHROME_10,
3491         0, 1, 1, 0, 1, 1, 1, 0, 0, TRUE, 1},
3492     {GST_H265_PROFILE_MONOCHROME_12,
3493         0, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3494     {GST_H265_PROFILE_MONOCHROME_16,
3495         0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 3},
3496     {GST_H265_PROFILE_MAIN_12,
3497         0, 1, 0, 0, 1, 1, 0, 0, 0, TRUE, 4},
3498     {GST_H265_PROFILE_MAIN_422_10,
3499         0, 1, 1, 0, 1, 0, 0, 0, 0, TRUE, 5},
3500     {GST_H265_PROFILE_MAIN_422_12,
3501         0, 1, 0, 0, 1, 0, 0, 0, 0, TRUE, 6},
3502     {GST_H265_PROFILE_MAIN_444,
3503         0, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 7},
3504     {GST_H265_PROFILE_MAIN_444_10,
3505         0, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 8},
3506     {GST_H265_PROFILE_MAIN_444_12,
3507         0, 1, 0, 0, 0, 0, 0, 0, 0, TRUE, 9},
3508     {GST_H265_PROFILE_MAIN_INTRA,
3509         0, 1, 1, 1, 1, 1, 0, 1, 0, FALSE, 10},
3510     {GST_H265_PROFILE_MAIN_10_INTRA,
3511         0, 1, 1, 0, 1, 1, 0, 1, 0, FALSE, 11},
3512     {GST_H265_PROFILE_MAIN_12_INTRA,
3513         0, 1, 0, 0, 1, 1, 0, 1, 0, FALSE, 12},
3514     {GST_H265_PROFILE_MAIN_422_10_INTRA,
3515         0, 1, 1, 0, 1, 0, 0, 1, 0, FALSE, 13},
3516     {GST_H265_PROFILE_MAIN_422_12_INTRA,
3517         0, 1, 0, 0, 1, 0, 0, 1, 0, FALSE, 14},
3518     {GST_H265_PROFILE_MAIN_444_INTRA,
3519         0, 1, 1, 1, 0, 0, 0, 1, 0, FALSE, 15},
3520     {GST_H265_PROFILE_MAIN_444_10_INTRA,
3521         0, 1, 1, 0, 0, 0, 0, 1, 0, FALSE, 16},
3522     {GST_H265_PROFILE_MAIN_444_12_INTRA,
3523         0, 1, 0, 0, 0, 0, 0, 1, 0, FALSE, 17},
3524     {GST_H265_PROFILE_MAIN_444_16_INTRA,
3525         0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 18},
3526     {GST_H265_PROFILE_MAIN_444_STILL_PICTURE,
3527         0, 1, 1, 1, 0, 0, 0, 1, 1, FALSE, 19},
3528     {GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE,
3529         0, 0, 0, 0, 0, 0, 0, 1, 1, FALSE, 20},
3530   };
3531 
3532   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3533 }
3534 
3535 static GstH265Profile
get_3d_profile(const GstH265ProfileTierLevel * ptl)3536 get_3d_profile (const GstH265ProfileTierLevel * ptl)
3537 {
3538   /* profile idc: GST_H265_PROFILE_IDC_3D_MAIN */
3539   static H265ExtensionProfile profiles[] = {
3540     {GST_H265_PROFILE_3D_MAIN,
3541         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3542   };
3543 
3544   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3545 }
3546 
3547 static GstH265Profile
get_multiview_profile(const GstH265ProfileTierLevel * ptl)3548 get_multiview_profile (const GstH265ProfileTierLevel * ptl)
3549 {
3550   static H265ExtensionProfile profiles[] = {
3551     {GST_H265_PROFILE_MULTIVIEW_MAIN,
3552         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3553   };
3554 
3555   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3556 }
3557 
3558 static GstH265Profile
get_scalable_profile(const GstH265ProfileTierLevel * ptl)3559 get_scalable_profile (const GstH265ProfileTierLevel * ptl)
3560 {
3561   static H265ExtensionProfile profiles[] = {
3562     {GST_H265_PROFILE_SCALABLE_MAIN,
3563         0, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3564     {GST_H265_PROFILE_SCALABLE_MAIN_10,
3565         0, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3566   };
3567 
3568   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3569 }
3570 
3571 static GstH265Profile
get_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3572 get_high_throughput_profile (const GstH265ProfileTierLevel * ptl)
3573 {
3574   static H265ExtensionProfile profiles[] = {
3575     {GST_H265_PROFILE_HIGH_THROUGHPUT_444,
3576         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3577     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_10,
3578         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3579     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_14,
3580         1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3581     {GST_H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA,
3582         0, 0, 0, 0, 0, 0, 0, 1, 0, FALSE, 3},
3583   };
3584 
3585   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3586 }
3587 
3588 static GstH265Profile
get_screen_content_coding_extensions_profile(const GstH265ProfileTierLevel * ptl)3589 get_screen_content_coding_extensions_profile (const GstH265ProfileTierLevel *
3590     ptl)
3591 {
3592   static H265ExtensionProfile profiles[] = {
3593     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN,
3594         1, 1, 1, 1, 1, 1, 0, 0, 0, TRUE, 0},
3595     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10,
3596         1, 1, 1, 0, 1, 1, 0, 0, 0, TRUE, 1},
3597     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
3598         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 2},
3599     {GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10,
3600         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 3},
3601   };
3602 
3603   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3604 }
3605 
3606 static GstH265Profile
get_scalable_format_range_extensions_profile(const GstH265ProfileTierLevel * ptl)3607 get_scalable_format_range_extensions_profile (const GstH265ProfileTierLevel *
3608     ptl)
3609 {
3610   static H265ExtensionProfile profiles[] = {
3611     {GST_H265_PROFILE_SCALABLE_MONOCHROME,
3612         1, 1, 1, 1, 1, 1, 1, 0, 0, TRUE, 0},
3613     {GST_H265_PROFILE_SCALABLE_MONOCHROME_12,
3614         1, 1, 0, 0, 1, 1, 1, 0, 0, TRUE, 1},
3615     {GST_H265_PROFILE_SCALABLE_MONOCHROME_16,
3616         0, 0, 0, 0, 1, 1, 1, 0, 0, TRUE, 2},
3617     {GST_H265_PROFILE_SCALABLE_MAIN_444,
3618         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 3},
3619   };
3620 
3621   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3622 }
3623 
3624 static GstH265Profile
get_screen_content_coding_extensions_high_throughput_profile(const GstH265ProfileTierLevel * ptl)3625     get_screen_content_coding_extensions_high_throughput_profile
3626     (const GstH265ProfileTierLevel * ptl)
3627 {
3628   static H265ExtensionProfile profiles[] = {
3629     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444,
3630         1, 1, 1, 1, 0, 0, 0, 0, 0, TRUE, 0},
3631     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10,
3632         1, 1, 1, 0, 0, 0, 0, 0, 0, TRUE, 1},
3633     {GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14,
3634         1, 0, 0, 0, 0, 0, 0, 0, 0, TRUE, 2},
3635   };
3636 
3637   return get_extension_profile (profiles, G_N_ELEMENTS (profiles), ptl);
3638 }
3639 
3640 static inline void
append_profile(GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * idx,GstH265Profile profile)3641 append_profile (GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * idx,
3642     GstH265Profile profile)
3643 {
3644   if (profile == GST_H265_PROFILE_INVALID)
3645     return;
3646   profiles[*idx] = profile;
3647   (*idx)++;
3648 }
3649 
3650 /* *INDENT-OFF* */
3651 struct h265_profiles_map
3652 {
3653   GstH265ProfileIDC profile_idc;
3654   GstH265Profile (*get_profile) (const GstH265ProfileTierLevel *);
3655   GstH265Profile profile;
3656 };
3657 /* *INDENT-ON* */
3658 
3659 static const struct h265_profiles_map profiles_map[] = {
3660   /* keep profile check in asc order */
3661   {GST_H265_PROFILE_IDC_MAIN, NULL, GST_H265_PROFILE_MAIN},
3662   {GST_H265_PROFILE_IDC_MAIN_10, NULL, GST_H265_PROFILE_MAIN_10},
3663   {GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE, NULL,
3664       GST_H265_PROFILE_MAIN_STILL_PICTURE},
3665   {GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION,
3666       get_format_range_extension_profile, GST_H265_PROFILE_INVALID},
3667   {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT, get_high_throughput_profile,
3668       GST_H265_PROFILE_INVALID},
3669   {GST_H265_PROFILE_IDC_MULTIVIEW_MAIN, get_multiview_profile,
3670       GST_H265_PROFILE_INVALID},
3671   {GST_H265_PROFILE_IDC_SCALABLE_MAIN, get_scalable_profile,
3672       GST_H265_PROFILE_INVALID},
3673   {GST_H265_PROFILE_IDC_3D_MAIN, get_3d_profile, GST_H265_PROFILE_INVALID},
3674   {GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING,
3675         get_screen_content_coding_extensions_profile,
3676       GST_H265_PROFILE_INVALID},
3677   {GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION,
3678         get_scalable_format_range_extensions_profile,
3679       GST_H265_PROFILE_INVALID},
3680   {GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION,
3681         get_screen_content_coding_extensions_high_throughput_profile,
3682       GST_H265_PROFILE_INVALID},
3683 };
3684 
3685 static void
gst_h265_profile_tier_level_get_profiles(const GstH265ProfileTierLevel * ptl,GstH265Profile profiles[GST_H265_PROFILE_MAX],guint * len)3686 gst_h265_profile_tier_level_get_profiles (const GstH265ProfileTierLevel * ptl,
3687     GstH265Profile profiles[GST_H265_PROFILE_MAX], guint * len)
3688 {
3689   guint i = 0, j;
3690 
3691   /* First add profile idc */
3692   for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3693     if (ptl->profile_idc == profiles_map[j].profile_idc) {
3694       if (profiles_map[j].get_profile)
3695         append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3696       else
3697         profiles[i++] = profiles_map[j].profile;
3698       break;
3699     }
3700   }
3701 
3702   /* Later add compatibility flags */
3703   for (j = 0; j < G_N_ELEMENTS (profiles_map); j++) {
3704     if (i > 0 && ptl->profile_idc == profiles_map[j].profile_idc)
3705       continue;
3706     if (ptl->profile_compatibility_flag[profiles_map[j].profile_idc]) {
3707       if (profiles_map[j].get_profile)
3708         append_profile (profiles, &i, profiles_map[j].get_profile (ptl));
3709       else
3710         profiles[i++] = profiles_map[j].profile;
3711     }
3712   }
3713 
3714   *len = i;
3715 }
3716 
3717 /**
3718  * gst_h265_profile_tier_level_get_profile:
3719  * @ptl: a #GstH265ProfileTierLevel
3720  *
3721  * Return the H265 profile defined in @ptl.
3722  *
3723  * Returns: a #GstH265Profile
3724  * Since: 1.14
3725  */
3726 GstH265Profile
gst_h265_profile_tier_level_get_profile(const GstH265ProfileTierLevel * ptl)3727 gst_h265_profile_tier_level_get_profile (const GstH265ProfileTierLevel * ptl)
3728 {
3729   guint len = 0;
3730   GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
3731 
3732   gst_h265_profile_tier_level_get_profiles (ptl, profiles, &len);
3733 
3734   if (len > 0)
3735     return profiles[0];
3736 
3737   return GST_H265_PROFILE_INVALID;
3738 }
3739 
3740 /**
3741  * gst_h265_profile_to_string:
3742  * @profile: a #GstH265Profile
3743  *
3744  * Returns the descriptive name for the #GstH265Profile.
3745  *
3746  * Returns: (nullable): the name for @profile or %NULL on error
3747  *
3748  * Since: 1.18
3749  */
3750 const gchar *
gst_h265_profile_to_string(GstH265Profile profile)3751 gst_h265_profile_to_string (GstH265Profile profile)
3752 {
3753   guint i;
3754 
3755   if (profile == GST_H265_PROFILE_INVALID || profile == GST_H265_PROFILE_MAX)
3756     return NULL;
3757 
3758   for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3759     if (profile == h265_profiles[i].profile)
3760       return h265_profiles[i].name;
3761   }
3762 
3763   return NULL;
3764 }
3765 
3766 /**
3767  * gst_h265_profile_from_string:
3768  * @string: the descriptive name for #GstH265Profile
3769  *
3770  * Returns a #GstH265Profile for the @string.
3771  *
3772  * Returns: the #GstH265Profile of @string or %GST_H265_PROFILE_INVALID on error
3773  *
3774  * Since: 1.18
3775  */
3776 GstH265Profile
gst_h265_profile_from_string(const gchar * string)3777 gst_h265_profile_from_string (const gchar * string)
3778 {
3779   guint i;
3780 
3781   if (string == NULL)
3782     return GST_H265_PROFILE_INVALID;
3783 
3784   for (i = 0; i < G_N_ELEMENTS (h265_profiles); i++) {
3785     if (g_strcmp0 (string, h265_profiles[i].name) == 0) {
3786       return h265_profiles[i].profile;
3787     }
3788   }
3789 
3790   return GST_H265_PROFILE_INVALID;
3791 }
3792 
3793 static gboolean
gst_h265_write_sei_registered_user_data(NalWriter * nw,GstH265RegisteredUserData * rud)3794 gst_h265_write_sei_registered_user_data (NalWriter * nw,
3795     GstH265RegisteredUserData * rud)
3796 {
3797   WRITE_UINT8 (nw, rud->country_code, 8);
3798   if (rud->country_code == 0xff)
3799     WRITE_UINT8 (nw, rud->country_code_extension, 8);
3800 
3801   WRITE_BYTES (nw, rud->data, rud->size);
3802 
3803   return TRUE;
3804 
3805 error:
3806   return FALSE;
3807 }
3808 
3809 static gboolean
gst_h265_write_sei_time_code(NalWriter * nw,GstH265TimeCode * tc)3810 gst_h265_write_sei_time_code (NalWriter * nw, GstH265TimeCode * tc)
3811 {
3812   gint i;
3813 
3814   WRITE_UINT8 (nw, tc->num_clock_ts, 2);
3815 
3816   for (i = 0; i < tc->num_clock_ts; i++) {
3817     WRITE_UINT8 (nw, tc->clock_timestamp_flag[i], 1);
3818     if (tc->clock_timestamp_flag[i]) {
3819       WRITE_UINT8 (nw, tc->units_field_based_flag[i], 1);
3820       WRITE_UINT8 (nw, tc->counting_type[i], 5);
3821       WRITE_UINT8 (nw, tc->full_timestamp_flag[i], 1);
3822       WRITE_UINT8 (nw, tc->discontinuity_flag[i], 1);
3823       WRITE_UINT8 (nw, tc->cnt_dropped_flag[i], 1);
3824       WRITE_UINT16 (nw, tc->n_frames[i], 9);
3825 
3826       if (tc->full_timestamp_flag[i]) {
3827         WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3828         WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3829         WRITE_UINT8 (nw, tc->hours_value[i], 5);
3830       } else {
3831         WRITE_UINT8 (nw, tc->seconds_flag[i], 1);
3832         if (tc->seconds_flag[i]) {
3833           WRITE_UINT8 (nw, tc->seconds_value[i], 6);
3834           WRITE_UINT8 (nw, tc->minutes_flag[i], 1);
3835           if (tc->minutes_flag[i]) {
3836             WRITE_UINT8 (nw, tc->minutes_value[i], 6);
3837             WRITE_UINT8 (nw, tc->hours_flag[i], 1);
3838             if (tc->hours_flag[i]) {
3839               WRITE_UINT8 (nw, tc->hours_value[i], 5);
3840             }
3841           }
3842         }
3843       }
3844     }
3845 
3846     WRITE_UINT8 (nw, tc->time_offset_length[i], 5);
3847 
3848     if (tc->time_offset_length[i] > 0)
3849       WRITE_UINT8 (nw, tc->time_offset_value[i], tc->time_offset_length[i]);
3850   }
3851 
3852   return TRUE;
3853 
3854 error:
3855   return FALSE;
3856 }
3857 
3858 static gboolean
gst_h265_write_sei_mastering_display_colour_volume(NalWriter * nw,GstH265MasteringDisplayColourVolume * mdcv)3859 gst_h265_write_sei_mastering_display_colour_volume (NalWriter * nw,
3860     GstH265MasteringDisplayColourVolume * mdcv)
3861 {
3862   gint i;
3863 
3864   for (i = 0; i < 3; i++) {
3865     WRITE_UINT16 (nw, mdcv->display_primaries_x[i], 16);
3866     WRITE_UINT16 (nw, mdcv->display_primaries_y[i], 16);
3867   }
3868 
3869   WRITE_UINT16 (nw, mdcv->white_point_x, 16);
3870   WRITE_UINT16 (nw, mdcv->white_point_y, 16);
3871   WRITE_UINT32 (nw, mdcv->max_display_mastering_luminance, 32);
3872   WRITE_UINT32 (nw, mdcv->min_display_mastering_luminance, 32);
3873 
3874   return TRUE;
3875 
3876 error:
3877   return FALSE;
3878 }
3879 
3880 static gboolean
gst_h265_write_sei_content_light_level_info(NalWriter * nw,GstH265ContentLightLevel * cll)3881 gst_h265_write_sei_content_light_level_info (NalWriter * nw,
3882     GstH265ContentLightLevel * cll)
3883 {
3884   WRITE_UINT16 (nw, cll->max_content_light_level, 16);
3885   WRITE_UINT16 (nw, cll->max_pic_average_light_level, 16);
3886 
3887   return TRUE;
3888 
3889 error:
3890   return FALSE;
3891 }
3892 
3893 static GstMemory *
gst_h265_create_sei_memory_internal(guint8 layer_id,guint8 temporal_id_plus1,guint nal_prefix_size,gboolean packetized,GArray * messages)3894 gst_h265_create_sei_memory_internal (guint8 layer_id, guint8 temporal_id_plus1,
3895     guint nal_prefix_size, gboolean packetized, GArray * messages)
3896 {
3897   NalWriter nw;
3898   gint i;
3899   gboolean have_written_data = FALSE;
3900 
3901   nal_writer_init (&nw, nal_prefix_size, packetized);
3902 
3903   if (messages->len == 0)
3904     goto error;
3905 
3906   GST_DEBUG ("Create SEI nal from array, len: %d", messages->len);
3907 
3908   /* nal header */
3909   /* forbidden_zero_bit */
3910   WRITE_UINT8 (&nw, 0, 1);
3911   /* nal_unit_type */
3912   WRITE_UINT8 (&nw, GST_H265_NAL_PREFIX_SEI, 6);
3913   /* nuh_layer_id */
3914   WRITE_UINT8 (&nw, layer_id, 6);
3915   /* nuh_temporal_id_plus1 */
3916   WRITE_UINT8 (&nw, temporal_id_plus1, 3);
3917 
3918   for (i = 0; i < messages->len; i++) {
3919     GstH265SEIMessage *msg = &g_array_index (messages, GstH265SEIMessage, i);
3920     guint32 payload_size_data = 0;
3921     guint32 payload_size_in_bits = 0;
3922     guint32 payload_type_data = msg->payloadType;
3923     gboolean need_align = FALSE;
3924 
3925     switch (payload_type_data) {
3926       case GST_H265_SEI_REGISTERED_USER_DATA:{
3927         GstH265RegisteredUserData *rud = &msg->payload.registered_user_data;
3928 
3929         /* itu_t_t35_country_code: 8 bits */
3930         payload_size_data = 1;
3931         if (rud->country_code == 0xff) {
3932           /* itu_t_t35_country_code_extension_byte */
3933           payload_size_data++;
3934         }
3935 
3936         payload_size_data += rud->size;
3937         break;
3938       }
3939       case GST_H265_SEI_TIME_CODE:{
3940         gint j;
3941         GstH265TimeCode *tc = &msg->payload.time_code;
3942         /* num_clock_ts: 2 bits */
3943         payload_size_in_bits = 2;
3944         for (j = 0; j < tc->num_clock_ts; j++) {
3945           /* clock_timestamp_flag: 1 bit */
3946           payload_size_in_bits += 1;
3947 
3948           if (tc->clock_timestamp_flag[j]) {
3949             /* units_field_based_flag: 1 bit
3950              * counting_type: 5 bits
3951              * full_timestamp_flag: 1 bit
3952              * discontinuity_flag: 1 bit
3953              * cnt_dropped_flag: 1 bit
3954              * n_frames: 9 bit
3955              */
3956             payload_size_in_bits += 18;
3957 
3958             if (tc->full_timestamp_flag[j]) {
3959               /* seconds_value: 6 bits
3960                * minutes_value: 6 bits
3961                * hours_value: 5 bits
3962                */
3963               payload_size_in_bits += 17;
3964             } else {
3965               /* seconds_flag: 1 bit */
3966               payload_size_in_bits += 1;
3967 
3968               if (tc->seconds_flag[j]) {
3969                 /* seconds_value: 6 bits
3970                  * minutes_flag: 1 bit
3971                  */
3972                 payload_size_in_bits += 7;
3973 
3974                 if (tc->minutes_flag[j]) {
3975                   /* minutes_value: 6 bits
3976                    * hours_flag: 1 bit
3977                    */
3978                   payload_size_in_bits += 7;
3979                   if (tc->hours_flag[j]) {
3980                     /* hours_value: 5 bits */
3981                     payload_size_in_bits += 5;
3982                   }
3983                 }
3984               }
3985             }
3986 
3987             /* time_offset_length: 5bits
3988              * time_offset_value: time_offset_length bits
3989              */
3990             payload_size_in_bits += (5 + tc->time_offset_length[j]);
3991           }
3992         }
3993 
3994         payload_size_data = payload_size_in_bits >> 3;
3995 
3996         if ((payload_size_in_bits & 0x7) != 0) {
3997           GST_INFO ("Bits for Time Code SEI is not byte aligned");
3998           payload_size_data++;
3999           need_align = TRUE;
4000         }
4001         break;
4002       }
4003       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4004         /* x, y 16 bits per RGB channel
4005          * x, y 16 bits white point
4006          * max, min luminance 32 bits
4007          *
4008          * (2 * 2 * 3) + (2 * 2) + (4 * 2) = 24 bytes
4009          */
4010         payload_size_data = 24;
4011         break;
4012       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4013         /* maxCLL and maxFALL per 16 bits
4014          *
4015          * 2 * 2 = 4 bytes
4016          */
4017         payload_size_data = 4;
4018         break;
4019       default:
4020         break;
4021     }
4022 
4023     if (payload_size_data == 0) {
4024       GST_FIXME ("Unsupported SEI type %d", msg->payloadType);
4025       continue;
4026     }
4027 
4028     /* write payload type bytes */
4029     while (payload_type_data >= 0xff) {
4030       WRITE_UINT8 (&nw, 0xff, 8);
4031       payload_type_data -= 0xff;
4032     }
4033     WRITE_UINT8 (&nw, payload_type_data, 8);
4034 
4035     /* write payload size bytes */
4036     while (payload_size_data >= 0xff) {
4037       WRITE_UINT8 (&nw, 0xff, 8);
4038       payload_size_data -= 0xff;
4039     }
4040     WRITE_UINT8 (&nw, payload_size_data, 8);
4041 
4042     switch (msg->payloadType) {
4043       case GST_H265_SEI_REGISTERED_USER_DATA:
4044         GST_DEBUG ("Writing \"Registered user data\" done");
4045         if (!gst_h265_write_sei_registered_user_data (&nw,
4046                 &msg->payload.registered_user_data)) {
4047           GST_WARNING ("Failed to write \"Registered user data\"");
4048           goto error;
4049         }
4050         have_written_data = TRUE;
4051         break;
4052       case GST_H265_SEI_TIME_CODE:
4053         GST_DEBUG ("Wrtiting \"Time code\"");
4054         if (!gst_h265_write_sei_time_code (&nw, &msg->payload.time_code)) {
4055           GST_WARNING ("Failed to write \"Time code\"");
4056           goto error;
4057         }
4058         have_written_data = TRUE;
4059         break;
4060       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
4061         GST_DEBUG ("Wrtiting \"Mastering display colour volume\"");
4062         if (!gst_h265_write_sei_mastering_display_colour_volume (&nw,
4063                 &msg->payload.mastering_display_colour_volume)) {
4064           GST_WARNING ("Failed to write \"Mastering display colour volume\"");
4065           goto error;
4066         }
4067         have_written_data = TRUE;
4068         break;
4069       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
4070         GST_DEBUG ("Writing \"Content light level\" done");
4071         if (!gst_h265_write_sei_content_light_level_info (&nw,
4072                 &msg->payload.content_light_level)) {
4073           GST_WARNING ("Failed to write \"Content light level\"");
4074           goto error;
4075         }
4076         have_written_data = TRUE;
4077         break;
4078       default:
4079         break;
4080     }
4081 
4082     if (need_align && !nal_writer_do_rbsp_trailing_bits (&nw)) {
4083       GST_WARNING ("Cannot insert traling bits");
4084       goto error;
4085     }
4086   }
4087 
4088   if (!have_written_data) {
4089     GST_WARNING ("No written sei data");
4090     goto error;
4091   }
4092 
4093   if (!nal_writer_do_rbsp_trailing_bits (&nw)) {
4094     GST_WARNING ("Failed to insert rbsp trailing bits");
4095     goto error;
4096   }
4097 
4098   return nal_writer_reset_and_get_memory (&nw);
4099 
4100 error:
4101   nal_writer_reset (&nw);
4102 
4103   return NULL;
4104 }
4105 
4106 /**
4107  * gst_h265_create_sei_memory:
4108  * @layer_id: a nal unit layer id
4109  * @temporal_id_plus1: a nal unit temporal identifier
4110  * @start_code_prefix_length: a length of start code prefix, must be 3 or 4
4111  * @messages: (transfer none): a GArray of #GstH265SEIMessage
4112  *
4113  * Creates raw byte-stream format (a.k.a Annex B type) SEI nal unit data
4114  * from @messages
4115  *
4116  * Returns: a #GstMemory containing a PREFIX SEI nal unit
4117  *
4118  * Since: 1.18
4119  */
4120 GstMemory *
gst_h265_create_sei_memory(guint8 layer_id,guint8 temporal_id_plus1,guint8 start_code_prefix_length,GArray * messages)4121 gst_h265_create_sei_memory (guint8 layer_id, guint8 temporal_id_plus1,
4122     guint8 start_code_prefix_length, GArray * messages)
4123 {
4124   g_return_val_if_fail (start_code_prefix_length == 3
4125       || start_code_prefix_length == 4, NULL);
4126   g_return_val_if_fail (messages != NULL, NULL);
4127   g_return_val_if_fail (messages->len > 0, NULL);
4128 
4129   return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4130       start_code_prefix_length, FALSE, messages);
4131 }
4132 
4133 /**
4134  * gst_h265_create_sei_memory_hevc:
4135  * @layer_id: a nal unit layer id
4136  * @temporal_id_plus1: a nal unit temporal identifier
4137  * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4138  * @messages: (transfer none): a GArray of #GstH265SEIMessage
4139  *
4140  * Creates raw packetized format SEI nal unit data from @messages
4141  *
4142  * Returns: a #GstMemory containing a PREFIX SEI nal unit
4143  *
4144  * Since: 1.18
4145  */
4146 GstMemory *
gst_h265_create_sei_memory_hevc(guint8 layer_id,guint8 temporal_id_plus1,guint8 nal_length_size,GArray * messages)4147 gst_h265_create_sei_memory_hevc (guint8 layer_id, guint8 temporal_id_plus1,
4148     guint8 nal_length_size, GArray * messages)
4149 {
4150   return gst_h265_create_sei_memory_internal (layer_id, temporal_id_plus1,
4151       nal_length_size, TRUE, messages);
4152 }
4153 
4154 static GstBuffer *
gst_h265_parser_insert_sei_internal(GstH265Parser * parser,guint8 nal_prefix_size,gboolean packetized,GstBuffer * au,GstMemory * sei)4155 gst_h265_parser_insert_sei_internal (GstH265Parser * parser,
4156     guint8 nal_prefix_size, gboolean packetized, GstBuffer * au,
4157     GstMemory * sei)
4158 {
4159   GstH265NalUnit nalu;
4160   GstH265NalUnit sei_nalu;
4161   GstMapInfo info;
4162   GstMapInfo sei_info;
4163   GstH265ParserResult pres;
4164   guint offset = 0;
4165   GstBuffer *new_buffer = NULL;
4166   GstMemory *new_mem = NULL;
4167 
4168   /* all SEI payload types supported by us need to have the identical
4169    * temporal id to that of slice. Parse SEI first and we will
4170    * update it if it's required */
4171   if (!gst_memory_map (sei, &sei_info, GST_MAP_READ)) {
4172     GST_ERROR ("Cannot map sei memory");
4173     return NULL;
4174   }
4175 
4176   if (packetized) {
4177     pres = gst_h265_parser_identify_nalu_hevc (parser,
4178         sei_info.data, 0, sei_info.size, nal_prefix_size, &sei_nalu);
4179   } else {
4180     pres = gst_h265_parser_identify_nalu (parser,
4181         sei_info.data, 0, sei_info.size, &sei_nalu);
4182   }
4183   gst_memory_unmap (sei, &sei_info);
4184   if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4185     GST_DEBUG ("Failed to identify sei nal unit, ret: %d", pres);
4186     return NULL;
4187   }
4188 
4189   if (!gst_buffer_map (au, &info, GST_MAP_READ)) {
4190     GST_ERROR ("Cannot map au buffer");
4191     return NULL;
4192   }
4193 
4194   /* Find the offset of the first slice */
4195   do {
4196     if (packetized) {
4197       pres = gst_h265_parser_identify_nalu_hevc (parser,
4198           info.data, offset, info.size, nal_prefix_size, &nalu);
4199     } else {
4200       pres = gst_h265_parser_identify_nalu (parser,
4201           info.data, offset, info.size, &nalu);
4202     }
4203 
4204     if (pres != GST_H265_PARSER_OK && pres != GST_H265_PARSER_NO_NAL_END) {
4205       GST_DEBUG ("Failed to identify nal unit, ret: %d", pres);
4206       gst_buffer_unmap (au, &info);
4207 
4208       return NULL;
4209     }
4210 
4211     if (nalu.type <= GST_H265_NAL_SLICE_RASL_R
4212         || (nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP
4213             && nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)) {
4214       GST_DEBUG ("Found slice nal type %d at offset %d", nalu.type,
4215           nalu.sc_offset);
4216       break;
4217     }
4218 
4219     offset = nalu.offset + nalu.size;
4220   } while (pres == GST_H265_PARSER_OK);
4221   gst_buffer_unmap (au, &info);
4222 
4223   /* found the best position now, create new buffer */
4224   new_buffer = gst_buffer_new ();
4225 
4226   /* copy all metadata */
4227   if (!gst_buffer_copy_into (new_buffer, au, GST_BUFFER_COPY_METADATA, 0, -1)) {
4228     GST_ERROR ("Failed to copy metadata into new buffer");
4229     gst_clear_buffer (&new_buffer);
4230     goto out;
4231   }
4232 
4233   /* copy non-slice nal */
4234   if (nalu.sc_offset > 0) {
4235     if (!gst_buffer_copy_into (new_buffer, au,
4236             GST_BUFFER_COPY_MEMORY, 0, nalu.sc_offset)) {
4237       GST_ERROR ("Failed to copy buffer");
4238       gst_clear_buffer (&new_buffer);
4239       goto out;
4240     }
4241   }
4242 
4243   /* check whether we need to update temporal id and layer id.
4244    * If it's not matched to slice nalu, update it.
4245    */
4246   if (sei_nalu.layer_id != nalu.layer_id || sei_nalu.temporal_id_plus1 !=
4247       nalu.temporal_id_plus1) {
4248     guint16 nalu_header;
4249     guint16 layer_id_temporal_id = 0;
4250     new_mem = gst_memory_copy (sei, 0, -1);
4251 
4252     if (!gst_memory_map (new_mem, &sei_info, GST_MAP_READWRITE)) {
4253       GST_ERROR ("Failed to map new sei memory");
4254       gst_memory_unref (new_mem);
4255       gst_clear_buffer (&new_buffer);
4256       goto out;
4257     }
4258 
4259     nalu_header = GST_READ_UINT16_BE (sei_info.data + sei_nalu.offset);
4260 
4261     /* clear bits 7 ~ 15
4262      * NOTE:
4263      * bit 0: forbidden_zero_bit
4264      * bits 1 ~ 6: nalu type */
4265     nalu_header &= 0xfe00;
4266 
4267     layer_id_temporal_id = ((nalu.layer_id << 3) & 0x1f8);
4268     layer_id_temporal_id |= (nalu.temporal_id_plus1 & 0x7);
4269 
4270     nalu_header |= layer_id_temporal_id;
4271     GST_WRITE_UINT16_BE (sei_info.data + sei_nalu.offset, nalu_header);
4272     gst_memory_unmap (new_mem, &sei_info);
4273   } else {
4274     new_mem = gst_memory_ref (sei);
4275   }
4276 
4277   /* insert sei */
4278   gst_buffer_append_memory (new_buffer, new_mem);
4279 
4280   /* copy the rest */
4281   if (!gst_buffer_copy_into (new_buffer, au,
4282           GST_BUFFER_COPY_MEMORY, nalu.sc_offset, -1)) {
4283     GST_ERROR ("Failed to copy buffer");
4284     gst_clear_buffer (&new_buffer);
4285     goto out;
4286   }
4287 
4288 out:
4289   return new_buffer;
4290 }
4291 
4292 /**
4293  * gst_h265_parser_insert_sei:
4294  * @parser: a #GstH265Parser
4295  * @au: (transfer none): a #GstBuffer containing AU data
4296  * @sei: (transfer none): a #GstMemory containing a SEI nal
4297  *
4298  * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4299  * The validation for completeness of @au and @sei is caller's responsibility.
4300  * Both @au and @sei must be byte-stream formatted
4301  *
4302  * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4303  *   if cannot figure out proper position to insert a @sei
4304  *
4305  * Since: 1.18
4306  */
4307 GstBuffer *
gst_h265_parser_insert_sei(GstH265Parser * parser,GstBuffer * au,GstMemory * sei)4308 gst_h265_parser_insert_sei (GstH265Parser * parser, GstBuffer * au,
4309     GstMemory * sei)
4310 {
4311   g_return_val_if_fail (parser != NULL, NULL);
4312   g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4313   g_return_val_if_fail (sei != NULL, NULL);
4314 
4315   /* the size of start code prefix (3 or 4) is not matter since it will be
4316    * scanned */
4317   return gst_h265_parser_insert_sei_internal (parser, 4, FALSE, au, sei);
4318 }
4319 
4320 /**
4321  * gst_h265_parser_insert_sei_hevc:
4322  * @parser: a #GstH265Parser
4323  * @nal_length_size: a size of nal length field, allowed range is [1, 4]
4324  * @au: (transfer none): a #GstBuffer containing AU data
4325  * @sei: (transfer none): a #GstMemory containing a SEI nal
4326  *
4327  * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
4328  * The validation for completeness of @au and @sei is caller's responsibility.
4329  * Nal prefix type of both @au and @sei must be packetized, and
4330  * also the size of nal length field must be identical to @nal_length_size
4331  *
4332  * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
4333  *   if cannot figure out proper position to insert a @sei
4334  *
4335  * Since: 1.18
4336  */
4337 GstBuffer *
gst_h265_parser_insert_sei_hevc(GstH265Parser * parser,guint8 nal_length_size,GstBuffer * au,GstMemory * sei)4338 gst_h265_parser_insert_sei_hevc (GstH265Parser * parser, guint8 nal_length_size,
4339     GstBuffer * au, GstMemory * sei)
4340 {
4341   g_return_val_if_fail (parser != NULL, NULL);
4342   g_return_val_if_fail (nal_length_size > 0 && nal_length_size < 5, NULL);
4343   g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
4344   g_return_val_if_fail (sei != NULL, NULL);
4345 
4346   return gst_h265_parser_insert_sei_internal (parser, nal_length_size, TRUE,
4347       au, sei);
4348 }
4349 
4350 /**
4351  * gst_h265_get_profile_from_sps:
4352  * @sps: a #GstH265SPS
4353  *
4354  * Return the H265 profile from @sps.
4355  *
4356  * Returns: a #GstH265Profile
4357  * Since: 1.20
4358  */
4359 GstH265Profile
gst_h265_get_profile_from_sps(GstH265SPS * sps)4360 gst_h265_get_profile_from_sps (GstH265SPS * sps)
4361 {
4362   GstH265Profile profiles[GST_H265_PROFILE_MAX] = { GST_H265_PROFILE_INVALID, };
4363   GstH265ProfileTierLevel tmp_ptl;
4364   guint i, len = 0;
4365   guint chroma_format_idc, bit_depth_luma, bit_depth_chroma;
4366 
4367   g_return_val_if_fail (sps != NULL, GST_H265_PROFILE_INVALID);
4368 
4369   tmp_ptl = sps->profile_tier_level;
4370   chroma_format_idc = sps->chroma_format_idc;
4371   bit_depth_luma = sps->bit_depth_luma_minus8 + 8;
4372   bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
4373 
4374   gst_h265_profile_tier_level_get_profiles (&sps->profile_tier_level, profiles,
4375       &len);
4376 
4377   for (i = 0; i < len && i < G_N_ELEMENTS (profiles); i++) {
4378     switch (profiles[i]) {
4379       case GST_H265_PROFILE_INVALID:
4380         break;
4381       case GST_H265_PROFILE_MAIN:
4382       case GST_H265_PROFILE_MAIN_STILL_PICTURE:
4383         /* A.3.2 or A.3.5 */
4384         if (chroma_format_idc == 1
4385             && bit_depth_luma == 8 && bit_depth_chroma == 8)
4386           return profiles[i];
4387         break;
4388       case GST_H265_PROFILE_MAIN_10:
4389         /* A.3.3 */
4390         if (chroma_format_idc == 1
4391             && bit_depth_luma >= 8 && bit_depth_luma <= 10
4392             && bit_depth_chroma >= 8 && bit_depth_chroma <= 10)
4393           return profiles[i];
4394         break;
4395       default:
4396         return profiles[i];
4397     }
4398   }
4399 
4400   /* Invalid profile: */
4401   /* Set the conformance indicators based on chroma_format_idc / bit_depth */
4402   switch (chroma_format_idc) {
4403     case 0:
4404       tmp_ptl.max_monochrome_constraint_flag = 1;
4405       tmp_ptl.max_420chroma_constraint_flag = 1;
4406       tmp_ptl.max_422chroma_constraint_flag = 1;
4407       break;
4408 
4409     case 1:
4410       tmp_ptl.max_monochrome_constraint_flag = 0;
4411       tmp_ptl.max_420chroma_constraint_flag = 1;
4412       tmp_ptl.max_422chroma_constraint_flag = 1;
4413       break;
4414 
4415     case 2:
4416       tmp_ptl.max_monochrome_constraint_flag = 0;
4417       tmp_ptl.max_420chroma_constraint_flag = 0;
4418       tmp_ptl.max_422chroma_constraint_flag = 1;
4419       break;
4420 
4421     case 3:
4422       tmp_ptl.max_monochrome_constraint_flag = 0;
4423       tmp_ptl.max_420chroma_constraint_flag = 0;
4424       tmp_ptl.max_422chroma_constraint_flag = 0;
4425       break;
4426 
4427     default:
4428       g_assert_not_reached ();
4429       break;
4430   }
4431 
4432   tmp_ptl.max_8bit_constraint_flag = 1;
4433   tmp_ptl.max_10bit_constraint_flag = 1;
4434   tmp_ptl.max_12bit_constraint_flag = 1;
4435   tmp_ptl.max_14bit_constraint_flag = 1;
4436 
4437   if (bit_depth_luma > 8 || bit_depth_chroma > 8)
4438     tmp_ptl.max_8bit_constraint_flag = 0;
4439 
4440   if (bit_depth_luma > 10 || bit_depth_chroma > 10)
4441     tmp_ptl.max_10bit_constraint_flag = 0;
4442 
4443   if (bit_depth_luma > 12 || bit_depth_chroma > 12)
4444     tmp_ptl.max_12bit_constraint_flag = 0;
4445 
4446   if (tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_HIGH_THROUGHPUT
4447       || tmp_ptl.profile_idc == GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING
4448       || tmp_ptl.profile_idc ==
4449       GST_H265_PROFILE_IDC_SCALABLE_FORMAT_RANGE_EXTENSION
4450       || tmp_ptl.profile_idc ==
4451       GST_H265_PROFILE_IDC_HIGH_THROUGHPUT_SCREEN_CONTENT_CODING_EXTENSION
4452       || tmp_ptl.profile_compatibility_flag[5]
4453       || tmp_ptl.profile_compatibility_flag[9]
4454       || tmp_ptl.profile_compatibility_flag[10]
4455       || tmp_ptl.profile_compatibility_flag[11]) {
4456     if (bit_depth_luma > 14 || bit_depth_chroma > 14)
4457       tmp_ptl.max_14bit_constraint_flag = 0;
4458   } else {
4459     tmp_ptl.max_14bit_constraint_flag = 0;
4460   }
4461 
4462   /* first profile of the synthetic ptl */
4463   return gst_h265_profile_tier_level_get_profile (&tmp_ptl);
4464 }
4465