libxcoder 5.6.0
Loading...
Searching...
No Matches
ni_decode_utils.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (C) 2022 NETINT Technologies
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 * SOFTWARE.
19 *
20 ******************************************************************************/
21
22/*!*****************************************************************************
23 * \file decode_utils.c
24 *
25 * \brief Video decoding utility functions shared by Libxcoder API examples
26 ******************************************************************************/
27
28#include "ni_generic_utils.h"
29#include "ni_decode_utils.h"
30#include "ni_log.h"
31#include "ni_util.h"
32#include "ni_defs.h"
33
34static const uint8_t default_scaling_list_inter[] = {
35 16, 16, 16, 16, 17, 18, 20, 24, 16, 16, 16, 17, 18, 20, 24, 25,
36 16, 16, 17, 18, 20, 24, 25, 28, 16, 17, 18, 20, 24, 25, 28, 33,
37 17, 18, 20, 24, 25, 28, 33, 41, 18, 20, 24, 25, 28, 33, 41, 54,
38 20, 24, 25, 28, 33, 41, 54, 71, 24, 25, 28, 33, 41, 54, 71, 91};
39
40static const uint8_t default_scaling_list_intra[] = {
41 16, 16, 16, 16, 17, 18, 21, 24, 16, 16, 16, 16, 17, 19, 22, 25,
42 16, 16, 17, 18, 20, 22, 25, 29, 16, 16, 18, 21, 24, 27, 31, 36,
43 17, 17, 20, 24, 30, 35, 41, 47, 18, 19, 22, 27, 35, 44, 54, 65,
44 21, 22, 25, 31, 41, 54, 70, 88, 24, 25, 29, 36, 47, 65, 88, 115};
45
46static const uint8_t default_scaling4[2][16] = {
47 {6, 13, 20, 28, 13, 20, 28, 32, 20, 28, 32, 37, 28, 32, 37, 42},
48 {10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34}};
49
50static const uint8_t default_scaling8[2][64] = {
51 {6, 10, 13, 16, 18, 23, 25, 27, 10, 11, 16, 18, 23, 25, 27, 29,
52 13, 16, 18, 23, 25, 27, 29, 31, 16, 18, 23, 25, 27, 29, 31, 33,
53 18, 23, 25, 27, 29, 31, 33, 36, 23, 25, 27, 29, 31, 33, 36, 38,
54 25, 27, 29, 31, 33, 36, 38, 40, 27, 29, 31, 33, 36, 38, 40, 42},
55 {9, 13, 15, 17, 19, 21, 22, 24, 13, 13, 17, 19, 21, 22, 24, 25,
56 15, 17, 19, 21, 22, 24, 25, 27, 17, 19, 21, 22, 24, 25, 27, 28,
57 19, 21, 22, 24, 25, 27, 28, 30, 21, 22, 24, 25, 27, 28, 30, 32,
58 22, 24, 25, 27, 28, 30, 32, 33, 24, 25, 27, 28, 30, 32, 33, 35}};
59
60static const uint8_t ni_zigzag_direct[64] = {
61 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
62 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
63 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
64 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
65
66static const uint8_t ni_zigzag_scan[16 + 1] = {
67 0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4, 1 + 1 * 4, 2 + 0 * 4,
68 3 + 0 * 4, 2 + 1 * 4, 1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4,
69 3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
70};
71
72static const ni_rational_t vui_sar[] = {
73 {0, 1}, {1, 1}, {12, 11}, {10, 11}, {16, 11}, {40, 33},
74 {24, 11}, {20, 11}, {32, 11}, {80, 33}, {18, 11}, {15, 11},
75 {64, 33}, {160, 99}, {4, 3}, {3, 2}, {2, 1},
76};
77
78static const uint8_t hevc_sub_width_c[] = {1, 2, 2, 1};
79
80static const uint8_t hevc_sub_height_c[] = {1, 2, 1, 1};
81
82static const uint8_t hevc_diag_scan4x4_x[16] = {
83 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 2, 3, 3,
84};
85
86static const uint8_t hevc_diag_scan4x4_y[16] = {
87 0, 1, 0, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 3, 2, 3,
88};
89
90static const uint8_t hevc_diag_scan8x8_x[64] = {
91 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0,
92 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 2,
93 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 4, 5, 6, 7, 5, 6, 7, 6, 7, 7,
94};
95
96static const uint8_t hevc_diag_scan8x8_y[64] = {
97 0, 1, 0, 2, 1, 0, 3, 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 6,
98 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 7,
99 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 7, 6, 5, 4, 7, 6, 5, 7, 6, 7,
100};
101
102// find/copy next H.264 NAL unit (including start code) and its type;
103// return NAL data size if found, 0 otherwise
104uint64_t find_h264_next_nalu(ni_demo_context_t *p_ctx, uint8_t *p_dst, int *nal_type)
105{
106 uint64_t data_size;
107 uint64_t i = p_ctx->curr_file_offset;
108
109 if (i + 3 >= p_ctx->total_file_size)
110 {
111 ni_log(NI_LOG_DEBUG, "%s reaching end, curr_pos %llu, total input size %llu\n",
112 __func__, (unsigned long long)p_ctx->curr_file_offset, (unsigned long long)p_ctx->total_file_size);
113
114 if (p_ctx->loops_left > 1)
115 {
116 p_ctx->loops_left--;
117 ni_log(NI_LOG_DEBUG, "input processed, %d loops left\n", p_ctx->loops_left);
118 reset_data_buf_pos(p_ctx);
119 i = p_ctx->curr_file_offset;
120 } else {
121 return 0;
122 }
123 }
124
125 // search for start code 0x000001 or 0x00000001
126 while ((p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
127 p_ctx->file_cache[i + 2] != 0x01) &&
128 (p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
129 p_ctx->file_cache[i + 2] != 0x00 || p_ctx->file_cache[i + 3] != 0x01))
130 {
131 i++;
132 if (i + 3 > p_ctx->total_file_size)
133 {
134 return 0;
135 }
136 }
137
138 // found start code, advance to NAL unit start depends on actual start code
139 if (p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
140 p_ctx->file_cache[i + 2] != 0x01)
141 {
142 i++;
143 }
144
145 i += 3;
146
147 // get the NAL type
148 *nal_type = (p_ctx->file_cache[i] & 0x1f);
149
150 // advance to the end of NAL, or stream
151 while ((p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
152 p_ctx->file_cache[i + 2] != 0x00) &&
153 (p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
154 p_ctx->file_cache[i + 2] != 0x01))
155 {
156 i++;
157 // if reaching the stream end
158 if (i + 3 > p_ctx->total_file_size)
159 {
160 data_size = p_ctx->total_file_size - p_ctx->curr_file_offset;
161 memcpy(p_dst, &p_ctx->file_cache[p_ctx->curr_file_offset], data_size);
162 p_ctx->curr_file_offset = p_ctx->total_file_size;
163 return data_size;
164 }
165 }
166
167 data_size = i - p_ctx->curr_file_offset;
168 memcpy(p_dst, &p_ctx->file_cache[p_ctx->curr_file_offset], data_size);
169 p_ctx->curr_file_offset = i;
170 return data_size;
171}
172
173// HRD parsing: return 0 if parsing ok, -1 otherwise
175{
176 int cpb_count, i;
177
178 cpb_count = (int)ni_bs_reader_get_ue(br) + 1;
179 if (cpb_count > 32U)
180 {
181 ni_log(NI_LOG_ERROR, "parse_hrd invalid cpb_count %d\n", cpb_count);
182 return -1;
183 }
184
185 ni_bs_reader_get_bits(br, 4); // bit_rate_scale
186 ni_bs_reader_get_bits(br, 4); // cpb_size_scale
187 for (i = 0; i < cpb_count; i++)
188 {
189 ni_bs_reader_get_ue(br); // bit_rate_value_minus1
190 ni_bs_reader_get_ue(br); // cpb_size_value_minus1
191 ni_bs_reader_get_bits(br, 1); // cbr_flag
192 }
194 (int)ni_bs_reader_get_bits(br, 5) + 1;
195 sps->cpb_removal_delay_length = (int)ni_bs_reader_get_bits(br, 5) + 1;
196 sps->dpb_output_delay_length = (int)ni_bs_reader_get_bits(br, 5) + 1;
198 sps->cpb_cnt = cpb_count;
199 return 0;
200}
201
202// VUI parsing: return 0 if parsing ok, -1 otherwise
204{
205 int ret = -1, aspect_ratio_info_present_flag;
206 unsigned int aspect_ratio_idc;
207
208 aspect_ratio_info_present_flag = ni_bs_reader_get_bits(br, 1);
209 if (aspect_ratio_info_present_flag)
210 {
211 aspect_ratio_idc = ni_bs_reader_get_bits(br, 8);
212 if (EXTENDED_SAR == aspect_ratio_idc)
213 {
214 sps->sar.num = ni_bs_reader_get_bits(br, 16);
215 sps->sar.den = ni_bs_reader_get_bits(br, 16);
216 } else if (aspect_ratio_idc < NI_NUM_PIXEL_ASPECT_RATIO)
217 {
218 sps->sar = ni_h264_pixel_aspect_list[aspect_ratio_idc];
219 } else
220 {
221 ni_log(NI_LOG_ERROR, "parse_vui: illegal aspect ratio %u\n",
222 aspect_ratio_idc);
223 goto end;
224 }
225 } else
226 {
227 sps->sar.num = sps->sar.den = 0;
228 }
229
230 if (ni_bs_reader_get_bits(br, 1)) // overscan_info_present_flag
231 {
232 ni_bs_reader_get_bits(br, 1); // overscan_appropriate_flag
233 }
236 {
237 ni_bs_reader_get_bits(br, 3); // video_format
238 sps->full_range =
239 ni_bs_reader_get_bits(br, 1); // video_full_range_flag
240
243 {
245 sps->color_trc = ni_bs_reader_get_bits(br, 8);
246 sps->colorspace = ni_bs_reader_get_bits(br, 8);
249 {
251 }
252 if (sps->color_trc < NI_COL_TRC_RESERVED0 ||
253 sps->color_trc >= NI_COL_TRC_NB)
254 {
256 }
257 if (sps->colorspace < NI_COL_SPC_RGB ||
259 {
261 }
262 }
263 }
264
265 if (ni_bs_reader_get_bits(br, 1)) // chroma_location_info_present_flag
266 {
267 ni_bs_reader_get_ue(br); // chroma_sample_location_type_top_field
268 ni_bs_reader_get_ue(br); // chroma_sample_location_type_bottom_field
269 }
270
273 {
274 unsigned num_units_in_tick = ni_bs_reader_get_bits(br, 32);
275 unsigned time_scale = ni_bs_reader_get_bits(br, 32);
276 if (!num_units_in_tick || !time_scale)
277 {
278 ni_log(NI_LOG_ERROR, "parse_vui: error num_units_in_tick/time_scale "
279 "(%u/%u)\n",
280 num_units_in_tick, time_scale);
282 }
284 }
285
287 if (sps->nal_hrd_parameters_present_flag && h264_parse_hrd(br, sps) < 0)
288 {
289 ni_log(NI_LOG_ERROR, "parse_vui: nal_hrd_parameters_present and error "
290 "parse_hrd !\n");
291 goto end;
292 }
293
295 if (sps->vcl_hrd_parameters_present_flag && h264_parse_hrd(br, sps) < 0)
296 {
297 ni_log(NI_LOG_ERROR, "parse_vui: vcl_hrd_parameters_present and error "
298 "parse_hrd !\n");
299 goto end;
300 }
301
304 {
305 ni_bs_reader_get_bits(br, 1); // low_delay_hrd_flag
306 }
307
309
312 {
314 1); // motion_vectors_over_pic_boundaries_flag
315 ni_bs_reader_get_ue(br); // max_bytes_per_pic_denom
316 ni_bs_reader_get_ue(br); // max_bits_per_mb_denom
317 ni_bs_reader_get_ue(br); // log2_max_mv_length_horizontal
318 ni_bs_reader_get_ue(br); // log2_max_mv_length_vertical
321
322 if (sps->num_reorder_frames > 16U)
323 {
324 ni_log(NI_LOG_ERROR, "parse_vui: clip illegal num_reorder_frames %d !\n",
325 sps->num_reorder_frames);
326 sps->num_reorder_frames = 16;
327 goto end;
328 }
329 }
330
331 // everything is fine
332 ret = 0;
333
334end:
335 return ret;
336}
337
338int h264_parse_scaling_list(ni_bitstream_reader_t *br, uint8_t *factors, int size,
339 const uint8_t *jvt_list, const uint8_t *fallback_list)
340{
341 int i, last = 8, next = 8;
342 const uint8_t *scan = (size == 16 ? ni_zigzag_scan : ni_zigzag_direct);
343
344 // matrix not written, we use the predicted one */
345 if (!ni_bs_reader_get_bits(br, 1))
346 {
347 memcpy(factors, fallback_list, size * sizeof(uint8_t));
348 } else
349 {
350 for (i = 0; i < size; i++)
351 {
352 if (next)
353 {
354 int v = ni_bs_reader_get_se(br);
355 if (v < -128 || v > 127)
356 {
357 ni_log(NI_LOG_ERROR, "delta scale %d is invalid\n", v);
358 return -1;
359 }
360 next = (last + v) & 0xff;
361 }
362 if (!i && !next)
363 { // matrix not written, we use the preset one
364 memcpy(factors, jvt_list, size * sizeof(uint8_t));
365 break;
366 }
367 last = (factors[scan[i]] = next ? next : last);
368 }
369 }
370 return 0;
371}
372
373// SPS seq scaling matrices parsing: return 0 if parsing ok, -1 otherwise
375 uint8_t (*scaling_matrix4)[16], uint8_t (*scaling_matrix8)[64])
376{
377 int ret = 0;
378 const uint8_t *fallback[4] = {default_scaling4[0], default_scaling4[1],
379 default_scaling8[0], default_scaling8[1]};
380
381 if (ni_bs_reader_get_bits(br, 1)) // scaling_matrix_present
382 {
383 // retrieve matrices
384 ret |= h264_parse_scaling_list(br, scaling_matrix4[0], 16,
385 default_scaling4[0], fallback[0]); // Intra, Y
386 ret |= h264_parse_scaling_list(br, scaling_matrix4[1], 16,
387 default_scaling4[0], scaling_matrix4[0]); // Intra, Cr
388 ret |= h264_parse_scaling_list(br, scaling_matrix4[2], 16,
389 default_scaling4[0], scaling_matrix4[1]); // Intra, Cb
390 ret |= h264_parse_scaling_list(br, scaling_matrix4[3], 16,
391 default_scaling4[1], fallback[1]); // Inter, Y
392 ret |= h264_parse_scaling_list(br, scaling_matrix4[4], 16,
393 default_scaling4[1], scaling_matrix4[3]); // Inter, Cr
394 ret |= h264_parse_scaling_list(br, scaling_matrix4[5], 16,
395 default_scaling4[1], scaling_matrix4[4]); // Inter, Cb
396 ret |= h264_parse_scaling_list(br, scaling_matrix8[0], 64,
397 default_scaling8[0], fallback[2]); // Intra, Y
398 ret |= h264_parse_scaling_list(br, scaling_matrix8[3], 64,
399 default_scaling8[1], fallback[3]); // Inter, Y
400 if (sps->chroma_format_idc == 3)
401 {
402 ret |= h264_parse_scaling_list(br, scaling_matrix8[1], 64,
403 default_scaling8[0], scaling_matrix8[0]); // Intra, Cr
404 ret |= h264_parse_scaling_list(br, scaling_matrix8[4], 64,
405 default_scaling8[1], scaling_matrix8[3]); // Inter, Cr
406 ret |= h264_parse_scaling_list(br, scaling_matrix8[2], 64,
407 default_scaling8[0], scaling_matrix8[1]); // Intra, Cb
408 ret |= h264_parse_scaling_list(br, scaling_matrix8[5], 64,
409 default_scaling8[1], scaling_matrix8[4]); // Inter, Cb
410 }
411 if (!ret)
412 {
413 ret = 1;
414 }
415 }
416 return ret;
417}
418
419// SPS parsing: return 0 if parsing ok, -1 otherwise
420int h264_parse_sps(uint8_t *buf, int size_bytes, ni_h264_sps_t *sps)
421{
422 int ret = -1;
424 int profile_idc, level_idc, constraint_set_flags = 0;
425 uint32_t sps_id;
426 int i, log2_max_frame_num_minus4;
427
428 ni_bitstream_reader_init(&br, buf, 8 * size_bytes);
429 // skip NAL header
431
432 profile_idc = ni_bs_reader_get_bits(&br, 8);
433 // from constraint_set0_flag to constraint_set5_flag
434 constraint_set_flags |= ni_bs_reader_get_bits(&br, 1) << 0;
435 constraint_set_flags |= ni_bs_reader_get_bits(&br, 1) << 1;
436 constraint_set_flags |= ni_bs_reader_get_bits(&br, 1) << 2;
437 constraint_set_flags |= ni_bs_reader_get_bits(&br, 1) << 3;
438 constraint_set_flags |= ni_bs_reader_get_bits(&br, 1) << 4;
439 constraint_set_flags |= ni_bs_reader_get_bits(&br, 1) << 5;
440 ni_bs_reader_skip_bits(&br, 2); // reserved_zero_2bits
441 level_idc = ni_bs_reader_get_bits(&br, 8);
442 sps_id = ni_bs_reader_get_ue(&br);
443
444 sps->sps_id = sps_id;
445 sps->profile_idc = profile_idc;
446 sps->constraint_set_flags = constraint_set_flags;
447 sps->level_idc = level_idc;
448 sps->full_range = -1;
449
450 memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
451 memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
452 sps->scaling_matrix_present = 0;
453 sps->colorspace = 2; // NI_COL_SPC_UNSPECIFIED
454
455 if (100 == profile_idc || 110 == profile_idc || 122 == profile_idc ||
456 244 == profile_idc || 44 == profile_idc || 83 == profile_idc ||
457 86 == profile_idc || 118 == profile_idc || 128 == profile_idc ||
458 138 == profile_idc || 139 == profile_idc || 134 == profile_idc ||
459 135 == profile_idc || 144 == profile_idc /* old High444 profile */)
460 {
462 if (sps->chroma_format_idc > 3U)
463 {
464 ni_log(NI_LOG_ERROR, "parse_sps error: chroma_format_idc > 3 !\n");
465 goto end;
466 } else if (3 == sps->chroma_format_idc)
467 {
470 {
471 ni_log(NI_LOG_ERROR, "parse_sps error: residual_color_transform not "
472 "supported !\n");
473 goto end;
474 }
475 }
476 sps->bit_depth_luma = (int)ni_bs_reader_get_ue(&br) + 8;
477 sps->bit_depth_chroma = (int)ni_bs_reader_get_ue(&br) + 8;
478 if (sps->bit_depth_luma != sps->bit_depth_chroma)
479 {
480 ni_log(NI_LOG_ERROR, "parse_sps error: different luma %d & chroma %d "
481 "bit depth !\n",
483 goto end;
484 }
485 if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 12 ||
486 sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 12)
487 {
488 ni_log(NI_LOG_ERROR, "parse_sps error: illegal luma/chroma bit depth "
489 "value (%d %d) !\n",
491 goto end;
492 }
493
496 if (ret < 0)
497 {
498 ni_log(NI_LOG_ERROR, "parse_sps error scaling matrices parse failed !\n");
499 goto end;
500 }
501 sps->scaling_matrix_present |= ret;
502 } // profile_idc
503 else
504 {
505 sps->chroma_format_idc = 1;
506 sps->bit_depth_luma = 8;
507 sps->bit_depth_chroma = 8;
508 }
509
510 log2_max_frame_num_minus4 = ni_bs_reader_get_ue(&br);
511 if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 ||
512 log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4)
513 {
514 ni_log(NI_LOG_ERROR, "parse_sps error: log2_max_frame_num_minus4 %d out of "
515 "range (0-12)!\n",
516 log2_max_frame_num_minus4);
517 goto end;
518 }
519 sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;
520
521 sps->poc_type = ni_bs_reader_get_ue(&br);
522 if (0 == sps->poc_type)
523 {
524 uint32_t v = ni_bs_reader_get_ue(&br);
525 if (v > 12)
526 {
527 ni_log(NI_LOG_ERROR, "parse_sps error: log2_max_poc_lsb %u out of range! "
528 "\n",
529 v);
530 goto end;
531 }
532 sps->log2_max_poc_lsb = (int)v + 4;
533 } else if (1 == sps->poc_type)
534 {
539 if ((unsigned)sps->poc_cycle_length >= 256)
540 {
541 ni_log(NI_LOG_ERROR, "parse_sps error: poc_cycle_length %d out of range! "
542 "\n",
543 sps->poc_cycle_length);
544 goto end;
545 }
546 for (i = 0; i < sps->poc_cycle_length; i++)
547 {
549 }
550 } else if (2 != sps->poc_type)
551 {
552 ni_log(NI_LOG_ERROR, "parse_sps error: illegal PIC type %d!\n",
553 sps->poc_type);
554 goto end;
555 }
558 sps->mb_width = (int)ni_bs_reader_get_ue(&br) + 1;
559 sps->mb_height = (int)ni_bs_reader_get_ue(&br) + 1;
560
562 sps->mb_height *= 2 - sps->frame_mbs_only_flag;
563
564 if (!sps->frame_mbs_only_flag)
565 {
566 sps->mb_aff = ni_bs_reader_get_bits(&br, 1);
567 } else
568 {
569 sps->mb_aff = 0;
570 }
571
573
574 sps->crop = ni_bs_reader_get_bits(&br, 1);
575 if (sps->crop)
576 {
577 unsigned int crop_left = ni_bs_reader_get_ue(&br);
578 unsigned int crop_right = ni_bs_reader_get_ue(&br);
579 unsigned int crop_top = ni_bs_reader_get_ue(&br);
580 unsigned int crop_bottom = ni_bs_reader_get_ue(&br);
581
582 // no range checking
583 int vsub = (sps->chroma_format_idc == 1) ? 1 : 0;
584 int hsub =
585 (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 :
586 0;
587 int step_x = 1 << hsub;
588 int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
589
590 sps->crop_left = crop_left * step_x;
591 sps->crop_right = crop_right * step_x;
592 sps->crop_top = crop_top * step_y;
593 sps->crop_bottom = crop_bottom * step_y;
594 } else
595 {
596 sps->crop_left = sps->crop_right = sps->crop_top = sps->crop_bottom =
597 sps->crop = 0;
598 }
599
600 // deduce real width/heigh
601 sps->width = (int)(16 * sps->mb_width - sps->crop_left - sps->crop_right);
602 sps->height = (int)(16 * sps->mb_height - sps->crop_top - sps->crop_bottom);
603
606 {
607 int ret1 = h264_parse_vui(&br, sps);
608 if (ret1 < 0)
609 {
610 ni_log(NI_LOG_ERROR, "parse_sps error: parse_vui failed %d!\n", ret);
611 goto end;
612 }
613 }
614
615 // everything is fine
616 ret = 0;
617
618end:
619
620 return ret;
621}
622
623int h264_parse_sei(uint8_t *buf, int size_bytes, ni_h264_sps_t *sps,
624 int *sei_type, int *is_interlaced)
625{
627 *is_interlaced = 0;
628 int ret = -1, dummy;
629 int cpb_dpb_delays_present_flag = (sps->nal_hrd_parameters_present_flag ||
631 //pic_struct_present_flag
632
633 ni_bitstream_reader_init(&br, buf, 8 * size_bytes);
634 // skip NAL header
636
637 while (ni_bs_reader_get_bits_left(&br) > 16)
638 {
639 int next, size = 0;
640 unsigned type = 0, tmp;
641
642 do
643 {
644 if (ni_bs_reader_get_bits_left(&br) < 8)
645 {
646 ni_log(NI_LOG_ERROR, "parse_sei type parse error !\n");
647 goto end;
648 }
649 tmp = ni_bs_reader_get_bits(&br, 8);
650 type += tmp;
651 } while (tmp == 0xFF);
652
653 *sei_type = (int)type;
654 do
655 {
656 if (ni_bs_reader_get_bits_left(&br) < 8)
657 {
658 ni_log(NI_LOG_ERROR, "parse_sei type %u size parse error !\n", type);
659 goto end;
660 }
661 tmp = ni_bs_reader_get_bits(&br, 8);
662 size += (int)tmp;
663 } while (tmp == 0xFF);
664
665 if (size > ni_bs_reader_get_bits_left(&br) / 8)
666 {
667 ni_log(NI_LOG_DEBUG, "parse_sei SEI type %u size %d truncated at %d\n",
668 type, size, ni_bs_reader_get_bits_left(&br));
669 goto end;
670 }
671 next = ni_bs_reader_bits_count(&br) + 8 * size;
672
673 switch (type)
674 {
676 if (cpb_dpb_delays_present_flag)
677 {
680 }
682 {
683 dummy = ni_bs_reader_get_bits(&br, 4);
684 if (dummy < NI_H264_SEI_PIC_STRUCT_FRAME ||
686 {
688 "parse_sei pic_timing SEI invalid pic_struct: "
689 "%d\n",
690 dummy);
691 goto end;
692 }
694 {
695 *is_interlaced = 1;
696 }
697 goto success;
698 }
699 break;
700 default:
701 // skip all other SEI types
702 ;
703 }
705 } // while in SEI
706
707success:
708 ret = 0;
709
710end:
711 return ret;
712}
713
714// probe h.264 stream info; return 0 if stream can be decoded, -1 otherwise
716{
717 int ret = -1;
718 uint8_t *buf = NULL;
719 uint8_t *p_buf;
720 uint32_t nal_size, ep3_removed = 0, vcl_nal_count = 0;
721 int nal_type = -1, sei_type = -1;
722 int sps_parsed = 0, is_interlaced = 0;
723
724 if (NULL == (buf = calloc(1, NI_MAX_TX_SZ)))
725 {
726 ni_log(NI_LOG_ERROR, "Error probe_h264_stream_info: allocate stream buf\n");
727 goto end;
728 }
729
730 reset_data_buf_pos(p_ctx);
731 // probe at most 100 VCL before stops
732 while ((!sps_parsed || !is_interlaced) && vcl_nal_count < 100 &&
733 (nal_size = (uint32_t)find_h264_next_nalu(p_ctx, buf, &nal_type)) > 0)
734 {
735 ni_log(NI_LOG_DEBUG, "nal %d nal_size %d\n", nal_type, nal_size);
736 p_buf = buf;
737
738 // skip the start code
739 while (!(p_buf[0] == 0x00 && p_buf[1] == 0x00 && p_buf[2] == 0x01) &&
740 nal_size > 3)
741 {
742 p_buf++;
743 nal_size--;
744 }
745 if (nal_size <= 3)
746 {
747 ni_log(NI_LOG_ERROR, "Error probe_h264_stream_info NAL has no header\n");
748 continue;
749 }
750
751 p_buf += 3;
752 nal_size -= 3;
753
754 ep3_removed = ni_remove_emulation_prevent_bytes(p_buf, nal_size);
755 nal_size -= ep3_removed;
756
757 if (H264_NAL_SPS == nal_type && !sps_parsed)
758 {
759 if (vcl_nal_count > 0)
760 {
762 "Warning: %s has %d slice NAL units ahead of SPS!\n",
763 __func__, vcl_nal_count);
764 }
765
766 if (h264_parse_sps(p_buf, nal_size, sps))
767 {
768 ni_log(NI_LOG_ERROR, "probe_h264_stream_info: parse_sps error\n");
769 break;
770 }
771 sps_parsed = 1;
772 } else if (H264_NAL_SEI == nal_type)
773 {
774 h264_parse_sei(p_buf, nal_size, sps, &sei_type, &is_interlaced);
775 } else if (H264_NAL_SLICE == nal_type || H264_NAL_IDR_SLICE == nal_type)
776 {
777 vcl_nal_count++;
778 }
779
780 if (sps_parsed &&
784 NI_H264_SEI_TYPE_PIC_TIMING == sei_type && is_interlaced)
785 {
787 "probe_h264_stream_info interlaced NOT supported!\n");
788 break;
789 }
790 } // while for each NAL unit
791
792 reset_data_buf_pos(p_ctx);
793
794 ni_log(NI_LOG_DEBUG, "VCL NAL parsed: %d, SPS parsed: %s, is interlaced: %s\n",
795 vcl_nal_count, sps_parsed ? "Yes" : "No",
796 is_interlaced ? "Yes" : "No");
797 if (sps_parsed && !is_interlaced)
798 {
799 ret = 0;
800 } else
801 {
802 ni_log(NI_LOG_ERROR, "Input is either interlaced, or unable to determine, "
803 "probing failed.\n");
804 }
805
806 static const char csp[4][5] = {"Gray", "420", "422", "444"};
808 "H.264 stream probed %d VCL NAL units, sps:%u "
809 "profile:%d/%d poc %d ref:%d %dx%d [SAR: %d:%d] %s %s "
810 "%" PRId32 "/%" PRId32 " %d bits max_reord:%d max_dec_buf:"
811 "%d\n",
812 vcl_nal_count, sps->sps_id, sps->profile_idc, sps->level_idc,
813 sps->poc_type, sps->ref_frame_count, sps->width, sps->height,
814 /*sps->crop_left, sps->crop_right, sps->crop_top, sps->crop_bottom,*/
815 sps->sar.num, sps->sar.den,
816 sps->vui_parameters_present_flag ? "VUI" : "no-VUI",
817 csp[sps->chroma_format_idc],
819 sps->timing_info_present_flag ? sps->time_scale : 0,
820 sps->bit_depth_luma,
823
824end:
825 free(buf);
826 buf = NULL;
827 return ret;
828}
829
830// parse H.264 slice header to get frame_num; return 0 if success, -1 otherwise
831int parse_h264_slice_header(uint8_t *buf, int size_bytes, ni_h264_sps_t *sps,
832 int32_t *frame_num, unsigned int *first_mb_in_slice)
833{
835 uint8_t *p_buf = buf;
836 unsigned int slice_type, pps_id;
837
838 // skip the start code
839 while (!(p_buf[0] == 0x00 && p_buf[1] == 0x00 && p_buf[2] == 0x01) &&
840 size_bytes > 3)
841 {
842 p_buf++;
843 size_bytes--;
844 }
845 if (size_bytes <= 3)
846 {
847 ni_log(NI_LOG_ERROR, "Error parse_h264_slice_header slice has no header\n");
848 return -1;
849 }
850
851 p_buf += 3;
852 size_bytes -= 3;
853
854 ni_bitstream_reader_init(&br, p_buf, 8 * size_bytes);
855
856 // skip NAL header
858
859 *first_mb_in_slice = ni_bs_reader_get_ue(&br);
860 slice_type = ni_bs_reader_get_ue(&br);
861 if (slice_type > 9)
862 {
863 ni_log(NI_LOG_ERROR, "parse_h264_slice_header error: slice type %u too "
864 "large at %u\n",
865 slice_type, *first_mb_in_slice);
866 return -1;
867 }
868 pps_id = ni_bs_reader_get_ue(&br);
869 *frame_num = ni_bs_reader_get_bits(&br, sps->log2_max_frame_num);
870
871 ni_log(NI_LOG_DEBUG, "parse_h264_slice_header slice type %u frame_num %d "
872 "pps_id %u size %d first_mb %u\n",
873 slice_type, *frame_num, pps_id, size_bytes,
874 *first_mb_in_slice);
875
876 return 0;
877}
878
883uint64_t find_h265_next_nalu(ni_demo_context_t *p_ctx, uint8_t *p_dst, int *nal_type)
884{
885 uint64_t data_size;
886 uint64_t i = p_ctx->curr_file_offset;
887
888 if (i + 3 >= p_ctx->total_file_size)
889 {
890 ni_log(NI_LOG_DEBUG, "%s reaching end, curr_pos %llu, total input size %llu\n",
891 __func__, (unsigned long long)p_ctx->curr_file_offset, (unsigned long long)p_ctx->total_file_size);
892
893 if (p_ctx->loops_left > 1)
894 {
895 p_ctx->loops_left--;
896 ni_log(NI_LOG_DEBUG, "input processed, %d loops left\n", p_ctx->loops_left);
897 reset_data_buf_pos(p_ctx);
898 i = p_ctx->curr_file_offset;
899 } else {
900 return 0;
901 }
902 }
903
904 // search for start code 0x000001 or 0x00000001
905 while ((p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
906 p_ctx->file_cache[i + 2] != 0x01) &&
907 (p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
908 p_ctx->file_cache[i + 2] != 0x00 || p_ctx->file_cache[i + 3] != 0x01))
909 {
910 i++;
911 if (i + 3 > p_ctx->total_file_size)
912 {
913 return 0;
914 }
915 }
916
917 // found start code, advance to NAL unit start depends on actual start code
918 if (p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
919 p_ctx->file_cache[i + 2] != 0x01)
920 {
921 i++;
922 }
923
924 i += 3;
925
926 // get the NAL type
927 *nal_type = (p_ctx->file_cache[i] & 0x7E) >> 1;
928
929 // advance to the end of NAL, or stream
930 while ((p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
931 p_ctx->file_cache[i + 2] != 0x00) &&
932 (p_ctx->file_cache[i] != 0x00 || p_ctx->file_cache[i + 1] != 0x00 ||
933 p_ctx->file_cache[i + 2] != 0x01))
934 {
935 i++;
936 // if reaching the stream end
937 if (i + 3 > p_ctx->total_file_size)
938 {
939 data_size = p_ctx->total_file_size - p_ctx->curr_file_offset;
940 memcpy(p_dst, &p_ctx->file_cache[p_ctx->curr_file_offset], data_size);
941 p_ctx->curr_file_offset = p_ctx->total_file_size;
942 return data_size;
943 }
944 }
945
946 data_size = i - p_ctx->curr_file_offset;
947 memcpy(p_dst, &p_ctx->file_cache[p_ctx->curr_file_offset], data_size);
948 p_ctx->curr_file_offset = i;
949 return data_size;
950}
951
953 int subpic_params_present)
954{
955 uint32_t i;
956
957 for (i = 0; i < nb_cpb; i++)
958 {
959 ni_bs_reader_get_ue(br); // bit_rate_value_minus1
960 ni_bs_reader_get_ue(br); // cpb_size_value_minus1
961
962 if (subpic_params_present)
963 {
964 ni_bs_reader_get_ue(br); // cpb_size_du_value_minus1
965 ni_bs_reader_get_ue(br); // bit_rate_du_value_minus1
966 }
967 ni_bs_reader_skip_bits(br, 1); // cbr_flag
968 }
969}
970
972{
973 int i;
974
975 if (ni_bs_reader_get_bits_left(br) < 2 + 1 + 5 + 32 + 4 + 43 + 1)
976 return -1;
977
979 ptl->tier_flag = ni_bs_reader_get_bits(br, 1);
981
982 for (i = 0; i < 32; i++)
983 {
985
986 if (ptl->profile_idc == 0 && i > 0 &&
988 ptl->profile_idc = i;
989 }
994
995#define check_profile_idc(idc) \
996 ptl->profile_idc == (idc) || ptl->profile_compatibility_flag[idc]
997
1001 {
1011
1012 if (check_profile_idc(5) || check_profile_idc(9) ||
1014 {
1016 ni_bs_reader_skip_bits(br, 33); // XXX_reserved_zero_33bits[0..32]
1017 } else
1018 {
1019 ni_bs_reader_skip_bits(br, 34); // XXX_reserved_zero_34bits[0..33]
1020 }
1021 } else if (check_profile_idc(2))
1022 {
1025 ni_bs_reader_skip_bits(br, 35); // XXX_reserved_zero_35bits[0..34]
1026 } else
1027 {
1028 ni_bs_reader_skip_bits(br, 43); // XXX_reserved_zero_43bits[0..42]
1029 }
1030
1033 ptl->inbld_flag = ni_bs_reader_get_bits(br, 1);
1034 else
1036#undef check_profile_idc
1037
1038 return 0;
1039}
1040
1041int h265_parse_ptl(ni_bitstream_reader_t *br, PTL *ptl, int max_num_sub_layers)
1042{
1043 int i;
1044 if (h265_decode_profile_tier_level(br, &ptl->general_ptl) < 0 ||
1046 8 + (8 * 2 * (max_num_sub_layers - 1 > 0)))
1047 {
1048 ni_log(NI_LOG_ERROR, "PTL information too short\n");
1049 return -1;
1050 }
1051
1053
1054 if (max_num_sub_layers > HEVC_MAX_SUB_LAYERS)
1055 {
1056 max_num_sub_layers = HEVC_MAX_SUB_LAYERS;
1057 }
1058 for (i = 0; i < max_num_sub_layers - 1; i++)
1059 {
1062 }
1063
1064 if (max_num_sub_layers - 1 > 0)
1065 for (i = max_num_sub_layers - 1; i < 8; i++)
1066 ni_bs_reader_skip_bits(br, 2); // reserved_zero_2bits[i]
1067 for (i = 0; i < max_num_sub_layers - 1; i++)
1068 {
1069 if (ptl->sub_layer_profile_present_flag[i] &&
1071 {
1072 ni_log(NI_LOG_ERROR, "PTL information for sublayer %i too short\n",
1073 i);
1074 return -1;
1075 }
1076 if (ptl->sub_layer_level_present_flag[i])
1077 {
1078 if (ni_bs_reader_get_bits_left(br) < 8)
1079 {
1081 "Not enough data for sublayer %i level_idc\n", i);
1082 return -1;
1083 } else
1085 }
1086 }
1087
1088 return 0;
1089}
1090
1091int h265_decode_hrd(ni_bitstream_reader_t *br, int common_inf_present, int max_sublayers)
1092{
1093 int nal_params_present = 0, vcl_params_present = 0;
1094 int subpic_params_present = 0;
1095 int i;
1096
1097 if (common_inf_present)
1098 {
1099 nal_params_present = ni_bs_reader_get_bits(br, 1);
1100 vcl_params_present = ni_bs_reader_get_bits(br, 1);
1101
1102 if (nal_params_present || vcl_params_present)
1103 {
1104 subpic_params_present = ni_bs_reader_get_bits(br, 1);
1105
1106 if (subpic_params_present)
1107 {
1108 ni_bs_reader_skip_bits(br, 8); // tick_divisor_minus2
1110 br, 5); // du_cpb_removal_delay_increment_length_minus1
1112 br, 1); // sub_pic_cpb_params_in_pic_timing_sei_flag
1114 br, 5); // dpb_output_delay_du_length_minus1
1115 }
1116
1117 ni_bs_reader_skip_bits(br, 4); // bit_rate_scale
1118 ni_bs_reader_skip_bits(br, 4); // cpb_size_scale
1119
1120 if (subpic_params_present)
1121 ni_bs_reader_skip_bits(br, 4); // cpb_size_du_scale
1122
1124 br, 5); // initial_cpb_removal_delay_length_minus1
1126 5); // au_cpb_removal_delay_length_minus1
1127 ni_bs_reader_skip_bits(br, 5); // dpb_output_delay_length_minus1
1128 }
1129 }
1130
1131 for (i = 0; i < max_sublayers; i++)
1132 {
1133 int low_delay = 0;
1134 unsigned int nb_cpb = 1;
1135 int fixed_rate = ni_bs_reader_get_bits(br, 1);
1136
1137 if (!fixed_rate)
1138 fixed_rate = ni_bs_reader_get_bits(br, 1);
1139
1140 if (fixed_rate)
1141 ni_bs_reader_get_ue(br); // elemental_duration_in_tc_minus1
1142 else
1143 low_delay = ni_bs_reader_get_bits(br, 1);
1144
1145 if (!low_delay)
1146 {
1147 nb_cpb = ni_bs_reader_get_ue(br) + 1;
1148 if (nb_cpb < 1 || nb_cpb > 32)
1149 {
1150 ni_log(NI_LOG_ERROR, "nb_cpb %d invalid\n", nb_cpb);
1151 return -1;
1152 }
1153 }
1154
1155 if (nal_params_present)
1156 h265_decode_sublayer_hrd(br, nb_cpb, subpic_params_present);
1157 if (vcl_params_present)
1158 h265_decode_sublayer_hrd(br, nb_cpb, subpic_params_present);
1159 }
1160 return 0;
1161}
1162
1164{
1165 int matrixId;
1166
1167 for (matrixId = 0; matrixId < 6; matrixId++)
1168 {
1169 // 4x4 default is 16
1170 memset(sl->sl[0][matrixId], 16, 16);
1171 sl->sl_dc[0][matrixId] = 16; // default for 16x16
1172 sl->sl_dc[1][matrixId] = 16; // default for 32x32
1173 }
1174 memcpy(sl->sl[1][0], default_scaling_list_intra, 64);
1175 memcpy(sl->sl[1][1], default_scaling_list_intra, 64);
1176 memcpy(sl->sl[1][2], default_scaling_list_intra, 64);
1177 memcpy(sl->sl[1][3], default_scaling_list_inter, 64);
1178 memcpy(sl->sl[1][4], default_scaling_list_inter, 64);
1179 memcpy(sl->sl[1][5], default_scaling_list_inter, 64);
1180 memcpy(sl->sl[2][0], default_scaling_list_intra, 64);
1181 memcpy(sl->sl[2][1], default_scaling_list_intra, 64);
1182 memcpy(sl->sl[2][2], default_scaling_list_intra, 64);
1183 memcpy(sl->sl[2][3], default_scaling_list_inter, 64);
1184 memcpy(sl->sl[2][4], default_scaling_list_inter, 64);
1185 memcpy(sl->sl[2][5], default_scaling_list_inter, 64);
1186 memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
1187 memcpy(sl->sl[3][1], default_scaling_list_intra, 64);
1188 memcpy(sl->sl[3][2], default_scaling_list_intra, 64);
1189 memcpy(sl->sl[3][3], default_scaling_list_inter, 64);
1190 memcpy(sl->sl[3][4], default_scaling_list_inter, 64);
1191 memcpy(sl->sl[3][5], default_scaling_list_inter, 64);
1192}
1193
1195{
1196 uint8_t scaling_list_pred_mode_flag;
1197 int32_t scaling_list_dc_coef[2][6];
1198 int size_id, matrix_id, pos;
1199 int i;
1200
1201 for (size_id = 0; size_id < 4; size_id++)
1202 for (matrix_id = 0; matrix_id < 6;
1203 matrix_id += ((size_id == 3) ? 3 : 1))
1204 {
1205 scaling_list_pred_mode_flag = ni_bs_reader_get_bits(br, 1);
1206 if (!scaling_list_pred_mode_flag)
1207 {
1208 int delta = ni_bs_reader_get_ue(br);
1209 /* Only need to handle non-zero delta. Zero means default,
1210 * which should already be in the arrays. */
1211 if (delta)
1212 {
1213 // Copy from previous array.
1214 delta *= (size_id == 3) ? 3 : 1;
1215 if (matrix_id < delta)
1216 {
1218 "Invalid delta in scaling list data: %d.\n",
1219 delta);
1220 return -1;
1221 }
1222
1223 memcpy(sl->sl[size_id][matrix_id],
1224 sl->sl[size_id][matrix_id - delta],
1225 size_id > 0 ? 64 : 16);
1226 if (size_id > 1)
1227 sl->sl_dc[size_id - 2][matrix_id] =
1228 sl->sl_dc[size_id - 2][matrix_id - delta];
1229 }
1230 } else
1231 {
1232 int32_t next_coef, coef_num;
1233 int32_t scaling_list_delta_coef;
1234
1235 next_coef = 8;
1236 coef_num = 1 << (4 + (size_id << 1));
1237 if (coef_num >= 64)
1238 coef_num = 64;
1239 if (size_id > 1)
1240 {
1241 scaling_list_dc_coef[size_id - 2][matrix_id] =
1242 ni_bs_reader_get_se(br) + 8;
1243 next_coef = scaling_list_dc_coef[size_id - 2][matrix_id];
1244 sl->sl_dc[size_id - 2][matrix_id] = next_coef;
1245 }
1246 for (i = 0; i < coef_num; i++)
1247 {
1248 if (size_id == 0)
1249 pos =
1250 4 * hevc_diag_scan4x4_y[i] + hevc_diag_scan4x4_x[i];
1251 else
1252 pos =
1253 8 * hevc_diag_scan8x8_y[i] + hevc_diag_scan8x8_x[i];
1254
1255 scaling_list_delta_coef = ni_bs_reader_get_se(br);
1256 next_coef =
1257 (next_coef + 256U + scaling_list_delta_coef) % 256;
1258 sl->sl[size_id][matrix_id][pos] = next_coef;
1259 }
1260 }
1261 }
1262
1263 if (sps->chroma_format_idc == 3)
1264 {
1265 for (i = 0; i < 64; i++)
1266 {
1267 sl->sl[3][1][i] = sl->sl[2][1][i];
1268 sl->sl[3][2][i] = sl->sl[2][2][i];
1269 sl->sl[3][4][i] = sl->sl[2][4][i];
1270 sl->sl[3][5][i] = sl->sl[2][5][i];
1271 }
1272 sl->sl_dc[1][1] = sl->sl_dc[0][1];
1273 sl->sl_dc[1][2] = sl->sl_dc[0][2];
1274 sl->sl_dc[1][4] = sl->sl_dc[0][4];
1275 sl->sl_dc[1][5] = sl->sl_dc[0][5];
1276 }
1277
1278 return 0;
1279}
1280
1282 const ni_h265_sps_t *sps, int is_slice_header)
1283{
1284 uint8_t rps_predict = 0;
1285 int32_t delta_poc;
1286 int k0 = 0;
1287 int k1 = 0;
1288 int32_t k = 0;
1289 int i;
1290
1291 if (rps != sps->st_rps && sps->nb_st_rps)
1292 rps_predict = ni_bs_reader_get_bits(br, 1);
1293
1294 if (rps_predict)
1295 {
1296 const ShortTermRPS *rps_ridx;
1297 int32_t delta_rps;
1298 int32_t abs_delta_rps;
1299 uint8_t use_delta_flag = 0;
1300 uint8_t delta_rps_sign;
1301
1302 if (is_slice_header)
1303 {
1304 unsigned int delta_idx = ni_bs_reader_get_ue(br) + 1;
1305 if (delta_idx > sps->nb_st_rps)
1306 {
1308 "Invalid value of delta_idx in slice header RPS: %d > "
1309 "%d.\n",
1310 delta_idx, sps->nb_st_rps);
1311 return -1;
1312 }
1313 rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];
1314 rps->rps_idx_num_delta_pocs = rps_ridx->num_delta_pocs;
1315 } else
1316 rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];
1317
1318 delta_rps_sign = ni_bs_reader_get_bits(br, 1);
1319 abs_delta_rps = (int)(ni_bs_reader_get_ue(br) + 1);
1320 if (abs_delta_rps < 1 || abs_delta_rps > 32768)
1321 {
1322 ni_log(NI_LOG_ERROR, "Invalid value of abs_delta_rps: %d\n",
1323 abs_delta_rps);
1324 return -1;
1325 }
1326 delta_rps = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
1327 for (i = 0; i <= rps_ridx->num_delta_pocs; i++)
1328 {
1329 int used = rps->used[k] = ni_bs_reader_get_bits(br, 1);
1330
1331 if (!used)
1332 use_delta_flag = ni_bs_reader_get_bits(br, 1);
1333
1334 if (used || use_delta_flag)
1335 {
1336 if (i < rps_ridx->num_delta_pocs)
1337 delta_poc = delta_rps + rps_ridx->delta_poc[i];
1338 else
1339 delta_poc = delta_rps;
1340 rps->delta_poc[k] = delta_poc;
1341 if (delta_poc < 0)
1342 k0++;
1343 else
1344 k1++;
1345 k++;
1346 }
1347 }
1348
1349 if (k >= (sizeof(rps->used) / sizeof(rps->used[0])))
1350 {
1351 ni_log(NI_LOG_ERROR, "Invalid num_delta_pocs: %d\n", k);
1352 return -1;
1353 }
1354
1355 rps->num_delta_pocs = k;
1356 rps->num_negative_pics = k0;
1357 // sort in increasing order (smallest first)
1358 if (rps->num_delta_pocs != 0)
1359 {
1360 int used, tmp;
1361 for (i = 1; i < rps->num_delta_pocs; i++)
1362 {
1363 delta_poc = rps->delta_poc[i];
1364 used = rps->used[i];
1365 for (k = i - 1; k >= 0; k--)
1366 {
1367 tmp = rps->delta_poc[k];
1368 if (delta_poc < tmp)
1369 {
1370 rps->delta_poc[k + 1] = tmp;
1371 rps->used[k + 1] = rps->used[k];
1372 rps->delta_poc[k] = delta_poc;
1373 rps->used[k] = used;
1374 }
1375 }
1376 }
1377 }
1378 if ((rps->num_negative_pics >> 1) != 0)
1379 {
1380 int used;
1381 k = rps->num_negative_pics - 1;
1382 // flip the negative values to largest first
1383 for (i = 0; i < (int)(rps->num_negative_pics >> 1); i++)
1384 {
1385 delta_poc = rps->delta_poc[i];
1386 used = rps->used[i];
1387 rps->delta_poc[i] = rps->delta_poc[k];
1388 rps->used[i] = rps->used[k];
1389 rps->delta_poc[k] = delta_poc;
1390 rps->used[k] = used;
1391 k--;
1392 }
1393 }
1394 } else
1395 {
1396 int prev, nb_positive_pics;
1398 nb_positive_pics = ni_bs_reader_get_ue(br);
1399
1400 if (rps->num_negative_pics >= HEVC_MAX_REFS ||
1401 nb_positive_pics >= HEVC_MAX_REFS)
1402 {
1403 ni_log(NI_LOG_ERROR, "Too many refs in a short term RPS.\n");
1404 return -1;
1405 }
1406
1407 rps->num_delta_pocs = (int)(rps->num_negative_pics + nb_positive_pics);
1408 if (rps->num_delta_pocs)
1409 {
1410 prev = 0;
1411 for (i = 0; i < (int)rps->num_negative_pics; i++)
1412 {
1413 delta_poc = ni_bs_reader_get_ue(br) + 1;
1414 if (delta_poc < 1 || delta_poc > 32768)
1415 {
1416 ni_log(NI_LOG_ERROR, "Invalid value of delta_poc: %d\n",
1417 delta_poc);
1418 return -1;
1419 }
1420 prev -= delta_poc;
1421 rps->delta_poc[i] = prev;
1422 rps->used[i] = ni_bs_reader_get_bits(br, 1);
1423 }
1424 prev = 0;
1425 for (i = 0; i < nb_positive_pics; i++)
1426 {
1427 delta_poc = ni_bs_reader_get_ue(br) + 1;
1428 if (delta_poc < 1 || delta_poc > 32768)
1429 {
1430 ni_log(NI_LOG_ERROR, "Invalid value of delta_poc: %d\n",
1431 delta_poc);
1432 return -1;
1433 }
1434 prev += delta_poc;
1435 rps->delta_poc[rps->num_negative_pics + i] = prev;
1436 rps->used[rps->num_negative_pics + i] =
1437 ni_bs_reader_get_bits(br, 1);
1438 }
1439 }
1440 }
1441 return 0;
1442}
1443
1444int h265_decode_vui(ni_bitstream_reader_t *br, int apply_defdispwin, ni_h265_sps_t *sps)
1445{
1446 VUI backup_vui, *vui = &sps->vui;
1447 ni_bitstream_reader_t br_backup;
1448 int sar_present, alt = 0;
1449
1450 sar_present = ni_bs_reader_get_bits(br, 1);
1451 if (sar_present)
1452 {
1453 uint8_t sar_idx = ni_bs_reader_get_bits(br, 8);
1454 if (sar_idx < (sizeof(vui_sar) / sizeof(vui_sar[0])))
1455 vui->sar = vui_sar[sar_idx];
1456 else if (sar_idx == 255)
1457 {
1458 vui->sar.num = ni_bs_reader_get_bits(br, 16);
1459 vui->sar.den = ni_bs_reader_get_bits(br, 16);
1460 } else
1461 {
1462 ni_log(NI_LOG_ERROR, "Unknown SAR Index: %u.\n", sar_idx);
1463 }
1464 }
1465
1469
1472 {
1473 vui->video_format = ni_bs_reader_get_bits(br, 3);
1479 {
1483
1484 if (vui->colour_primaries >= NI_COL_PRI_NB)
1485 {
1487 }
1489 {
1491 }
1492 if (vui->matrix_coeffs >= NI_COL_SPC_NB)
1493 {
1495 }
1496 if (vui->matrix_coeffs == NI_COL_SPC_RGB)
1497 {
1498 if (sps->pix_fmt)
1499 {
1501 "Invalid format, only support yuv420p\n");
1502 return -1;
1503 }
1504 }
1505 }
1506 }
1507
1510 {
1513 }
1514
1518
1519 // Backup context in case an alternate header is detected
1520 memcpy(&br_backup, br, sizeof(br_backup));
1521 memcpy(&backup_vui, vui, sizeof(backup_vui));
1523
1525 {
1526 int vert_mult = hevc_sub_height_c[sps->chroma_format_idc];
1527 int horiz_mult = hevc_sub_width_c[sps->chroma_format_idc];
1528 vui->def_disp_win.left_offset = ni_bs_reader_get_ue(br) * horiz_mult;
1529 vui->def_disp_win.right_offset = ni_bs_reader_get_ue(br) * horiz_mult;
1530 vui->def_disp_win.top_offset = ni_bs_reader_get_ue(br) * vert_mult;
1531 vui->def_disp_win.bottom_offset = ni_bs_reader_get_ue(br) * vert_mult;
1532
1533 if (apply_defdispwin)
1534 {
1536 "discarding vui default display window, "
1537 "original values are l:%u r:%u t:%u b:%u\n",
1541
1544 0;
1545 }
1546 }
1547
1548timing_info:
1550
1552 {
1553 if (ni_bs_reader_get_bits_left(br) < 66 && !alt)
1554 {
1555 // The alternate syntax seem to have timing info located
1556 // at where def_disp_win is normally located
1558 "Strange VUI timing information, retrying...\n");
1559 memcpy(vui, &backup_vui, sizeof(backup_vui));
1560 memcpy(br, &br_backup, sizeof(br_backup));
1561 alt = 1;
1562 goto timing_info;
1563 }
1566 if (alt)
1567 {
1568 ni_log(NI_LOG_INFO, "Retry got %u/%ufps\n", vui->vui_time_scale,
1570 }
1576 h265_decode_hrd(br, 1, sps->max_sub_layers);
1577 }
1578
1581 {
1582 if (ni_bs_reader_get_bits_left(br) < 8 && !alt)
1583 {
1585 "Strange VUI bitstream restriction information, retrying"
1586 " from timing information...\n");
1587 memcpy(vui, &backup_vui, sizeof(backup_vui));
1588 memcpy(br, &br_backup, sizeof(br_backup));
1589 alt = 1;
1590 goto timing_info;
1591 }
1594 ni_bs_reader_get_bits(br, 1);
1601 }
1602
1603 if (ni_bs_reader_get_bits_left(br) < 1 && !alt)
1604 {
1606 "Overread in VUI, retrying from timing information...\n");
1607 memcpy(vui, &backup_vui, sizeof(backup_vui));
1608 memcpy(br, &br_backup, sizeof(br_backup));
1609 alt = 1;
1610 goto timing_info;
1611 }
1612 return 0;
1613}
1614
1615int h265_parse_sps(ni_h265_sps_t *sps, uint8_t *buf, int size_bytes)
1616{
1617 ni_h265_window_t *ow;
1618 int ret = 0;
1619 int log2_diff_max_min_transform_block_size;
1620 int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
1621 int i;
1622
1624 uint32_t sps_id;
1625 ni_bitstream_reader_init(&br, buf, 8 * size_bytes);
1626
1627 ni_bs_reader_skip_bits(&br, 16); // skip NAL header
1628
1629 sps->vps_id = ni_bs_reader_get_bits(&br, 4);
1630
1631 sps->max_sub_layers = (int)ni_bs_reader_get_bits(&br, 3) + 1;
1633 {
1634 ni_log(NI_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",
1635 sps->max_sub_layers);
1636 return -1;
1637 }
1638
1640
1641 if ((ret = h265_parse_ptl(&br, &sps->ptl, sps->max_sub_layers)) < 0)
1642 return ret;
1643
1644 sps_id = ni_bs_reader_get_ue(&br);
1645 if (sps_id >= HEVC_MAX_SPS_COUNT)
1646 {
1647 ni_log(NI_LOG_ERROR, "SPS id out of range: %d\n", sps_id);
1648 return -1;
1649 }
1650
1652 if (sps->chroma_format_idc > 3U)
1653 {
1654 ni_log(NI_LOG_ERROR, "chroma_format_idc %d is invalid\n",
1655 sps->chroma_format_idc);
1656 return -1;
1657 }
1658
1659 if (sps->chroma_format_idc == 3)
1661
1663 sps->chroma_format_idc = 0;
1664
1665 sps->width = (int)ni_bs_reader_get_ue(&br);
1666 sps->height = (int)ni_bs_reader_get_ue(&br);
1667
1668 if (ni_bs_reader_get_bits(&br, 1))
1669 { // pic_conformance_flag
1670 int vert_mult = hevc_sub_height_c[sps->chroma_format_idc];
1671 int horiz_mult = hevc_sub_width_c[sps->chroma_format_idc];
1672 sps->pic_conf_win.left_offset = ni_bs_reader_get_ue(&br) * horiz_mult;
1673 sps->pic_conf_win.right_offset = ni_bs_reader_get_ue(&br) * horiz_mult;
1674 sps->pic_conf_win.top_offset = ni_bs_reader_get_ue(&br) * vert_mult;
1675 sps->pic_conf_win.bottom_offset = ni_bs_reader_get_ue(&br) * vert_mult;
1676
1677 sps->output_window = sps->pic_conf_win;
1678 }
1679
1680 sps->bit_depth = (int)(ni_bs_reader_get_ue(&br) + 8);
1681 bit_depth_chroma = (int)(ni_bs_reader_get_ue(&br) + 8);
1682 if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth)
1683 {
1685 "Luma bit depth (%d) is different from chroma bit depth (%d), "
1686 "this is unsupported.\n",
1687 sps->bit_depth, bit_depth_chroma);
1688 return -1;
1689 }
1690 sps->bit_depth_chroma = bit_depth_chroma;
1691 if (((sps->bit_depth != 8) && (sps->bit_depth != 10)) ||
1692 (sps->chroma_format_idc != 1))
1693 {
1695 "only support 8bit/10bit yuv420p, bit_depth %d, "
1696 "chroma_format_idc %d\n",
1697 sps->bit_depth, sps->chroma_format_idc);
1698 return -1;
1699 }
1700 sps->pix_fmt = 0;
1701 sps->hshift[0] = sps->vshift[0] = 0;
1702 sps->hshift[2] = sps->hshift[1] = 1;
1703 sps->vshift[2] = sps->vshift[1] = 1;
1704 sps->pixel_shift = sps->bit_depth > 8;
1705
1706 sps->log2_max_poc_lsb = ni_bs_reader_get_ue(&br) + 4;
1707 if (sps->log2_max_poc_lsb > 16)
1708 {
1710 "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",
1711 sps->log2_max_poc_lsb - 4);
1712 return -1;
1713 }
1714
1715 sublayer_ordering_info = ni_bs_reader_get_bits(&br, 1);
1716 start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;
1717 for (i = start; i < sps->max_sub_layers; i++)
1718 {
1720 (int)(ni_bs_reader_get_ue(&br) + 1);
1723 (int)(ni_bs_reader_get_ue(&br) - 1);
1724 if (sps->temporal_layer[i].num_reorder_pics >
1726 {
1727 ni_log(NI_LOG_ERROR, "sps_max_num_reorder_pics out of range: %d\n",
1730 sps->temporal_layer[i].num_reorder_pics + 1;
1731 }
1732 }
1733
1734 if (!sublayer_ordering_info)
1735 {
1736 for (i = 0; i < start; i++)
1737 {
1741 sps->temporal_layer[start].num_reorder_pics;
1744 }
1745 }
1746
1747 sps->log2_min_cb_size = ni_bs_reader_get_ue(&br) + 3;
1749 sps->log2_min_tb_size = ni_bs_reader_get_ue(&br) + 2;
1750 log2_diff_max_min_transform_block_size = ni_bs_reader_get_ue(&br);
1751 sps->log2_max_trafo_size =
1752 log2_diff_max_min_transform_block_size + sps->log2_min_tb_size;
1753
1754 if (sps->log2_min_cb_size < 3 || sps->log2_min_cb_size > 30)
1755 {
1756 ni_log(NI_LOG_ERROR, "Invalid value %d for log2_min_cb_size",
1757 sps->log2_min_cb_size);
1758 return -1;
1759 }
1760
1762 {
1764 "Invalid value %d for log2_diff_max_min_coding_block_size",
1766 return -1;
1767 }
1768
1769 if (sps->log2_min_tb_size >= sps->log2_min_cb_size ||
1770 sps->log2_min_tb_size < 2)
1771 {
1772 ni_log(NI_LOG_ERROR, "Invalid value for log2_min_tb_size");
1773 return -1;
1774 }
1775
1776 if (log2_diff_max_min_transform_block_size < 0 ||
1777 log2_diff_max_min_transform_block_size > 30)
1778 {
1780 "Invalid value %d for log2_diff_max_min_transform_block_size",
1781 log2_diff_max_min_transform_block_size);
1782 return -1;
1783 }
1784
1787
1789 if (sps->scaling_list_enable_flag)
1790 {
1792
1793 if (ni_bs_reader_get_bits(&br, 1))
1794 {
1795 ret = h265_scaling_list_data(&br, &sps->scaling_list, sps);
1796 if (ret < 0)
1797 return ret;
1798 }
1799 }
1800
1802 sps->sao_enabled = ni_bs_reader_get_bits(&br, 1);
1803
1805 if (sps->pcm_enabled_flag)
1806 {
1807 sps->pcm.bit_depth = ni_bs_reader_get_bits(&br, 4) + 1;
1808 sps->pcm.bit_depth_chroma = ni_bs_reader_get_bits(&br, 4) + 1;
1812 if ((sps->pcm.bit_depth > sps->bit_depth) ||
1813 (sps->pcm.bit_depth_chroma > sps->bit_depth))
1814 {
1816 "PCM bit depth (%d, %d) is greater than normal bit depth "
1817 "(%d)\n",
1818 sps->pcm.bit_depth, sps->pcm.bit_depth_chroma,
1819 sps->bit_depth);
1820 return -1;
1821 }
1822
1824 }
1825
1826 sps->nb_st_rps = ni_bs_reader_get_ue(&br);
1828 {
1829 ni_log(NI_LOG_ERROR, "Too many short term RPS: %d.\n", sps->nb_st_rps);
1830 return -1;
1831 }
1832 for (i = 0; i < (int)sps->nb_st_rps; i++)
1833 {
1834 if ((ret = h265_decode_short_term_rps(&br, &sps->st_rps[i], sps, 0)) <
1835 0)
1836 return ret;
1837 }
1838
1841 {
1844 {
1845 ni_log(NI_LOG_ERROR, "Too many long term ref pics: %d.\n",
1847 return -1;
1848 }
1849 for (i = 0; i < sps->num_long_term_ref_pics_sps; i++)
1850 {
1851 sps->lt_ref_pic_poc_lsb_sps[i] =
1854 ni_bs_reader_get_bits(&br, 1);
1855 }
1856 }
1857
1860 sps->vui.sar = (ni_rational_t){0, 1};
1861 vui_present = ni_bs_reader_get_bits(&br, 1);
1862 if (vui_present)
1863 h265_decode_vui(&br, 0, sps);
1864
1865 if (ni_bs_reader_get_bits(&br, 1))
1866 { // sps_extension_flag
1869 &br, 7); //sps_extension_7bits = ni_bs_reader_get_bits(br, 7);
1870 if (sps->sps_range_extension_flag)
1871 {
1873 ni_bs_reader_get_bits(&br, 1);
1875 ni_bs_reader_get_bits(&br, 1);
1877
1879
1881 ni_bs_reader_get_bits(&br, 1);
1883 ni_log(
1885 "extended_precision_processing_flag not yet implemented\n");
1886
1889 ni_bs_reader_get_bits(&br, 1);
1892 "high_precision_offsets_enabled_flag not yet "
1893 "implemented\n");
1894
1896 ni_bs_reader_get_bits(&br, 1);
1897
1899 ni_bs_reader_get_bits(&br, 1);
1902 "cabac_bypass_alignment_enabled_flag not yet "
1903 "implemented\n");
1904 }
1905 }
1906
1907 ow = &sps->output_window;
1908 if (ow->left_offset >= INT32_MAX - ow->right_offset ||
1909 ow->top_offset >= INT32_MAX - ow->bottom_offset ||
1910 ow->left_offset + ow->right_offset >= (uint32_t)sps->width ||
1911 ow->top_offset + ow->bottom_offset >= (uint32_t)sps->height)
1912 {
1913 ni_log(NI_LOG_INFO, "Invalid cropping offsets: %u/%u/%u/%u\n",
1914 ow->left_offset, ow->right_offset, ow->top_offset,
1915 ow->bottom_offset);
1916 ni_log(NI_LOG_INFO, "Displaying the whole video surface.\n");
1917 memset(ow, 0, sizeof(*ow));
1918 memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win));
1919 }
1920
1921 // Inferred parameters
1922 sps->log2_ctb_size =
1924 sps->log2_min_pu_size = sps->log2_min_cb_size - 1;
1925
1927 {
1928 ni_log(NI_LOG_ERROR, "CTB size out of range: 2^%d\n",
1929 sps->log2_ctb_size);
1930 return -1;
1931 }
1932 if (sps->log2_ctb_size < 4)
1933 {
1934 ni_log(
1936 "log2_ctb_size %d differs from the bounds of any known profile\n",
1937 sps->log2_ctb_size);
1938 return -1;
1939 }
1940
1941 sps->ctb_width =
1942 (sps->width + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
1943 sps->ctb_height =
1944 (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
1945 sps->ctb_size = sps->ctb_width * sps->ctb_height;
1946
1947 sps->min_cb_width = sps->width >> sps->log2_min_cb_size;
1948 sps->min_cb_height = sps->height >> sps->log2_min_cb_size;
1949 sps->min_tb_width = sps->width >> sps->log2_min_tb_size;
1950 sps->min_tb_height = sps->height >> sps->log2_min_tb_size;
1951 sps->min_pu_width = sps->width >> sps->log2_min_pu_size;
1952 sps->min_pu_height = sps->height >> sps->log2_min_pu_size;
1953 sps->tb_mask = (1 << (sps->log2_ctb_size - sps->log2_min_tb_size)) - 1;
1954
1955 sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
1956
1957 if ((sps->width & ((1U << sps->log2_min_cb_size) - 1)) ||
1958 (sps->height & ((1U << sps->log2_min_cb_size) - 1)))
1959 {
1960 ni_log(NI_LOG_ERROR, "Invalid coded frame dimensions.\n");
1961 return -1;
1962 }
1963
1965 (int)(sps->log2_ctb_size - sps->log2_min_tb_size))
1966 {
1968 "max_transform_hierarchy_depth_inter out of range: %d\n",
1970 return -1;
1971 }
1973 (int)(sps->log2_ctb_size - sps->log2_min_tb_size))
1974 {
1976 "max_transform_hierarchy_depth_intra out of range: %d\n",
1978 return -1;
1979 }
1980 if ((sps->log2_max_trafo_size > sps->log2_ctb_size) &&
1981 (sps->log2_max_trafo_size > 5))
1982 {
1983 ni_log(NI_LOG_ERROR, "max transform block size out of range: %d\n",
1984 sps->log2_max_trafo_size);
1985 return -1;
1986 }
1987 if (ni_bs_reader_get_bits_left(&br) < 0)
1988 {
1989 ni_log(NI_LOG_ERROR, "Overread SPS by %d bits\n",
1991 return -1;
1992 }
1993
1994 return 0;
1995}
1996
1997// probe h.265 stream info; return 0 if stream can be decoded, -1 otherwise
1999{
2000 int ret = -1;
2001 uint8_t *buf = NULL;
2002 uint8_t *p_buf;
2003 uint32_t nal_size, ep3_removed = 0, vcl_nal_count = 0;
2004 int nal_type = -1;
2005 int sps_parsed = 0;
2006
2007 if (NULL == (buf = calloc(1, NI_MAX_TX_SZ)))
2008 {
2010 "Error probe_h265_stream_info: allocate stream buf failed\n");
2011 goto end;
2012 }
2013
2014 reset_data_buf_pos(p_ctx);
2015 // probe at most 100 VCL before stops
2016 while ((!sps_parsed) && vcl_nal_count < 100 &&
2017 (nal_size = (uint32_t)find_h265_next_nalu(p_ctx, buf, &nal_type)) > 0)
2018 {
2019 p_buf = buf;
2020
2021 // skip the start code
2022 while (!(p_buf[0] == 0x00 && p_buf[1] == 0x00 && p_buf[2] == 0x01) &&
2023 (nal_size > 3))
2024 {
2025 p_buf++;
2026 nal_size--;
2027 }
2028 if (nal_size <= 3)
2029 {
2031 "Error probe_h265_stream_info NAL has no header\n");
2032 continue;
2033 }
2034
2035 p_buf += 3; // skip start code
2036 nal_size -= 3;
2037 ep3_removed = ni_remove_emulation_prevent_bytes(p_buf, nal_size);
2038 nal_size -= ep3_removed;
2039 ni_log(NI_LOG_DEBUG, "nal %d nal_size %d\n", nal_type, nal_size);
2040
2041 if (HEVC_NAL_SPS == nal_type && !sps_parsed)
2042 {
2043 if (vcl_nal_count > 0)
2044 {
2046 "Warning: %s has %d slice NAL units ahead of SPS!\n",
2047 __func__, vcl_nal_count);
2048 }
2049
2050 if (h265_parse_sps(sps, p_buf, nal_size))
2051 {
2053 "probe_h265_stream_info: parse_sps error\n");
2054 break;
2055 }
2056 sps_parsed = 1;
2057 } else if (nal_type < 32)
2058 {
2059 vcl_nal_count++;
2060 }
2061 }
2062
2063 reset_data_buf_pos(p_ctx);
2064 if (sps_parsed)
2065 {
2066 ret = 0;
2067 } else
2068 {
2069 ni_log(NI_LOG_ERROR, "probing failed.\n");
2070 }
2071
2072end:
2073 free(buf);
2074 buf = NULL;
2075 return ret;
2076}
2077
2078uint64_t find_vp9_next_packet(ni_demo_context_t *p_ctx, uint8_t *p_dst, ni_vp9_header_info_t *vp9_info)
2079{
2080 uint64_t data_size;
2081 uint64_t i = p_ctx->curr_file_offset ? p_ctx->curr_file_offset : vp9_info->header_length;
2082 if (i + 12 >= p_ctx->total_file_size)
2083 {
2084 ni_log(NI_LOG_DEBUG, "%s reaching end, curr_pos %llu, total input size %llu\n",
2085 __func__, (unsigned long long)p_ctx->curr_file_offset, (unsigned long long)p_ctx->total_file_size);
2086
2087 if (p_ctx->loops_left > 1)
2088 {
2089 p_ctx->loops_left--;
2090 ni_log(NI_LOG_DEBUG, "input processed, %d loops left\n", p_ctx->loops_left);
2091 reset_data_buf_pos(p_ctx);
2092 i = vp9_info->header_length;
2093 } else {
2094 return 0;
2095 }
2096 }
2102 data_size =
2103 ((p_ctx->file_cache[i]) + (p_ctx->file_cache[i + 1] << 8) +
2104 (p_ctx->file_cache[i + 2] << 16) + (p_ctx->file_cache[i + 3] << 24));
2105 ni_log(NI_LOG_DEBUG, "vp9 packet data_size %u\n", data_size);
2106 i += 12;
2107
2108 if (i + data_size > p_ctx->total_file_size)
2109 {
2110 data_size = p_ctx->total_file_size - i;
2111 memcpy(p_dst, &p_ctx->file_cache[i], data_size);
2112 p_ctx->curr_file_offset = p_ctx->total_file_size;
2113 return data_size;
2114 }
2115
2116 memcpy(p_dst, &p_ctx->file_cache[i], data_size);
2117 p_ctx->curr_file_offset = i + data_size; // point to the start of data packet
2118 return data_size;
2119}
2120
2121int vp9_parse_header(ni_vp9_header_info_t *vp9_info, uint8_t *buf, int size_bytes)
2122{
2124 ni_bitstream_reader_init(&br, buf, 8 * size_bytes);
2125
2126 ni_bs_reader_skip_bits(&br, 32); // skip signature
2127 ni_bs_reader_skip_bits(&br, 16); // skip version
2128
2129 vp9_info->header_length = ni_bs_reader_get_bits(&br, 8);
2130 vp9_info->header_length |= ni_bs_reader_get_bits(&br, 8) << 8;
2131
2132 ni_bs_reader_skip_bits(&br, 32); // skip codec fucc
2133
2134 vp9_info->width = ni_bs_reader_get_bits(&br, 8);
2135 vp9_info->width |= ni_bs_reader_get_bits(&br, 8) << 8;
2136
2137 vp9_info->height = ni_bs_reader_get_bits(&br, 8);
2138 vp9_info->height |= ni_bs_reader_get_bits(&br, 8) << 8;
2139
2140 vp9_info->timebase.den = ni_bs_reader_get_bits(&br, 8);
2141 vp9_info->timebase.den |= ni_bs_reader_get_bits(&br, 8) << 8;
2142 vp9_info->timebase.den |= ni_bs_reader_get_bits(&br, 8) << 16;
2143 vp9_info->timebase.den |= ni_bs_reader_get_bits(&br, 8) << 24;
2144
2145 vp9_info->timebase.num = ni_bs_reader_get_bits(&br, 8);
2146 vp9_info->timebase.num |= ni_bs_reader_get_bits(&br, 8) << 8;
2147 vp9_info->timebase.num |= ni_bs_reader_get_bits(&br, 8) << 16;
2148 vp9_info->timebase.num |= ni_bs_reader_get_bits(&br, 8) << 24;
2149
2150 vp9_info->total_frames = ni_bs_reader_get_bits(&br, 8);
2151 vp9_info->total_frames |= ni_bs_reader_get_bits(&br, 8) << 8;
2152 vp9_info->total_frames |= ni_bs_reader_get_bits(&br, 8) << 16;
2153 vp9_info->total_frames |= ni_bs_reader_get_bits(&br, 8) << 24;
2154
2155 if (vp9_info->header_length != 32)
2156 {
2157 ni_log(NI_LOG_ERROR, "Parse faled: header_length %d != 32\n",
2158 vp9_info->header_length);
2159 return -1;
2160 }
2161 ni_bs_reader_skip_bits(&br, 32); // unused bytes
2162 // here we skip frame header(12 bytes) to get profile
2163 ni_bs_reader_skip_bits(&br, 8 * 12);
2164 if (ni_bs_reader_get_bits(&br, 2) != 0x2) // frame marker
2165 {
2166 ni_log(NI_LOG_ERROR, "Invalid frame marker\n");
2167 return -1;
2168 }
2169 int profile = 0;
2170 profile = ni_bs_reader_get_bits(&br, 1);
2171 profile |= ni_bs_reader_get_bits(&br, 1) << 1;
2172 if ((profile != 0) && (profile != 2))
2173 {
2174 ni_log(
2176 "Only support profile0(yuv420,8bit) and profile2(yuv420, 10bit)\n");
2177 return -1;
2178 }
2179 vp9_info->profile = profile;
2180 return 0;
2181}
2182
2183// probe vp9 stream info; return 0 if stream can be decoded, -1 otherwise
2185{
2186 int ret = -1;
2187 uint8_t *buf = NULL;
2188
2189 if (NULL == (buf = calloc(1, 64)))
2190 {
2192 "Error probe_vp9_stream_info: allocate stream buf failed\n");
2193 goto end;
2194 }
2195
2196 reset_data_buf_pos(p_ctx);
2197 uint32_t size_bytes = 64;
2198 if (32 + 12 + 1 >= p_ctx->total_file_size)
2199 {
2200 ni_log(NI_LOG_ERROR, "No frame data probed!\n");
2201 goto end;
2202 } else
2203 {
2204 if (size_bytes > p_ctx->total_file_size)
2205 size_bytes = (uint32_t)p_ctx->total_file_size;
2206 memcpy(buf, &p_ctx->file_cache[p_ctx->curr_file_offset], size_bytes);
2207 }
2208
2209 ret = vp9_parse_header(vp9_info, buf, size_bytes);
2210 if (ret)
2211 {
2212 ni_log(NI_LOG_ERROR, "Failed to parse vp9 header info\n");
2213 goto end;
2214 }
2215 reset_data_buf_pos(p_ctx);
2216 // packets data starts after ivf file header
2217 p_ctx->curr_file_offset += vp9_info->header_length;
2218
2219end:
2220 free(buf);
2221 buf = NULL;
2222 return ret;
2223}
2224
2225/*!*****************************************************************************
2226 * \brief Send decoder input data
2227 *
2228 * \param
2229 *
2230 * \return
2231 ******************************************************************************/
2233 ni_session_data_io_t *p_in_data,
2234 int input_video_width, int input_video_height,
2235 void *stream_info)
2236{
2237 static uint8_t tmp_buf[NI_MAX_TX_SZ];
2238 uint8_t *tmp_buf_ptr = tmp_buf;
2239 int packet_size;
2240 uint32_t frame_pkt_size = 0, nal_size;
2241 int nal_type = -1;
2242 int tx_size = 0;
2243 uint32_t send_size = 0;
2244 int new_packet = 0;
2245 int32_t frame_num = -1, curr_frame_num;
2246 unsigned int first_mb_in_slice = 0;
2247 ni_packet_t *p_in_pkt = &(p_in_data->data.packet);
2248
2249 ni_log(NI_LOG_DEBUG, "===> decoder_send_data <===\n");
2250
2251 if (p_ctx->dec_eos_sent)
2252 {
2253 ni_log(NI_LOG_DEBUG, "decoder_send_data: ALL data (incl. eos) sent "
2254 "already!\n");
2256 }
2257
2258 if (0 == p_in_pkt->data_len)
2259 {
2260 memset(p_in_pkt, 0, sizeof(ni_packet_t));
2261
2262 if (NI_CODEC_FORMAT_H264 == p_dec_ctx->codec_format)
2263 {
2264 ni_h264_sps_t *sps;
2265 sps = (ni_h264_sps_t *)stream_info;
2266 // send whole encoded packet which ends with a slice NAL
2267 while ((nal_size = (uint32_t)find_h264_next_nalu(p_ctx, tmp_buf_ptr, &nal_type)) > 0)
2268 {
2269 frame_pkt_size += nal_size;
2270 tmp_buf_ptr += nal_size;
2271 ni_log(NI_LOG_DEBUG, "%s nal %d nal_size %d\n", __func__,
2272 nal_type, nal_size);
2273
2274 if (H264_NAL_SLICE == nal_type ||
2275 H264_NAL_IDR_SLICE == nal_type)
2276 {
2277 if (!parse_h264_slice_header(tmp_buf_ptr - nal_size,
2278 nal_size, sps, &curr_frame_num,
2279 &first_mb_in_slice))
2280 {
2281 if (-1 == frame_num)
2282 {
2283 // first slice, continue to check
2284 frame_num = curr_frame_num;
2285 } else if (curr_frame_num != frame_num ||
2286 0 == first_mb_in_slice)
2287 {
2288 // this slice has diff. frame_num or first_mb_in_slice addr is
2289 // 0: not the same frame and return
2290 rewind_data_buf_pos_by(p_ctx, nal_size);
2291 frame_pkt_size -= nal_size;
2292 break;
2293 }
2294 // this slice is in the same frame, so continue to check and see
2295 // if there is more
2296 } else
2297 {
2299 "decoder_send_data: parse_slice_header error "
2300 "NAL type %d size %u, continue\n",
2301 nal_type, nal_size);
2302 }
2303 } else if (-1 != frame_num)
2304 {
2305 // already got a slice and this is non-slice NAL: return
2306 rewind_data_buf_pos_by(p_ctx, nal_size);
2307 frame_pkt_size -= nal_size;
2308 break;
2309 }
2310 // otherwise continue until a slice is found
2311 } // while there is still NAL
2312 } else if (NI_CODEC_FORMAT_H265 == p_dec_ctx->codec_format)
2313 {
2314 while ((nal_size = (uint32_t)find_h265_next_nalu(p_ctx, tmp_buf_ptr, &nal_type)) > 0)
2315 {
2316 frame_pkt_size += nal_size;
2317 tmp_buf_ptr += nal_size;
2318 ni_log(NI_LOG_DEBUG, "%s nal_type %d nal_size %d\n", __func__,
2319 nal_type, nal_size);
2320
2321 if (nal_type >= 0 && nal_type <= 23) // vcl units
2322 {
2323 ni_log(NI_LOG_DEBUG, "%s send vcl_nal %d nal_size %d\n",
2324 __func__, nal_type, nal_size);
2325 break;
2326 }
2327 }
2328 } else if (NI_CODEC_FORMAT_VP9 == p_dec_ctx->codec_format)
2329 {
2330 while ((packet_size = (uint32_t)find_vp9_next_packet(p_ctx, tmp_buf_ptr, stream_info)) > 0)
2331 {
2332 frame_pkt_size += packet_size;
2333 ni_log(NI_LOG_DEBUG, "%s vp9 packet_size %d\n", __func__,
2334 packet_size);
2335 break;
2336 }
2337 } else {
2338 ni_log(NI_LOG_ERROR, "Error: Unsupported codec format %u", p_dec_ctx->codec_format);
2340 }
2341 ni_log(NI_LOG_DEBUG, "decoder_send_data * frame_pkt_size %d\n",
2342 frame_pkt_size);
2343
2344 p_in_pkt->p_data = NULL;
2345 send_size = frame_pkt_size + p_dec_ctx->prev_size;
2346 if (send_size > 0)
2347 {
2348 ni_packet_buffer_alloc(p_in_pkt, (int)send_size);
2349 }
2350 p_in_pkt->data_len = send_size;
2351 new_packet = 1;
2352 } else
2353 {
2354 send_size = p_in_pkt->data_len;
2355 }
2356
2357 p_in_pkt->start_of_stream = 0;
2358 if (!p_ctx->dec_sos_sent)
2359 {
2360 p_in_pkt->start_of_stream = 1;
2361 p_ctx->dec_sos_sent = 1;
2362 }
2363 p_in_pkt->end_of_stream = 0;
2364 p_in_pkt->video_width = input_video_width;
2365 p_in_pkt->video_height = input_video_height;
2366
2367 if (send_size == 0)
2368 {
2369 if (p_ctx->curr_file_offset)
2370 {
2371 p_in_pkt->end_of_stream = 1;
2372 ni_log(NI_LOG_ERROR, "Sending eos\n");
2373 }
2374 } else
2375 {
2376 if (new_packet)
2377 {
2378 ni_packet_copy(p_in_pkt->p_data, tmp_buf, frame_pkt_size,
2379 p_dec_ctx->p_leftover, &p_dec_ctx->prev_size);
2380 }
2381 }
2382
2383 tx_size =
2384 ni_device_session_write(p_dec_ctx, p_in_data, NI_DEVICE_TYPE_DECODER);
2385
2386 if (tx_size < 0)
2387 {
2388 // Error
2389 ni_log(NI_LOG_ERROR, "Error: sending data error. rc:%d\n", tx_size);
2391 } else if (tx_size == 0 && !p_dec_ctx->ready_to_close)
2392 {
2393 ni_log(NI_LOG_DEBUG, "0 byte sent this time, return EAGAIN to retry.\n");
2395 }
2396
2397 p_ctx->dec_total_bytes_sent += tx_size;
2398
2399 if (p_dec_ctx->ready_to_close)
2400 {
2401 p_ctx->dec_eos_sent = 1;
2402 }
2403
2404 if (tx_size > 0)
2405 {
2406 ni_log(NI_LOG_DEBUG, "decoder_send_data: reset packet_buffer.\n");
2407 ni_packet_buffer_free(p_in_pkt);
2408 }
2409
2411}
2412
2413/*!*****************************************************************************
2414 * \brief Receive decoded output data from decoder
2415 *
2416 * \param
2417 *
2418 * \return 0: got YUV frame; 1: end-of-stream; 2: got nothing
2419 ******s************************************************************************/
2421 ni_session_data_io_t *p_out_data,
2422 int output_video_width, int output_video_height,
2423 FILE *p_file, int write_to_file,
2424 int * p_rx_size)
2425{
2426 int rc = NI_RETCODE_FAILURE;
2427 int rx_size = 0;
2428 bool b_is_hwframe = p_dec_ctx->hw_action;
2429 ni_frame_t *p_out_frame = &(p_out_data->data.frame);
2430 ni_session_data_io_t hwdl_session_data = {0};
2431 int width, height;
2432 // In decoder session read function it will allocate the actual YUV
2433 // transfer size for the very first read. And the pixel format of session
2434 // context would be set as well. So it does not matter with the planar
2435 // format for the first call of this function.
2436 int is_planar = get_pixel_planar(p_dec_ctx->pixel_format) == NI_PIXEL_PLANAR_FORMAT_PLANAR;
2437
2439 "===> decoder_receive_data hwframe %d pixel_format %d <===\n",
2440 b_is_hwframe, p_dec_ctx->pixel_format);
2441
2442 if (p_ctx->dec_eos_received)
2443 {
2444 ni_log(NI_LOG_DEBUG, "decoder_receive_data eos received already, Done!\n");
2446 goto end;
2447 }
2448
2449 // prepare memory buffer for receiving decoded frame
2450 width = p_dec_ctx->actual_video_width > 0 ?
2451 (int)(p_dec_ctx->actual_video_width) :
2452 output_video_width;
2453 height = p_dec_ctx->active_video_height > 0 ?
2454 (int)(p_dec_ctx->active_video_height) :
2455 output_video_height;
2456
2457 // allocate memory only after resolution is known (for buffer pool set up)
2458 int alloc_mem = (p_dec_ctx->active_video_width > 0 &&
2459 p_dec_ctx->active_video_height > 0 ?
2460 1 :
2461 0);
2462 if (!b_is_hwframe)
2463 {
2465 p_dec_ctx->dec_fme_buf_pool, &(p_out_data->data.frame), alloc_mem,
2466 width, height, p_dec_ctx->codec_format == NI_CODEC_FORMAT_H264,
2467 p_dec_ctx->bit_depth_factor, is_planar);
2468 if (NI_RETCODE_SUCCESS != rc)
2469 {
2471 goto end;
2472 }
2473 rx_size = ni_device_session_read(p_dec_ctx, p_out_data,
2475 } else
2476 {
2478 &(p_out_data->data.frame), width, height,
2479 p_dec_ctx->codec_format == NI_CODEC_FORMAT_H264, 1,
2480 p_dec_ctx->bit_depth_factor,
2481 3 /*3 is max supported hwframe output count per frame*/, is_planar);
2482 if (NI_RETCODE_SUCCESS != rc)
2483 {
2485 goto end;
2486 }
2487 rx_size = ni_device_session_read_hwdesc(p_dec_ctx, p_out_data,
2489 }
2490
2491 // the actual pix_fmt is known and updated in ctx only after the first
2492 // frame is decoded, so check/update it here again to be used below
2493 is_planar = get_pixel_planar(p_dec_ctx->pixel_format) ==
2495
2496 if (rx_size < 0)
2497 {
2498 ni_log(NI_LOG_ERROR, "Error: receiving data error. rc:%d\n", rx_size);
2499 if (!b_is_hwframe)
2500 {
2501 ni_decoder_frame_buffer_free(p_out_frame);
2502 } else
2503 {
2504 ni_frame_buffer_free(p_out_frame);
2505 }
2507 goto end;
2508 } else if (rx_size > 0)
2509 {
2510 p_ctx->num_frames_received++;
2511 ni_log(NI_LOG_DEBUG, "Got frame # %" PRIu64 " bytes %d\n",
2512 p_dec_ctx->frame_num, rx_size);
2513
2514 ni_dec_retrieve_aux_data(p_out_frame);
2515
2516 if (p_file && write_to_file) {
2517 if (p_dec_ctx->hw_action == NI_CODEC_HW_ENABLE)
2518 {
2519 rc = hwdl_frame(p_dec_ctx, &hwdl_session_data, p_out_frame, p_dec_ctx->pixel_format);
2520 if (rc <= 0) {
2522 goto end;
2523 }
2524 rc = write_rawvideo_data(p_file, p_dec_ctx->active_video_width, p_dec_ctx->active_video_height,
2525 output_video_width, output_video_height, p_dec_ctx->pixel_format,
2526 &hwdl_session_data.data.frame);
2527 ni_frame_buffer_free(&hwdl_session_data.data.frame);
2528 } else
2529 {
2530 rc = write_rawvideo_data(p_file, p_dec_ctx->active_video_width, p_dec_ctx->active_video_height,
2531 output_video_width, output_video_height, p_dec_ctx->pixel_format, p_out_frame);
2532 }
2533
2534 if (rc < 0) {
2535 goto end;
2536 }
2537 }
2538 } else // rx_size == 0 means no decoded frame is available now
2539 {
2540 ni_log(NI_LOG_DEBUG, "No data received from decoder, return EAGAIN and retry\n");
2541 if (!p_out_frame->end_of_stream)
2542 {
2543 if (!b_is_hwframe)
2544 {
2545 ni_decoder_frame_buffer_free(p_out_frame);
2546 } else
2547 {
2548 ni_frame_buffer_free(p_out_frame);
2549 }
2550 }
2552 }
2553
2554 p_ctx->dec_total_bytes_received += rx_size;
2555 *p_rx_size = rx_size;
2556
2557 if (p_out_frame->end_of_stream)
2558 {
2559 ni_log(NI_LOG_INFO, "Decoder Receiving done.\n");
2560 p_ctx->dec_eos_received = 1;
2562 }
2563
2564 ni_log(NI_LOG_DEBUG, "decoder_receive_data: success\n");
2565
2566end:
2567 ni_log(NI_LOG_DEBUG, "decoder_receive_data: rc %d rx_size %d\n", rc, rx_size);
2568
2569 return rc;
2570}
2571
2572/*!*****************************************************************************
2573 * \brief decoder session open
2574 *
2575 * \param
2576 *
2577 * \return 0 if successful, < 0 otherwise
2578 ******************************************************************************/
2579int decoder_open_session(ni_session_context_t *p_dec_ctx, int iXcoderGUID,
2580 ni_xcoder_params_t *p_dec_params)
2581{
2582 int ret = 0;
2583
2584 // default is little_endian
2586 p_dec_ctx->p_session_config = p_dec_params;
2587 p_dec_ctx->session_id = NI_INVALID_SESSION_ID;
2588
2589 // assign the card GUID in the encoder context and let session open
2590 // take care of the rest
2591 p_dec_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
2592 p_dec_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
2593 p_dec_ctx->hw_id = iXcoderGUID;
2594
2595 if (p_dec_params->dec_input_params.hwframes)
2596 {
2597 p_dec_ctx->hw_action = NI_CODEC_HW_ENABLE;
2598 } else
2599 {
2600 p_dec_ctx->hw_action = NI_CODEC_HW_NONE;
2601 }
2602
2604
2605 if (ret != NI_RETCODE_SUCCESS)
2606 {
2607 ni_log(NI_LOG_ERROR, "Error: ni_decoder_session_open() failure!\n");
2608 return -1;
2609 } else
2610 {
2611 ni_log(NI_LOG_INFO, "Decoder device %d session open successful.\n", iXcoderGUID);
2612 return 0;
2613 }
2614}
2615
2617{
2618 uint64_t current_time;
2619
2621
2622 ni_log(NI_LOG_ERROR, "Decoder Closing, Got: Frames=%u FPS=%.2f Total bytes %llu\n",
2623 p_ctx->num_frames_received,
2624 (float)p_ctx->num_frames_received / (float)(current_time - p_ctx->start_time) * (float)1000000000,
2626
2628}
2629
2630void *decoder_send_thread(void *args)
2631{
2632 dec_send_param_t *p_dec_send_param = args;
2633 ni_demo_context_t *p_ctx = p_dec_send_param->p_ctx;
2634 ni_session_context_t *p_dec_ctx = p_dec_send_param->p_dec_ctx;
2635 ni_test_frame_list_t *frame_list = p_dec_send_param->frame_list;
2636 ni_session_data_io_t in_pkt = {0};
2637 int retval = 0;
2638
2639 ni_log(NI_LOG_INFO, "decoder_send_thread start: decoder_low_delay %d\n",
2640 p_dec_ctx->decoder_low_delay);
2641 while (1)
2642 {
2643 // Do not send packet to decoder if the output frame list is full.
2644 // Try to consume one decoded frame before sending new packets
2645 while (frame_list_is_full(frame_list) && !p_ctx->end_all_threads)
2646 {
2647 ni_usleep(100);
2648 }
2649
2650 if (p_ctx->end_all_threads)
2651 {
2652 break;
2653 }
2654
2655 retval = decoder_send_data(p_ctx, p_dec_ctx, &in_pkt, p_dec_send_param->input_width,
2656 p_dec_send_param->input_height, p_dec_send_param->p_stream_info);
2657 if (retval < 0) // Error
2658 {
2659 ni_log(NI_LOG_ERROR, "Error: decoder send packet failed\n");
2660 break;
2661 } else if (p_dec_send_param->p_ctx->dec_eos_sent) //eos
2662 {
2663 ni_log(NI_LOG_INFO, "decoder_send_thread reached eos\n");
2664 break;
2665 } else if (retval == NI_TEST_RETCODE_EAGAIN) {
2666 ni_usleep(100);
2667 }
2668 }
2669
2671
2672 // Broadcast all codec threads to quit on exception such as NVMe IO.
2673 if (retval < 0)
2674 {
2675 p_ctx->end_all_threads = 1;
2676 }
2677
2678 ni_log(NI_LOG_TRACE, "decoder_send_thread exit\n");
2679 return (void *)(int64_t)retval;
2680}
2681
2682void *decoder_receive_thread(void *args)
2683{
2684 dec_recv_param_t *p_dec_recv_param = args;
2685 ni_demo_context_t *p_ctx = p_dec_recv_param->p_ctx;
2686 ni_session_context_t *p_dec_ctx = p_dec_recv_param->p_dec_ctx;
2687 ni_test_frame_list_t *frame_list = p_dec_recv_param->frame_list;
2688 ni_scale_params_t *scale_params = p_dec_recv_param->scale_params;
2689 ni_drawbox_params_t *drawbox_params = p_dec_recv_param->drawbox_params;
2690 ni_session_data_io_t filter_out_frame = {0};
2691 ni_session_data_io_t *p_out_frame = NULL;
2692 ni_frame_t *p_ni_frame = NULL;
2693 niFrameSurface1_t *p_hwframe;
2694 int retval = 0;
2695 int rx_size = 0;
2696 uint64_t current_time, previous_time = p_ctx->start_time;
2697
2698 ni_log(NI_LOG_INFO, "decoder_receive_thread start\n");
2699
2700 for (;;)
2701 {
2702 while (frame_list_is_full(frame_list) && !p_ctx->end_all_threads)
2703 {
2704 ni_usleep(100);
2705 }
2706
2707 if (p_ctx->end_all_threads)
2708 {
2709 break;
2710 }
2711
2712 p_out_frame = &frame_list->frames[frame_list->tail];
2713 p_ni_frame = &p_out_frame->data.frame;
2714 retval = decoder_receive_data(
2715 p_ctx, p_dec_ctx, p_out_frame, p_dec_recv_param->input_width,
2716 p_dec_recv_param->input_height, NULL, 0 /* no save to file */, &rx_size);
2717 if (retval < 0) // Error
2718 {
2719 if (!p_dec_ctx->hw_action)
2720 {
2721 ni_decoder_frame_buffer_free(p_ni_frame);
2722 } else
2723 {
2724 ni_frame_buffer_free(p_ni_frame);
2725 }
2726 ni_log(
2728 "Error: decoder_receive_thread break in transcode mode!\n");
2729 break;
2730 } else if (p_ni_frame->end_of_stream)
2731 {
2732 frame_list_enqueue(frame_list);
2733 ni_log(NI_LOG_INFO, "decoder_receive_thread reach eos\n");
2734 retval = 0;
2735 break;
2736 } else if (retval == NI_TEST_RETCODE_EAGAIN)
2737 {
2738 if (!p_dec_ctx->hw_action)
2739 {
2740 ni_decoder_frame_buffer_free(p_ni_frame);
2741 } else
2742 {
2743 ni_frame_buffer_free(p_ni_frame);
2744 }
2745 ni_usleep(100);
2746 } else
2747 {
2748 if (scale_params->enabled)
2749 {
2750 p_hwframe = (niFrameSurface1_t *)p_ni_frame->p_data[3];
2751 ni_hw_frame_ref(p_hwframe);
2752 scale_filter(p_dec_recv_param->p_sca_ctx, p_ni_frame, &filter_out_frame, p_dec_recv_param->xcoderGUID,
2753 scale_params->width, scale_params->height, ni_to_gc620_pix_fmt(p_dec_ctx->pixel_format),
2754 scale_params->format);
2755 ni_hw_frame_unref(p_hwframe->ui16FrameIdx);
2756 ni_frame_buffer_free(p_ni_frame);
2757 memcpy(p_out_frame, &filter_out_frame, sizeof(ni_session_data_io_t));
2758 memset(&filter_out_frame, 0, sizeof(ni_session_data_io_t));
2759 }
2760 else if (drawbox_params->enabled)
2761 {
2762 p_hwframe = (niFrameSurface1_t *)p_ni_frame->p_data[3];
2763 ni_hw_frame_ref(p_hwframe);
2764 drawbox_filter(p_dec_recv_param->p_crop_ctx, p_dec_recv_param->p_pad_ctx, p_dec_recv_param->p_ovly_ctx,
2765 p_dec_recv_param->p_fmt_ctx, p_ni_frame, &filter_out_frame, drawbox_params,
2766 p_dec_recv_param->xcoderGUID, ni_to_gc620_pix_fmt(p_dec_ctx->pixel_format), GC620_I420);
2767 ni_hw_frame_unref(p_hwframe->ui16FrameIdx);
2768 ni_frame_buffer_free(p_ni_frame);
2769 memcpy(p_out_frame, &filter_out_frame, sizeof(ni_session_data_io_t));
2770 memset(&filter_out_frame, 0, sizeof(ni_session_data_io_t));
2771 }
2772 if (p_dec_ctx->hw_action)
2773 {
2774 uint16_t current_hwframe_index = ((niFrameSurface1_t *)p_ni_frame->p_data[3])->ui16FrameIdx;
2775 ni_log(NI_LOG_DEBUG, "decoder recv:%d, tail:%d\n", current_hwframe_index, frame_list->tail);
2776 }
2777 frame_list_enqueue(frame_list);
2778 }
2779
2781 if (current_time - previous_time >= (uint64_t)1000000000) {
2782 ni_log(NI_LOG_INFO, "Decoder stats: received %u frames, fps %.2f, total bytes %u\n",
2783 p_ctx->num_frames_received,
2784 (float)p_ctx->num_frames_received / (float)(current_time - p_ctx->start_time) * (float)1000000000,
2787 }
2788 }
2789
2790 ni_frame_buffer_free(&filter_out_frame.data.frame);
2791
2792 // Broadcast all codec threads to quit on exception such as NVMe IO.
2793 if (retval < 0)
2794 {
2795 p_ctx->end_all_threads = 1;
2796 }
2797
2798 ni_log(NI_LOG_TRACE, "decoder_receive_thread exit\n");
2799 return (void *)(int64_t)retval;
2800}
void ni_dec_retrieve_aux_data(ni_frame_t *frame)
Retrieve auxiliary data (close caption, various SEI) associated with this frame that is returned by d...
@ NI_COL_TRC_RESERVED0
@ NI_COL_TRC_UNSPECIFIED
@ NI_COL_TRC_NB
@ NI_COL_SPC_NB
@ NI_COL_SPC_UNSPECIFIED
@ NI_COL_SPC_RGB
@ NI_COL_PRI_RESERVED0
Definition ni_av_codec.h:96
@ NI_COL_PRI_NB
Not part of ABI.
@ NI_COL_PRI_UNSPECIFIED
Definition ni_av_codec.h:99
#define NI_NUM_PIXEL_ASPECT_RATIO
Definition ni_av_codec.h:38
@ NI_H264_SEI_PIC_STRUCT_FRAME_TRIPLING
frame tripling
Definition ni_av_codec.h:89
@ NI_H264_SEI_PIC_STRUCT_FRAME
frame
Definition ni_av_codec.h:73
@ NI_H264_SEI_TYPE_PIC_TIMING
Definition ni_av_codec.h:54
int ni_bs_reader_bits_count(ni_bitstream_reader_t *br)
return the number of bits already parsed in stream
uint32_t ni_bs_reader_get_ue(ni_bitstream_reader_t *br)
read an unsigned Exp-Golomb code ue(v)
int32_t ni_bs_reader_get_se(ni_bitstream_reader_t *br)
read a signed Exp-Golomb code se(v)
void ni_bitstream_reader_init(ni_bitstream_reader_t *br, const uint8_t *data, int bit_size)
init a bitstream reader Note: bitstream_reader takes reading ownership of the data
uint32_t ni_bs_reader_get_bits(ni_bitstream_reader_t *br, int n)
read bits (up to 32) from the bitstream reader, after reader init
int ni_bs_reader_get_bits_left(ni_bitstream_reader_t *br)
return the number of bits left to parse in stream
void ni_bs_reader_skip_bits(ni_bitstream_reader_t *br, int n)
skip a number of bits ahead in the bitstream reader
int h265_parse_ptl(ni_bitstream_reader_t *br, PTL *ptl, int max_num_sub_layers)
void decoder_stat_report_and_close(ni_demo_context_t *p_ctx, ni_session_context_t *p_dec_ctx)
int probe_h264_stream_info(ni_demo_context_t *p_ctx, ni_h264_sps_t *sps)
int vp9_parse_header(ni_vp9_header_info_t *vp9_info, uint8_t *buf, int size_bytes)
uint64_t find_h264_next_nalu(ni_demo_context_t *p_ctx, uint8_t *p_dst, int *nal_type)
int h264_parse_sei(uint8_t *buf, int size_bytes, ni_h264_sps_t *sps, int *sei_type, int *is_interlaced)
int h264_parse_hrd(ni_bitstream_reader_t *br, ni_h264_sps_t *sps)
int h265_decode_profile_tier_level(ni_bitstream_reader_t *br, PTLCommon *ptl)
int h265_decode_hrd(ni_bitstream_reader_t *br, int common_inf_present, int max_sublayers)
int h264_parse_scaling_matrices(ni_bitstream_reader_t *br, const ni_h264_sps_t *sps, uint8_t(*scaling_matrix4)[16], uint8_t(*scaling_matrix8)[64])
void * decoder_send_thread(void *args)
int decoder_receive_data(ni_demo_context_t *p_ctx, ni_session_context_t *p_dec_ctx, ni_session_data_io_t *p_out_data, int output_video_width, int output_video_height, FILE *p_file, int write_to_file, int *p_rx_size)
Receive decoded output data from decoder.
int h264_parse_vui(ni_bitstream_reader_t *br, ni_h264_sps_t *sps)
uint64_t find_h265_next_nalu(ni_demo_context_t *p_ctx, uint8_t *p_dst, int *nal_type)
int h264_parse_sps(uint8_t *buf, int size_bytes, ni_h264_sps_t *sps)
int h264_parse_scaling_list(ni_bitstream_reader_t *br, uint8_t *factors, int size, const uint8_t *jvt_list, const uint8_t *fallback_list)
int h265_parse_sps(ni_h265_sps_t *sps, uint8_t *buf, int size_bytes)
int parse_h264_slice_header(uint8_t *buf, int size_bytes, ni_h264_sps_t *sps, int32_t *frame_num, unsigned int *first_mb_in_slice)
int decoder_open_session(ni_session_context_t *p_dec_ctx, int iXcoderGUID, ni_xcoder_params_t *p_dec_params)
decoder session open
int probe_h265_stream_info(ni_demo_context_t *p_ctx, ni_h265_sps_t *sps)
void h265_decode_sublayer_hrd(ni_bitstream_reader_t *br, unsigned int nb_cpb, int subpic_params_present)
void * decoder_receive_thread(void *args)
int h265_scaling_list_data(ni_bitstream_reader_t *br, ScalingList *sl, ni_h265_sps_t *sps)
#define check_profile_idc(idc)
int probe_vp9_stream_info(ni_demo_context_t *p_ctx, ni_vp9_header_info_t *vp9_info)
void h265_set_default_scaling_list_data(ScalingList *sl)
int h265_decode_short_term_rps(ni_bitstream_reader_t *br, ShortTermRPS *rps, const ni_h265_sps_t *sps, int is_slice_header)
int decoder_send_data(ni_demo_context_t *p_ctx, ni_session_context_t *p_dec_ctx, ni_session_data_io_t *p_in_data, int input_video_width, int input_video_height, void *stream_info)
Send decoder input data.
uint64_t find_vp9_next_packet(ni_demo_context_t *p_ctx, uint8_t *p_dst, ni_vp9_header_info_t *vp9_info)
int h265_decode_vui(ni_bitstream_reader_t *br, int apply_defdispwin, ni_h265_sps_t *sps)
@ H264_NAL_SPS
@ H264_NAL_SLICE
@ H264_NAL_SEI
@ H264_NAL_IDR_SLICE
@ HEVC_NAL_SPS
Common NETINT definitions used by all modules.
@ NI_DEVICE_TYPE_DECODER
Definition ni_defs.h:360
#define NI_MAX_TX_SZ
Definition ni_defs.h:261
@ NI_RETCODE_FAILURE
Definition ni_defs.h:444
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:443
ni_retcode_t ni_frame_buffer_free(ni_frame_t *p_frame)
Free frame buffer that was previously allocated with either ni_frame_buffer_alloc or ni_encoder_frame...
int ni_packet_copy(void *p_destination, const void *const p_source, int cur_size, void *p_leftover, int *p_prev_size)
Copy video packet accounting for alignment.
ni_retcode_t ni_frame_buffer_alloc(ni_frame_t *p_frame, int video_width, int video_height, int alignment, int metadata_flag, int factor, int hw_frame_count, int is_planar)
Allocate preliminary memory for the frame buffer based on provided parameters. Applicable to YUV420 P...
ni_retcode_t ni_device_session_close(ni_session_context_t *p_ctx, int eos_recieved, ni_device_type_t device_type)
Close device session that was previously opened by calling ni_device_session_open() If device_type is...
ni_retcode_t ni_device_session_open(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Open a new device session depending on the device_type parameter If device_type is NI_DEVICE_TYPE_DEC...
ni_retcode_t ni_packet_buffer_free(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc.
int ni_device_session_read(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, ni_device_type_t device_type)
Read data from the device If device_type is NI_DEVICE_TYPE_DECODER reads data packet from decoder If ...
ni_retcode_t ni_decoder_frame_buffer_alloc(ni_buf_pool_t *p_pool, ni_frame_t *p_frame, int alloc_mem, int video_width, int video_height, int alignment, int factor, int is_planar)
Allocate memory for decoder frame buffer based on provided parameters; the memory is retrieved from a...
int ni_device_session_read_hwdesc(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, ni_device_type_t device_type)
Read data from the device If device_type is NI_DEVICE_TYPE_DECODER reads data hwdesc from decoder If ...
ni_retcode_t ni_packet_buffer_alloc(ni_packet_t *p_packet, int packet_size)
Allocate memory for the packet buffer based on provided packet size.
int ni_device_session_write(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, ni_device_type_t device_type)
Sends data to the device If device_type is NI_DEVICE_TYPE_DECODER sends data packet to decoder If dev...
ni_retcode_t ni_decoder_frame_buffer_free(ni_frame_t *p_frame)
Free decoder frame buffer that was previously allocated with ni_decoder_frame_buffer_alloc,...
#define GC620_I420
@ NI_PIXEL_PLANAR_FORMAT_PLANAR
#define NI_FRAME_LITTLE_ENDIAN
#define NI_INVALID_SESSION_ID
@ NI_CODEC_HW_NONE
@ NI_CODEC_HW_ENABLE
@ NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_VP9
@ NI_PIX_FMT_YUV420P
struct _ni_rational ni_rational_t
int scale_filter(ni_session_context_t *p_ctx, ni_frame_t *p_frame_in, ni_session_data_io_t *p_data_out, int iXcoderGUID, int scale_width, int scale_height, int in_format, int out_format)
Do a scale and/or format-change operation.
int drawbox_filter(ni_session_context_t *p_crop_ctx, ni_session_context_t *p_pad_ctx, ni_session_context_t *p_overlay_ctx, ni_session_context_t *p_fmt_ctx, ni_frame_t *p_frame_in, ni_session_data_io_t *p_data_out, ni_drawbox_params_t *p_box_params, int iXcoderGUID, int input_format, int output_format)
Use crop->pad->overlay to simulate a drawbox filter.
void ni_hw_frame_unref(uint16_t hwframe_index)
int ni_to_gc620_pix_fmt(ni_pix_fmt_t pix_fmt)
ni_pixel_planar_format get_pixel_planar(ni_pix_fmt_t pix_fmt)
bool frame_list_is_full(ni_test_frame_list_t *list)
void rewind_data_buf_pos_by(ni_demo_context_t *p_ctx, uint64_t nb_bytes)
int hwdl_frame(ni_session_context_t *p_ctx, ni_session_data_io_t *p_session_data, ni_frame_t *p_src_frame, int output_format)
Download hw frames by HwDesc.
int write_rawvideo_data(FILE *p_file, int input_aligned_width, int input_aligned_height, int output_width, int output_height, int format, ni_frame_t *p_out_frame)
Write hwdl data to files.
void reset_data_buf_pos(ni_demo_context_t *p_ctx)
int frame_list_enqueue(ni_test_frame_list_t *list)
void ni_hw_frame_ref(const niFrameSurface1_t *p_surface)
#define HEVC_MAX_SUB_LAYERS
#define MIN_LOG2_MAX_FRAME_NUM
#define HEVC_MAX_LONG_TERM_REF_PICS
#define HEVC_MAX_SHORT_TERM_REF_PIC_SETS
#define HEVC_MAX_REFS
#define NI_TEST_RETCODE_SUCCESS
#define NI_TEST_RETCODE_EAGAIN
#define EXTENDED_SAR
#define NI_TEST_RETCODE_END_OF_STREAM
#define HEVC_MAX_LOG2_CTB_SIZE
#define HEVC_MAX_SPS_COUNT
#define NI_TEST_RETCODE_FAILURE
#define MAX_LOG2_MAX_FRAME_NUM
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition ni_log.c:183
Logging definitions.
@ NI_LOG_DEBUG
Definition ni_log.h:64
@ NI_LOG_TRACE
Definition ni_log.h:65
@ NI_LOG_ERROR
Definition ni_log.h:62
@ NI_LOG_INFO
Definition ni_log.h:63
struct timeval current_time
struct timeval previous_time
int ni_remove_emulation_prevent_bytes(uint8_t *buf, int size)
Remove emulation prevention byte(s) as needed from the data buffer.
Definition ni_util.c:3268
void ni_usleep(int64_t usec)
Definition ni_util.c:362
uint64_t ni_gettime_ns(void)
Definition ni_util.c:2622
Utility definitions.
uint64_t dec_total_bytes_received
uint64_t dec_total_bytes_sent
uint32_t end_of_stream
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
ni_color_transfer_characteristic_t color_trc
int colour_description_present_flag
ni_color_primaries_t color_primaries
int nal_hrd_parameters_present_flag
int log2_max_frame_num
log2_max_frame_num_minus4 + 4
unsigned int crop_left
frame_cropping_rect_left_offset
int cpb_removal_delay_length
cpb_removal_delay_length_minus1 + 1
int poc_type
pic_order_cnt_type
uint32_t num_units_in_tick
int constraint_set_flags
constraint_set[0-3]_flag
unsigned int sps_id
int bit_depth_luma
bit_depth_luma_minus8 + 8
int transform_bypass
qpprime_y_zero_transform_bypass_flag
int gaps_in_frame_num_allowed_flag
uint8_t scaling_matrix8[6][64]
int initial_cpb_removal_delay_length
initial_cpb_removal_delay_length_minus1 + 1
unsigned int max_dec_frame_buffering
unsigned int crop_bottom
frame_cropping_rect_bottom_offset
int offset_for_top_to_bottom_field
int delta_pic_order_always_zero_flag
ni_color_space_t colorspace
uint8_t scaling_matrix4[6][16]
int vcl_hrd_parameters_present_flag
int poc_cycle_length
num_ref_frames_in_pic_order_cnt_cycle
int residual_color_transform_flag
residual_colour_transform_flag
int video_signal_type_present_flag
int mb_aff
mb_adaptive_frame_field_flag
short offset_for_ref_frame[256]
int dpb_output_delay_length
dpb_output_delay_length_minus1 + 1
unsigned int crop_right
frame_cropping_rect_right_offset
unsigned int crop_top
frame_cropping_rect_top_offset
int cpb_cnt
See H.264 E.1.2.
int crop
frame_cropping_flag
int ref_frame_count
num_ref_frames
int bit_depth_chroma
bit_depth_chroma_minus8 + 8
ni_rational_t sar
int log2_max_poc_lsb
log2_max_pic_order_cnt_lsb_minus4
int mb_width
(pic_height_in_map_units_minus1 + 1) * (2 - frame_mbs_only_flag)
unsigned int log2_max_poc_lsb
unsigned int log2_max_trafo_size
int transform_skip_rotation_enabled_flag
unsigned int log2_min_pu_size
int cabac_bypass_alignment_enabled_flag
coded frame dimension in various units
uint8_t num_long_term_ref_pics_sps
unsigned int log2_min_cb_size
struct _ni_h265_sps_t::@1 temporal_layer[HEVC_MAX_SUB_LAYERS]
uint8_t temporal_id_nesting_flag
uint8_t sps_temporal_mvp_enabled_flag
unsigned int log2_max_pcm_cb_size
ScalingList scaling_list
uint8_t long_term_ref_pics_present_flag
int extended_precision_processing_flag
uint8_t used_by_curr_pic_lt_sps_flag[HEVC_MAX_LONG_TERM_REF_PICS]
int max_transform_hierarchy_depth_inter
ni_h265_window_t pic_conf_win
unsigned int log2_min_tb_size
int intra_smoothing_disabled_flag
ni_h265_window_t output_window
unsigned int log2_min_pcm_cb_size
unsigned int nb_st_rps
int transform_skip_context_enabled_flag
uint16_t lt_ref_pic_poc_lsb_sps[HEVC_MAX_LONG_TERM_REF_PICS]
int high_precision_offsets_enabled_flag
unsigned int log2_ctb_size
uint8_t sps_strong_intra_smoothing_enable_flag
unsigned int log2_diff_max_min_coding_block_size
uint8_t loop_filter_disable_flag
uint8_t scaling_list_enable_flag
int persistent_rice_adaptation_enabled_flag
uint8_t separate_colour_plane_flag
int max_transform_hierarchy_depth_intra
ShortTermRPS st_rps[HEVC_MAX_SHORT_TERM_REF_PIC_SETS]
struct _ni_h265_sps_t::@2 pcm
unsigned int left_offset
unsigned int bottom_offset
unsigned int right_offset
unsigned int top_offset
uint32_t data_len
uint32_t start_of_stream
uint32_t end_of_stream
uint32_t video_width
uint32_t video_height
ni_device_handle_t device_handle
ni_device_handle_t blk_io_handle
ni_buf_pool_t * dec_fme_buf_pool
union _ni_session_data_io::@19 data
ni_session_data_io_t frames[NI_MAX_BUFFERED_FRAME]
struct _ni_vp9_header_info::@3 timebase
ni_decoder_input_params_t dec_input_params
uint8_t inbld_flag
uint8_t lower_bit_rate_constraint_flag
uint8_t profile_space
uint8_t max_10bit_constraint_flag
uint8_t one_picture_only_constraint_flag
uint8_t max_12bit_constraint_flag
uint8_t profile_idc
uint8_t max_monochrome_constraint_flag
uint8_t intra_constraint_flag
uint8_t level_idc
uint8_t progressive_source_flag
uint8_t tier_flag
uint8_t max_420chroma_constraint_flag
uint8_t profile_compatibility_flag[32]
uint8_t max_8bit_constraint_flag
uint8_t max_422chroma_constraint_flag
uint8_t frame_only_constraint_flag
uint8_t interlaced_source_flag
uint8_t max_14bit_constraint_flag
uint8_t non_packed_constraint_flag
uint8_t sub_layer_profile_present_flag[HEVC_MAX_SUB_LAYERS]
uint8_t sub_layer_level_present_flag[HEVC_MAX_SUB_LAYERS]
PTLCommon sub_layer_ptl[HEVC_MAX_SUB_LAYERS]
PTLCommon general_ptl
uint8_t sl[4][6][64]
uint8_t sl_dc[2][6]
unsigned int num_negative_pics
int32_t delta_poc[32]
uint8_t used[32]
int vui_poc_proportional_to_timing_flag
uint8_t transfer_characteristic
int colour_description_present_flag
int field_seq_flag
int chroma_sample_loc_type_top_field
uint8_t matrix_coeffs
int frame_field_info_present_flag
uint32_t vui_time_scale
int overscan_appropriate_flag
int vui_hrd_parameters_present_flag
int default_display_window_flag
int vui_timing_info_present_flag
int log2_max_mv_length_horizontal
int tiles_fixed_structure_flag
uint32_t vui_num_units_in_tick
int max_bits_per_min_cu_denom
int vui_num_ticks_poc_diff_one_minus1
int bitstream_restriction_flag
int motion_vectors_over_pic_boundaries_flag
int min_spatial_segmentation_idc
int max_bytes_per_pic_denom
int log2_max_mv_length_vertical
int neutra_chroma_indication_flag
int chroma_sample_loc_type_bottom_field
int restricted_ref_pic_lists_flag
int video_signal_type_present_flag
int overscan_info_present_flag
int chroma_loc_info_present_flag
int video_format
ni_h265_window_t def_disp_win
uint8_t colour_primaries
int video_full_range_flag
ni_rational_t sar
ni_demo_context_t * p_ctx
ni_drawbox_params_t * drawbox_params
ni_session_context_t * p_sca_ctx
ni_scale_params_t * scale_params
ni_session_context_t * p_pad_ctx
ni_session_context_t * p_dec_ctx
ni_session_context_t * p_ovly_ctx
ni_session_context_t * p_crop_ctx
ni_test_frame_list_t * frame_list
ni_session_context_t * p_fmt_ctx
ni_demo_context_t * p_ctx
ni_session_context_t * p_dec_ctx
ni_test_frame_list_t * frame_list