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