libxcoder  5.3.1
ni_av_codec.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 ni_av_codec.c
24  *
25  * \brief Audio/video related utility definitions
26  ******************************************************************************/
27 
28 #ifdef _WIN32
29 #include <winsock2.h>
30 #else
31 #include <arpa/inet.h>
32 #endif
33 #include <limits.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include "ni_util.h"
38 #include "ni_nvme.h"
39 #include "ni_bitstream.h"
40 #include "ni_av_codec.h"
41 #include "ni_device_api_priv.h"
42 
43 typedef enum
44 {
49 } slice_type_t;
50 
51 typedef enum
52 {
62  // single_ref
67 
68  // newly added
74 } gop_preset_t;
75 
76 NI_UNUSED static const int32_t GOP_SIZE[NUM_GOP_PRESET_NUM] = {0, 1, 1, 1, 2, 4, 4,
77  4, 8, 1, 2, 4, 4};
78 
79 static const int32_t LT_GOP_PRESET_I_1[6] = {SLICE_TYPE_I, 1, 0, 0, 0, 0};
80 static const int32_t LT_GOP_PRESET_P_1[6] = {SLICE_TYPE_MP, 1, 1, 0, 0, -1};
81 static const int32_t LT_GOP_PRESET_B_1[6] = {SLICE_TYPE_B, 1, 1, 0, 0, -1};
82 // gop_size = 2
83 static const int32_t LT_GOP_PRESET_BP_2[12] = {
84  SLICE_TYPE_MP, 2, 1, 0, 0, -2, SLICE_TYPE_B, 1, 3, 0, 0, 2,
85 };
86 // gop_size = 4
87 static const int32_t LT_GOP_PRESET_BBBP_4[24] = {
88  SLICE_TYPE_MP, 4, 1, 0, 0, -4, SLICE_TYPE_B, 2, 3, 0, 0, 4,
89  SLICE_TYPE_B, 1, 5, 0, 0, 2, SLICE_TYPE_B, 3, 5, 0, 2, 4,
90 };
91 
92 static const int32_t LT_GOP_PRESET_LP_4[24] = {
93  SLICE_TYPE_MP, 1, 5, 0, 0, -4, SLICE_TYPE_MP, 2, 3, 0, 1, 0,
94  SLICE_TYPE_MP, 3, 5, 0, 2, 0, SLICE_TYPE_MP, 4, 1, 0, 3, 0,
95 };
96 static const int32_t LT_GOP_PRESET_LD_4[24] = {
97  SLICE_TYPE_B, 1, 5, 0, 0, -4, SLICE_TYPE_B, 2, 3, 0, 1, 0,
98  SLICE_TYPE_B, 3, 5, 0, 2, 0, SLICE_TYPE_B, 4, 1, 0, 3, 0,
99 };
100 
101 // gop_size = 8
102 static const int32_t LT_GOP_PRESET_RA_8[48] = {
103  SLICE_TYPE_B, 8, 1, 0, 0, -8, SLICE_TYPE_B, 4, 3, 0, 0, 8,
104  SLICE_TYPE_B, 2, 5, 0, 0, 4, SLICE_TYPE_B, 1, 8, 0, 0, 2,
105  SLICE_TYPE_B, 3, 8, 0, 2, 4, SLICE_TYPE_B, 6, 5, 0, 4, 8,
106  SLICE_TYPE_B, 5, 8, 0, 4, 6, SLICE_TYPE_B, 7, 8, 0, 6, 8,
107 };
108 // single-ref-P
109 static const int32_t LT_GOP_PRESET_SP_1[6] = {SLICE_TYPE_P, 1, 1, 0, 0, -1};
110 
111 static const int32_t LT_GOP_PRESET_BSP_2[12] = {
112  SLICE_TYPE_P, 2, 1, 0, 0, -2, SLICE_TYPE_B, 1, 3, 0, 0, 2,
113 };
114 static const int32_t LT_GOP_PRESET_BBBSP_4[24] = {
115  SLICE_TYPE_P, 4, 1, 0, 0, -4, SLICE_TYPE_B, 2, 3, 0, 0, 4,
116  SLICE_TYPE_B, 1, 5, 0, 0, 2, SLICE_TYPE_B, 3, 5, 0, 2, 4,
117 };
118 static const int32_t LT_GOP_PRESET_LSP_4[24] = {
119  SLICE_TYPE_P, 1, 5, 0, 0, -4, SLICE_TYPE_P, 2, 3, 0, 1, 0,
120  SLICE_TYPE_P, 3, 5, 0, 2, 0, SLICE_TYPE_P, 4, 1, 0, 3, 0,
121 };
122 
123 static const int32_t LT_GOP_PRESET_BBP_3[18] = {
124  SLICE_TYPE_MP, 3, 1, 0, 0, -3, SLICE_TYPE_B, 1, 3, 0, 0, 3,
125  SLICE_TYPE_B, 2, 6, 0, 1, 3,
126 };
127 
128 static const int32_t LT_GOP_PRESET_BBSP_3[18] = {
129  SLICE_TYPE_P, 3, 1, 0, 0, 0, SLICE_TYPE_B, 1, 3, 0, 0, 3,
130  SLICE_TYPE_B, 2, 6, 0, 1, 3,
131 };
132 
133 static const int32_t LT_GOP_PRESET_BBBBBBBP_8[48] = {
134  SLICE_TYPE_MP, 8, 1, 0, 0, -8, SLICE_TYPE_B, 4, 3, 0, 0, 8,
135  SLICE_TYPE_B, 2, 5, 0, 0, 4, SLICE_TYPE_B, 1, 8, 0, 0, 2,
136  SLICE_TYPE_B, 3, 8, 0, 2, 4, SLICE_TYPE_B, 6, 5, 0, 4, 8,
137  SLICE_TYPE_B, 5, 8, 0, 4, 6, SLICE_TYPE_B, 7, 8, 0, 6, 8,
138 };
139 
140 static const int32_t LT_GOP_PRESET_BBBBBBBSP_8[48] = {
141  SLICE_TYPE_P, 8, 1, 0, 0, 0, SLICE_TYPE_B, 4, 3, 0, 0, 8,
142  SLICE_TYPE_B, 2, 5, 0, 0, 4, SLICE_TYPE_B, 1, 8, 0, 0, 2,
143  SLICE_TYPE_B, 3, 8, 0, 2, 4, SLICE_TYPE_B, 6, 5, 0, 4, 8,
144  SLICE_TYPE_B, 5, 8, 0, 4, 6, SLICE_TYPE_B, 7, 8, 0, 6, 8,
145 };
146 
147 NI_UNUSED static const int32_t *GOP_PRESET[NUM_GOP_PRESET_NUM] = {
148  NULL,
149  LT_GOP_PRESET_I_1,
150  LT_GOP_PRESET_P_1,
151  LT_GOP_PRESET_B_1,
152  LT_GOP_PRESET_BP_2,
153  LT_GOP_PRESET_BBBP_4,
154  LT_GOP_PRESET_LP_4,
155  LT_GOP_PRESET_LD_4,
156  LT_GOP_PRESET_RA_8,
157 
158  LT_GOP_PRESET_SP_1,
159  LT_GOP_PRESET_BSP_2,
160  LT_GOP_PRESET_BBBSP_4,
161  LT_GOP_PRESET_LSP_4,
162 
163  LT_GOP_PRESET_BBP_3,
164  LT_GOP_PRESET_BBSP_3,
165  LT_GOP_PRESET_BBBBBBBP_8,
166  LT_GOP_PRESET_BBBBBBBSP_8,
167 };
168 
169 #define BR_SHIFT 6
170 #define CPB_SHIFT 4
171 
172 #define SAMPLE_SPS_MAX_SUB_LAYERS_MINUS1 0
173 #define MAX_VPS_MAX_SUB_LAYERS 16
174 #define MAX_CPB_COUNT 16
175 #define MAX_DURATION 0.5
176 
177 /*!*****************************************************************************
178  * \brief Whether SEI (HDR) should be sent together with this frame to encoder
179  *
180  * \param[in] p_enc_ctx encoder session context
181  * \param[in] pic_type frame type
182  * \param[in] p_param encoder parameters
183  *
184  * \return 1 if yes, 0 otherwise
185  ******************************************************************************/
187  ni_pic_type_t pic_type,
188  ni_xcoder_params_t *p_param)
189 {
190  // repeatHeaders = 0. send on first frame only (IDR)
191  // repeatHeaders = 1. send on every I-frame including I-frames generated
192  // on the intraPeriod interval as well as I-frames that are forced.
193  if (0 == p_enc_ctx->frame_num || PIC_TYPE_IDR == pic_type ||
195  p_param->cfg_enc_params.intra_period &&
196  0 ==
197  ((p_enc_ctx->frame_num + p_enc_ctx->force_idr_intra_offset) %
198  p_param->cfg_enc_params.intra_period)))
199  {
200  if (PIC_TYPE_IDR == pic_type &&
202  p_param->cfg_enc_params.intra_period &&
203  0 != (p_enc_ctx->frame_num % p_param->cfg_enc_params.intra_period))
204  {
205  p_enc_ctx->force_idr_intra_offset =
206  p_param->cfg_enc_params.intra_period -
207  (p_enc_ctx->frame_num % p_param->cfg_enc_params.intra_period);
208  }
209  ni_log2(p_enc_ctx, NI_LOG_TRACE, "should send sei? %" PRIu64 " %d %d %d %u\n",
210  p_enc_ctx->frame_num, pic_type,
212  p_param->cfg_enc_params.intra_period,
213  p_enc_ctx->force_idr_intra_offset);
214  return 1;
215  }
216  return 0;
217 }
218 
219 // create a ni_rational_t
220 NI_UNUSED static ni_rational_t ni_make_rational(int num, int den)
221 {
222  ni_rational_t r = {num, den};
223  return r;
224 }
225 
226 /*!*****************************************************************************
227  * \brief Retrieve auxiliary data (close caption, various SEI) associated with
228  * this frame that is returned by decoder, convert them to appropriate
229  * format and save them in the frame's auxiliary data storage for
230  * future use by encoding. Usually they would be sent together with
231  * this frame to encoder at encoding.
232  *
233  * \param[in/out] frame that is returned by decoder
234  *
235  * \return NONE
236  ******************************************************************************/
238 {
239  uint8_t *sei_buf = NULL;
240  ni_aux_data_t *aux_data = NULL;
241  int start_offset = 0;
242  if (frame->data_len[3] != 0)
243  {
244  //HW frame
245  start_offset = 3;
246  }
247  // User Data Unregistered SEI if available
249  {
250  sei_buf = (uint8_t *)frame->p_data[start_offset] +
253  frame, NI_FRAME_AUX_DATA_UDU_SEI, sei_buf,
254  (int)frame->sei_user_data_unreg_len))
255  {
256  ni_log(NI_LOG_ERROR, "ni_dec_retrieve_aux_data error retrieve User data "
257  "unregisted SEI!\n");
258  }
259  }
260 
261  // close caption data if available
262  if (frame->sei_cc_len && frame->sei_cc_offset)
263  {
264  sei_buf = (uint8_t *)frame->p_data[start_offset] + frame->sei_cc_offset;
266  frame, NI_FRAME_AUX_DATA_A53_CC, sei_buf,
267  (int)frame->sei_cc_len))
268  {
269  ni_log(NI_LOG_ERROR, "ni_dec_retrieve_aux_data error retrieve close "
270  "caption SEI!\n");
271  }
272  }
273 
274  // hdr10 sei data if available
275 
276  // mastering display metadata
279  {
280  aux_data = ni_frame_new_aux_data(
283 
284  if (!aux_data)
285  {
286  ni_log(NI_LOG_ERROR, "ni_dec_retrieve_aux_data error retrieve HDR10 "
287  "mastering display color SEI!\n");
288  } else
289  {
292  const int chroma_den = MASTERING_DISP_CHROMA_DEN;
293  const int luma_den = MASTERING_DISP_LUMA_DEN;
296  *)((uint8_t *)frame->p_data[start_offset] +
298 
299  // HEVC uses a g,b,r ordering, which we convert to a more natural r,
300  // g,b,this is so we are compatible with FFmpeg default soft decoder
301  mdm->display_primaries[0][0].num =
302  ntohs(pColourVolume->display_primaries[2][0]);
303  mdm->display_primaries[0][0].den = chroma_den;
304  mdm->display_primaries[0][1].num =
305  ntohs(pColourVolume->display_primaries[2][1]);
306  mdm->display_primaries[0][1].den = chroma_den;
307  mdm->display_primaries[1][0].num =
308  ntohs(pColourVolume->display_primaries[0][0]);
309  mdm->display_primaries[1][0].den = chroma_den;
310  mdm->display_primaries[1][1].num =
311  ntohs(pColourVolume->display_primaries[0][1]);
312  mdm->display_primaries[1][1].den = chroma_den;
313  mdm->display_primaries[2][0].num =
314  ntohs(pColourVolume->display_primaries[1][0]);
315  mdm->display_primaries[2][0].den = chroma_den;
316  mdm->display_primaries[2][1].num =
317  ntohs(pColourVolume->display_primaries[1][1]);
318  mdm->display_primaries[2][1].den = chroma_den;
319  mdm->white_point[0].num = ntohs(pColourVolume->white_point_x);
320  mdm->white_point[0].den = chroma_den;
321  mdm->white_point[1].num = ntohs(pColourVolume->white_point_y);
322  mdm->white_point[1].den = chroma_den;
323 
324  mdm->min_luminance.num =
325  ntohl(pColourVolume->min_display_mastering_luminance);
326  mdm->min_luminance.den = luma_den;
327  mdm->max_luminance.num =
328  ntohl(pColourVolume->max_display_mastering_luminance);
329  mdm->max_luminance.den = luma_den;
330 
331  mdm->has_luminance = mdm->has_primaries = 1;
332  }
333  }
334 
335  // hdr10 content light level
338  {
339  aux_data =
341  sizeof(ni_content_light_level_t));
342 
343  if (!aux_data)
344  {
345  ni_log(NI_LOG_ERROR, "ni_dec_retrieve_aux_data error retrieve HDR10 "
346  "content light level SEI !\n");
347  } else
348  {
350  (ni_content_light_level_t *)aux_data->data;
353  *)((uint8_t *)frame->p_data[start_offset] +
355 
356  clm->max_cll = ntohs(pLightLevel->max_content_light_level);
357  clm->max_fall = ntohs(pLightLevel->max_pic_average_light_level);
358  }
359  }
360 
361  // hdr10+ sei data if available
362  if (frame->sei_hdr_plus_len && frame->sei_hdr_plus_offset)
363  {
365  sizeof(ni_dynamic_hdr_plus_t));
366 
367  if (!aux_data)
368  {
369  ni_log(NI_LOG_ERROR, "ni_dec_retrieve_aux_data error retrieve HDR10+ SEI "
370  "!\n");
371  } else
372  {
373  int w, i, j, i_limit, j_limit;
374  ni_dynamic_hdr_plus_t *hdrp =
375  (ni_dynamic_hdr_plus_t *)aux_data->data;
377 
378  sei_buf = (uint8_t *)frame->p_data[start_offset] +
379  frame->sei_hdr_plus_offset;
380  ni_bitstream_reader_init(&br, sei_buf,
381  8 * (int)frame->sei_hdr_plus_len);
382  hdrp->itu_t_t35_country_code = 0xB5;
383  // first 6 bytes of t35 SEI data header already matched HDR10+, and:
384  ni_bs_reader_skip_bits(&br, 6 * 8);
385  // application_version u(8)
387  ni_log(NI_LOG_DEBUG, "hdr10+ application_version %u\n", hdrp->application_version);
388 
389 
390  // Num_windows u(2)
391  hdrp->num_windows = ni_bs_reader_get_bits(&br, 2);
392  ni_log(NI_LOG_DEBUG, "hdr10+ num_windows %u\n", hdrp->num_windows);
393  if (!(1 == hdrp->num_windows || 2 == hdrp->num_windows ||
394  3 == hdrp->num_windows))
395  {
396  // wrong format and skip this HDR10+ SEI
397  } else
398  {
399  // the following block will be skipped for hdrp->num_windows ==
400  // 1
401  for (w = 1; w < hdrp->num_windows; w++)
402  {
403  hdrp->params[w - 1].window_upper_left_corner_x =
404  ni_make_q(ni_bs_reader_get_bits(&br, 16), 1);
405  hdrp->params[w - 1].window_upper_left_corner_y =
406  ni_make_q(ni_bs_reader_get_bits(&br, 16), 1);
407  hdrp->params[w - 1].window_lower_right_corner_x =
408  ni_make_q(ni_bs_reader_get_bits(&br, 16), 1);
409  hdrp->params[w - 1].window_lower_right_corner_y =
410  ni_make_q(ni_bs_reader_get_bits(&br, 16), 1);
411  hdrp->params[w - 1].center_of_ellipse_x =
412  ni_bs_reader_get_bits(&br, 16);
413  hdrp->params[w - 1].center_of_ellipse_y =
414  ni_bs_reader_get_bits(&br, 16);
415  hdrp->params[w - 1].rotation_angle =
416  ni_bs_reader_get_bits(&br, 8);
418  ni_bs_reader_get_bits(&br, 16);
420  ni_bs_reader_get_bits(&br, 16);
422  ni_bs_reader_get_bits(&br, 16);
423  hdrp->params[w - 1].overlap_process_option =
425  ni_bs_reader_get_bits(&br, 1);
426  }
427 
428  // values are scaled down according to standard spec
430  ni_bs_reader_get_bits(&br, 27);
432 
434  ni_bs_reader_get_bits(&br, 1);
435 
437  "hdr10+ targeted_system_display_maximum_luminance "
438  "%d\n",
441  "hdr10+ targeted_system_display_actual_peak_lumi"
442  "nance_flag %u\n",
444 
446  {
447  i_limit =
449  ni_bs_reader_get_bits(&br, 5);
450 
451  j_limit =
453  ni_bs_reader_get_bits(&br, 5);
454 
456  "hdr10+ num_rows_targeted_system_display_actual"
457  "_peak_luminance x "
458  "num_cols_targeted_system_display_actual_"
459  "peak_luminance %d x %d\n",
460  i_limit, j_limit);
461 
462  i_limit = i_limit > 25 ? 25 : i_limit;
463  j_limit = j_limit > 25 ? 25 : j_limit;
464  for (i = 0; i < i_limit; i++)
465  for (j = 0; j < j_limit; j++)
466  {
468  [i][j]
469  .num = ni_bs_reader_get_bits(&br, 4);
471  [i][j]
472  .den = 15;
474  "hdr10+ targeted_system_display_actual_peak"
475  "_luminance[%d][%d] %d\n",
476  i, j,
478  [i][j]
479  .num);
480  }
481  }
482 
483  for (w = 0; w < hdrp->num_windows; w++)
484  {
485  for (i = 0; i < 3; i++)
486  {
487  hdrp->params[w].maxscl[i].num =
488  ni_bs_reader_get_bits(&br, 17);
489  hdrp->params[w].maxscl[i].den = 100000;
490  ni_log(NI_LOG_DEBUG, "hdr10+ maxscl[%d][%d] %d\n", w, i,
491  hdrp->params[w].maxscl[i].num);
492  }
493  hdrp->params[w].average_maxrgb.num =
494  ni_bs_reader_get_bits(&br, 17);
495  hdrp->params[w].average_maxrgb.den = 100000;
496  ni_log(NI_LOG_DEBUG, "hdr10+ average_maxrgb[%d] %d\n", w,
497  hdrp->params[w].average_maxrgb.num);
498 
499  i_limit =
501  ni_bs_reader_get_bits(&br, 4);
503  "hdr10+ num_distribution_maxrgb_percentiles[%d] %d\n",
505 
506  i_limit = i_limit > 15 ? 15 : i_limit;
507  for (i = 0; i < i_limit; i++)
508  {
510  ni_bs_reader_get_bits(&br, 7);
512  ni_bs_reader_get_bits(&br, 17);
514  100000;
516  "hdr10+ distribution_maxrgb_percentage[%d][%d] "
517  "%u\n",
518  w, i,
521  "hdr10+ distribution_maxrgb_percentile[%d][%d] "
522  "%d\n",
523  w, i,
524  hdrp->params[w]
526  .percentile.num);
527  }
528 
530  ni_bs_reader_get_bits(&br, 10);
531  hdrp->params[w].fraction_bright_pixels.den = 1000;
532  ni_log(NI_LOG_DEBUG, "hdr10+ fraction_bright_pixels[%d] %d\n", w,
534  }
535 
537  ni_bs_reader_get_bits(&br, 1);
539  "hdr10+ mastering_display_actual_peak_luminance_flag %u\n",
542  {
543  i_limit =
545  ni_bs_reader_get_bits(&br, 5);
546  j_limit =
548  ni_bs_reader_get_bits(&br, 5);
550  "hdr10+ num_rows_mastering_display_actual_peak_"
551  "luminance x "
552  "num_cols_mastering_display_actual_peak_luminance "
553  "%d x %d\n",
554  i_limit, j_limit);
555 
556  i_limit = i_limit > 25 ? 25 : i_limit;
557  j_limit = j_limit > 25 ? 25 : j_limit;
558  for (i = 0; i < i_limit; i++)
559  for (j = 0; j < j_limit; j++)
560  {
562  .num = ni_bs_reader_get_bits(&br, 4);
564  .den = 15;
566  "hdr10+ mastering_display_actual_peak_lumi"
567  "nance[%d][%d] %d\n",
568  i, j,
569  hdrp
570  ->mastering_display_actual_peak_luminance[i]
571  [j]
572  .num);
573  }
574  }
575 
576  for (w = 0; w < hdrp->num_windows; w++)
577  {
578  hdrp->params[w].tone_mapping_flag =
579  ni_bs_reader_get_bits(&br, 1);
580  ni_log(NI_LOG_DEBUG, "hdr10+ tone_mapping_flag[%d] %u\n", w,
581  hdrp->params[w].tone_mapping_flag);
582 
583  if (hdrp->params[w].tone_mapping_flag)
584  {
585  hdrp->params[w].knee_point_x.num =
586  ni_bs_reader_get_bits(&br, 12);
587  hdrp->params[w].knee_point_x.den = 4095;
588  hdrp->params[w].knee_point_y.num =
589  ni_bs_reader_get_bits(&br, 12);
590  hdrp->params[w].knee_point_y.den = 4095;
591  ni_log(NI_LOG_DEBUG, "hdr10+ knee_point_x[%d] %d\n", w,
592  hdrp->params[w].knee_point_x.num);
593  ni_log(NI_LOG_DEBUG, "hdr10+ knee_point_y[%d] %d\n", w,
594  hdrp->params[w].knee_point_y.num);
595 
597  ni_bs_reader_get_bits(&br, 4);
599  "hdr10+ num_bezier_curve_anchors[%d] %u\n", w,
601  for (i = 0;
602  i < hdrp->params[w].num_bezier_curve_anchors; i++)
603  {
604  hdrp->params[w].bezier_curve_anchors[i].num =
605  ni_bs_reader_get_bits(&br, 10);
606  hdrp->params[w].bezier_curve_anchors[i].den = 1023;
608  "hdr10+ bezier_curve_anchors[%d][%d] %d\n", w,
609  i, hdrp->params[w].bezier_curve_anchors[i].num);
610  }
611  }
612 
614  ni_bs_reader_get_bits(&br, 1);
616  "hdr10+ color_saturation_mapping_flag[%d] %u\n", w,
619  {
621  ni_bs_reader_get_bits(&br, 6);
622  hdrp->params[w].color_saturation_weight.den = 8;
624  "hdr10+ color_saturation_weight[%d] %d\n", w,
626  }
627  } // num_windows
628 
629  } // right number of windows
630  } // alloc memory
631  } // HDR10+ SEI
632 
633  // init source stream info to default values (unspecified)
637  frame->video_full_range_flag = 0;
638  frame->aspect_ratio_idc = 0;
639  frame->sar_width = 0;
640  frame->sar_height = 0;
641  frame->vui_num_units_in_tick = 0;
642  frame->vui_time_scale = 0;
643 
644  // VUI if retrieved
645  if (frame->vui_offset || frame->vui_len)
646  {
647  sei_buf = (uint8_t *)frame->p_data[start_offset] + frame->vui_offset;
648  ni_extended_dec_metadata_t *p_dec_ext_meta =
649  (ni_extended_dec_metadata_t *)sei_buf;
650  frame->vui_num_units_in_tick = p_dec_ext_meta->num_units_in_tick;
651  frame->vui_time_scale = p_dec_ext_meta->time_scale;
652  frame->color_primaries = p_dec_ext_meta->color_primaries;
653  frame->color_trc = p_dec_ext_meta->color_trc;
654  frame->color_space = p_dec_ext_meta->color_space;
655  frame->video_full_range_flag = p_dec_ext_meta->video_full_range_flag;
656 
658  "ni_dec_retrieve_aux_data VUI "
659  "aspect_ratio_idc %u "
660  "sar_width %u sar_height %u "
661  "video_full_range_flag %d "
662  "color-pri %u color-trc %u color-space %u "
663  "vui_num_units_in_tick %u "
664  "vui_time_scale %u\n",
665  frame->aspect_ratio_idc, frame->sar_width, frame->sar_height,
666  frame->video_full_range_flag, frame->color_primaries,
667  frame->color_trc, frame->color_space,
668  frame->vui_num_units_in_tick, frame->vui_time_scale);
669  }
670 
671  // alternative transfer characteristics SEI if available
674  {
675  sei_buf = (uint8_t *)frame->p_data[start_offset] +
677 
678  // and overwrite the color-trc in the VUI
679  ni_log(NI_LOG_DEBUG, "ni_dec_retrieve_aux_data alt trc SEI value %u over-"
680  "writting VUI color-trc value %u\n",
681  *sei_buf, frame->color_trc);
682  frame->color_trc = *sei_buf;
683  }
684 }
685 
686 // Convert struct of ROIs to NetInt ROI map and store them inside the encoder
687 // context passed in.
688 // return 0 if successful, -1 otherwise
689 static int set_roi_map(ni_session_context_t *p_enc_ctx,
690  ni_codec_format_t codec_format,
691  const ni_aux_data_t *aux_data, int nb_roi, int width,
692  int height, int intra_qp)
693 {
694  int r;
695  uint32_t i, j, k, m;
696  const ni_region_of_interest_t *roi =
697  (const ni_region_of_interest_t *)aux_data->data;
698  uint32_t self_size = roi->self_size;
699  int32_t set_qp = 0;
700  uint32_t sumQp = 0;
701  uint8_t isAbsQp_flag = 0; // 0 for delta qp, 1 for absolute qp
702  ni_xcoder_params_t *api_params =
703  (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
704 
705  uint32_t max_cu_size = (codec_format == NI_CODEC_FORMAT_H264) ? 16 : 64;
706 
707  // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
708  if (NI_CODEC_FORMAT_AV1 == codec_format)
709  {
710  width = (width / 8) * 8;
711  height = (height / 8) * 8;
712  }
713 
714  // for H.264, select ROI Map Block Unit Size: 16x16
715  // for H.265, select ROI Map Block Unit Size: 64x64
716  uint32_t roiMapBlockUnitSize =
717  (codec_format == NI_CODEC_FORMAT_H264) ? 16 : 64;
718  uint32_t mbWidth = ((width + max_cu_size - 1) & (~(max_cu_size - 1))) /
719  roiMapBlockUnitSize;
720  uint32_t mbHeight = ((height + max_cu_size - 1) & (~(max_cu_size - 1))) /
721  roiMapBlockUnitSize;
722  uint32_t numMbs = mbWidth * mbHeight;
723  uint32_t subMbWidth = roiMapBlockUnitSize / 8;
724  uint32_t subMbHeight = subMbWidth;
725  uint32_t subNumMbs = subMbWidth * subMbHeight;
726 
727  // (ROI map version >= 1) each QP info takes 8-bit, represent 8x8 pixel
728  // block
729  uint32_t block_size = ((width + max_cu_size - 1) & (~(max_cu_size - 1))) *
730  ((height + max_cu_size - 1) & (~(max_cu_size - 1))) / (8 * 8);
731 
732  // need to align to 64 bytes
733  uint32_t customMapSize = ((block_size + 63) & (~63));
734  if (!p_enc_ctx->roi_map)
735  {
736  p_enc_ctx->roi_map =
737  (ni_enc_quad_roi_custom_map *)calloc(1, customMapSize);
738  if (!p_enc_ctx->roi_map)
739  {
740  return -1;
741  }
742  }
743 
744  // init ipcm_flag to 0, roiAbsQp_falg to 0 (qp delta), and qp_info to 0
745  memset(p_enc_ctx->roi_map, 0, customMapSize);
746 
747  // iterate ROI list from the last as regions are defined in order of
748  // decreasing importance.
749  for (r = nb_roi - 1; r >= 0; r--)
750  {
751  roi = (const ni_region_of_interest_t *)((uint8_t *)aux_data->data + self_size * r);
752  if (!roi->qoffset.den)
753  {
754  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_region_of_interest_t.qoffset.den must not be "
755  "zero.\n");
756  continue;
757  }
758  if (api_params->cfg_enc_params.customize_roi_qp_level) {
759  // set_qp in range [1, 10] mean it need to reset qp after
760  // rate control in fw when customize_roi_qp_level > 0.
761  // set_qp is the level in customize qp map, it choose dst qp
762  // in customize qp map base on the rate control qp and set_qp
763  set_qp = (int32_t)((float)roi->qoffset.num * 1.0f /
765  if (set_qp > 0 && set_qp <= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL) {
766  isAbsQp_flag = api_params->cfg_enc_params.customize_roi_qp_level;
767  } else {
768  continue;
769  }
770  } else {
771  set_qp = (int32_t)((float)roi->qoffset.num * 1.0f /
772  (float)roi->qoffset.den * NI_INTRA_QP_RANGE);
773  set_qp = clip3(NI_MIN_QP_DELTA, NI_MAX_QP_DELTA, set_qp);
774  // Adjust qp delta range (-25 to 25) to (0 to 63): 0 to 0, -1 to 1, -2 to
775  // 2 ... 1 to 63, 2 to 62 ...
776  // Theoretically the possible qp delta range is (-32 to 31)
777  set_qp = (NI_MAX_QP_INFO + 1 - set_qp) % (NI_MAX_QP_INFO + 1);
778  }
779  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
780  "set_roi_map: left %d right %d top %d bottom %d num %d den"
781  " %d set_qp %d\n",
782  roi->left, roi->right, roi->top, roi->bottom, roi->qoffset.num,
783  roi->qoffset.den, set_qp);
784 
785  // copy ROI MBs QPs into custom map
786  for (j = 0; j < mbHeight; j++)
787  {
788  for (i = 0; i < mbWidth; i++)
789  {
790  k = j * (int)mbWidth + i;
791 
792  for (m = 0; m < subNumMbs; m++)
793  {
794  if (((int)(i % mbWidth) >=
795  (int)((roi->left + roiMapBlockUnitSize - 1) /
796  roiMapBlockUnitSize) -
797  1) &&
798  ((int)(i % mbWidth) <=
799  (int)((roi->right + roiMapBlockUnitSize - 1) /
800  roiMapBlockUnitSize) -
801  1) &&
802  ((int)(j % mbHeight) >=
803  (int)((roi->top + roiMapBlockUnitSize - 1) /
804  roiMapBlockUnitSize) -
805  1) &&
806  ((int)(j % mbHeight) <=
807  (int)((roi->bottom + roiMapBlockUnitSize - 1) /
808  roiMapBlockUnitSize) -
809  1))
810  {
811  p_enc_ctx->roi_map[k * subNumMbs + m].field.ipcm_flag =
812  0; // don't force skip mode
813  p_enc_ctx->roi_map[k * subNumMbs + m]
814  .field.roiAbsQp_flag = isAbsQp_flag;
815  p_enc_ctx->roi_map[k * subNumMbs + m].field.qp_info =
816  set_qp;
817  // ni_log2(p_enc_ctx, NI_LOG_DEBUG, "## x %d y %d index %d\n", i,
818  // j, k*subNumMbs+m);
819  }
820  }
821  sumQp += p_enc_ctx->roi_map[k * subNumMbs].field.qp_info;
822  }
823  }
824  }
825 
826  p_enc_ctx->roi_len = customMapSize;
827  p_enc_ctx->roi_avg_qp = (numMbs != 0 ? (sumQp + (numMbs >> 1)) / numMbs : 0) + NI_DEFAULT_INTRA_QP;
828 
829  return 0;
830 }
831 
832 /*!*****************************************************************************
833  * \brief Prepare auxiliary data that should be sent together with this frame
834  * to encoder based on the auxiliary data of the decoded frame.
835  *
836  * Note: Some of the SEI (e.g. HDR) will be updated and stored in encoder
837  * context whenever received through decoded frame; they will be sent
838  * out with the encoded frame to encoder only when appropriate, i.e.
839  * should_send_sei_with_frame is true. When a type of aux data is to be
840  * sent, its associated length will be set in the encoder frame.
841  *
842  * \param[in/out] p_enc_ctx encoder session contextwhose various SEI type
843  * header can be updated as the result of this function
844  * \param[out] p_enc_frame frame to be sent to encoder
845  * \param[in] p_dec_frame frame that is returned by decoder
846  * \param[in] codec_format H.264 or H.265
847  * \param[in] should_send_sei_with_frame if need to send a certain type of
848  * SEI with this frame
849  * \param[out] mdcv_data SEI for HDR mastering display color volume info
850  * \param[out] cll_data SEI for HDR content light level info
851  * \param[out] cc_data SEI for close caption
852  * \param[out] udu_data SEI for User data unregistered
853  * \param[out] hdrp_data SEI for HDR10+
854  *
855  * \return NONE
856  ******************************************************************************/
858  ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame,
859  ni_codec_format_t codec_format,
860  int should_send_sei_with_frame, uint8_t *mdcv_data,
861  uint8_t *cll_data, uint8_t *cc_data,
862  uint8_t *udu_data, uint8_t *hdrp_data)
863 {
864  uint8_t *dst = NULL;
865  ni_aux_data_t *aux_data = NULL;
866  ni_xcoder_params_t *api_params =
867  (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
868 
869  // reset all auxiliary data flag and length of encode frame
871  p_enc_frame->use_cur_src_as_long_term_pic =
872  p_enc_frame->use_long_term_ref = 0;
873 
874  p_enc_frame->sei_total_len = p_enc_frame->sei_cc_offset =
875  p_enc_frame->sei_cc_len =
880  p_enc_frame->sei_user_data_unreg_offset =
881  p_enc_frame->sei_user_data_unreg_len =
882  p_enc_frame->sei_hdr_plus_offset =
883  p_enc_frame->sei_hdr_plus_len = 0;
884 
885  // prep for NetInt intra period reconfiguration support: when intra period
886  // setting has been requested by both frame and API, API takes priority
887  int intraprd = -1;
888  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_INTRAPRD);
889  if (aux_data)
890  {
891  intraprd = *((int32_t *)aux_data->data);
892  if (intraprd < 0 || intraprd > 1024)
893  {
894  ni_log(NI_LOG_ERROR, "ERROR: %s(): invalid intraperiod in aux data %d\n",
895  __func__, intraprd);
896  intraprd = -1;
897  }
898  }
899 
900  if (p_enc_ctx->reconfig_intra_period >= 0)
901  {
902  intraprd = p_enc_ctx->reconfig_intra_period;
903  p_enc_ctx->reconfig_intra_period = -1;
904  ni_log(NI_LOG_DEBUG, "%s(): API set intraPeriod %d\n", __func__,
905  intraprd);
906  }
907 
908  if (intraprd >= 0)
909  {
910  if (api_params->cfg_enc_params.intra_mb_refresh_mode ||
911  api_params->cfg_enc_params.gop_preset_index == 1)
912  {
913  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): NOT allowed to reconfig intraPeriod %d in intra_mb_refresh_mode %d or gop_preset_index %d\n",
914  __func__,
915  intraprd,
917  api_params->cfg_enc_params.gop_preset_index);
918  }
919  else
920  {
921  // FW forces IDR frame when reconfig intra period, so the following steps are required for repeating SEI (and required for ni_should_send_sei_with_frame)
922  should_send_sei_with_frame = 1;
923  api_params->cfg_enc_params.intra_period = intraprd;
924 
925  if (intraprd)
926  {
927  p_enc_ctx->force_idr_intra_offset =
928  intraprd - (p_enc_ctx->frame_num % intraprd);
929  }
930  else
931  {
932  p_enc_ctx->force_idr_intra_offset = 0;
933  }
934 
935  p_enc_ctx->enc_change_params->enable_option |=
937  p_enc_ctx->enc_change_params->intraPeriod = intraprd;
938  ni_log(NI_LOG_INFO, "%s(): set intraPeriod %d on frame %u, update intra offset %u\n", __func__,
939  intraprd, p_enc_ctx->frame_num, p_enc_ctx->force_idr_intra_offset);
940  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
941  }
942  }
943 
944  // prep SEI for HDR (mastering display color volume)
945  aux_data = ni_frame_get_aux_data(
947  if (aux_data)
948  {
949  p_enc_ctx->mdcv_max_min_lum_data_len = 8;
951  8 + 6 * 2 + 2 * 2 + 2 * 4 + 1;
952  if (NI_CODEC_FORMAT_H264 == codec_format)
953  {
955  }
956 
959 
960  // save a copy
961  if (!p_enc_ctx->p_master_display_meta_data)
962  {
963  p_enc_ctx->p_master_display_meta_data = malloc(sizeof(ni_mastering_display_metadata_t));
964  }
965  if (!p_enc_ctx->p_master_display_meta_data)
966  {
967  ni_log2(p_enc_ctx, NI_LOG_ERROR, "Error mem alloc for mastering display color vol\n");
968  } else
969  {
970  memcpy(p_enc_ctx->p_master_display_meta_data, p_src,
972 
973  const int luma_den = MASTERING_DISP_LUMA_DEN;
974 
975  uint32_t uint32_t_tmp = htonl(
976  (uint32_t)(lrint(luma_den * ni_q2d(p_src->max_luminance))));
977  memcpy(p_enc_ctx->ui8_mdcv_max_min_lum_data, &uint32_t_tmp,
978  sizeof(uint32_t));
979  uint32_t_tmp = htonl(
980  (uint32_t)(lrint(luma_den * ni_q2d(p_src->min_luminance))));
981  memcpy(p_enc_ctx->ui8_mdcv_max_min_lum_data + 4, &uint32_t_tmp,
982  sizeof(uint32_t));
983 
984  // emulation prevention checking of luminance data
985  int emu_bytes_inserted = ni_insert_emulation_prevent_bytes(
986  p_enc_ctx->ui8_mdcv_max_min_lum_data, 2 * 4);
987 
988  p_enc_ctx->mdcv_max_min_lum_data_len += emu_bytes_inserted;
990  emu_bytes_inserted;
991  }
992  }
993 
995  p_enc_ctx->p_master_display_meta_data && should_send_sei_with_frame)
996  {
997  dst = mdcv_data;
998  dst[0] = dst[1] = dst[2] = 0;
999  dst[3] = 1;
1000 
1001  if (NI_CODEC_FORMAT_H264 == codec_format)
1002  {
1003  dst[4] = 0x6;
1004  dst[5] = 0x89; // payload type=137
1005  dst[6] = 0x18; // payload size=24
1006  dst += 7;
1007  } else
1008  {
1009  dst[4] = 0x4e;
1010  dst[5] = 1;
1011  dst[6] = 0x89; // payload type=137
1012  dst[7] = 0x18; // payload size=24
1013  dst += 8;
1014  }
1015 
1020  p_enc_ctx->p_master_display_meta_data;
1021 
1022  const int chroma_den = MASTERING_DISP_CHROMA_DEN;
1023  const int luma_den = MASTERING_DISP_LUMA_DEN;
1024 
1025  uint16_t dp00 = 0, dp01 = 0, dp10 = 0, dp11 = 0, dp20 = 0, dp21 = 0,
1026  wpx = 0, wpy = 0;
1027  // assuming p_src->has_primaries is always true
1028  // this is stored in r,g,b order and needs to be in g.b,r order
1029  // when sent to encoder
1030  dp00 = (uint16_t)lrint(chroma_den *
1031  ni_q2d(p_src->display_primaries[1][0]));
1032  p_mdcv->display_primaries[0][0] = htons(dp00);
1033  dp01 = (uint16_t)lrint(chroma_den *
1034  ni_q2d(p_src->display_primaries[1][1]));
1035  p_mdcv->display_primaries[0][1] = htons(dp01);
1036  dp10 = (uint16_t)lrint(chroma_den *
1037  ni_q2d(p_src->display_primaries[2][0]));
1038  p_mdcv->display_primaries[1][0] = htons(dp10);
1039  dp11 = (uint16_t)lrint(chroma_den *
1040  ni_q2d(p_src->display_primaries[2][1]));
1041  p_mdcv->display_primaries[1][1] = htons(dp11);
1042  dp20 = (uint16_t)lrint(chroma_den *
1043  ni_q2d(p_src->display_primaries[0][0]));
1044  p_mdcv->display_primaries[2][0] = htons(dp20);
1045  dp21 = (uint16_t)lrint(chroma_den *
1046  ni_q2d(p_src->display_primaries[0][1]));
1047  p_mdcv->display_primaries[2][1] = htons(dp21);
1048 
1049  wpx = (uint16_t)lrint(chroma_den * ni_q2d(p_src->white_point[0]));
1050  p_mdcv->white_point_x = htons(wpx);
1051  wpy = (uint16_t)lrint(chroma_den * ni_q2d(p_src->white_point[1]));
1052  p_mdcv->white_point_y = htons(wpy);
1053 
1054  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1055  "mastering display color volume, primaries "
1056  "%u/%u/%u/%u/%u/%u white_point_x/y %u/%u max/min_lumi %u/%u\n",
1057  (uint16_t)dp00, (uint16_t)dp01, (uint16_t)dp10, (uint16_t)dp11,
1058  (uint16_t)dp20, (uint16_t)dp21, (uint16_t)wpx, (uint16_t)wpy,
1059  (uint32_t)(luma_den * ni_q2d(p_src->max_luminance)),
1060  (uint32_t)(luma_den * ni_q2d(p_src->min_luminance)));
1061 
1062  dst += 6 * 2 + 2 * 2;
1063  memcpy(dst, p_enc_ctx->ui8_mdcv_max_min_lum_data,
1064  p_enc_ctx->mdcv_max_min_lum_data_len);
1065 
1066  dst += p_enc_ctx->mdcv_max_min_lum_data_len;
1067  *dst = 0x80;
1068 
1071 
1072  p_enc_frame->sei_total_len +=
1074  }
1075 
1076  // prep SEI for HDR (content light level info)
1077  aux_data = ni_frame_get_aux_data(p_dec_frame,
1079  if (aux_data)
1080  {
1081  // size of: start code + NAL unit header + payload type byte +
1082  // payload size byte + payload + rbsp trailing bits, default HEVC
1083  p_enc_ctx->light_level_data_len = 4;
1084  p_enc_ctx->sei_hdr_content_light_level_info_len = 8 + 2 * 2 + 1;
1085  if (NI_CODEC_FORMAT_H264 == codec_format)
1086  {
1088  }
1089 
1090  uint16_t max_content_light_level =
1091  htons(((ni_content_light_level_t *)aux_data->data)->max_cll);
1092  uint16_t max_pic_average_light_level =
1093  htons(((ni_content_light_level_t *)aux_data->data)->max_fall);
1094 
1095  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "content light level info, MaxCLL %u MaxFALL %u\n",
1096  ((ni_content_light_level_t *)aux_data->data)->max_cll,
1097  ((ni_content_light_level_t *)aux_data->data)->max_fall);
1098 
1099  memcpy(p_enc_ctx->ui8_light_level_data, &max_content_light_level,
1100  sizeof(uint16_t));
1101  memcpy(&(p_enc_ctx->ui8_light_level_data[2]),
1102  &max_pic_average_light_level, sizeof(uint16_t));
1103 
1104  // emulation prevention checking
1105  int emu_bytes_inserted = ni_insert_emulation_prevent_bytes(
1106  p_enc_ctx->ui8_light_level_data, p_enc_ctx->light_level_data_len);
1107 
1108  p_enc_ctx->light_level_data_len += emu_bytes_inserted;
1109  p_enc_ctx->sei_hdr_content_light_level_info_len += emu_bytes_inserted;
1110  }
1111 
1112  if (p_enc_ctx->sei_hdr_content_light_level_info_len &&
1113  should_send_sei_with_frame)
1114  {
1115  dst = cll_data;
1116  dst[0] = dst[1] = dst[2] = 0;
1117  dst[3] = 1;
1118 
1119  if (NI_CODEC_FORMAT_H264 == codec_format)
1120  {
1121  dst[4] = 0x6;
1122  dst[5] = 0x90; // payload type=144
1123  dst[6] = 4; // payload size=4
1124  dst += 7;
1125  } else
1126  {
1127  dst[4] = 0x4e;
1128  dst[5] = 1;
1129  dst[6] = 0x90; // payload type=144
1130  dst[7] = 4; // payload size=4
1131  dst += 8;
1132  }
1133 
1134  memcpy(dst, p_enc_ctx->ui8_light_level_data,
1135  p_enc_ctx->light_level_data_len);
1136  dst += p_enc_ctx->light_level_data_len;
1137  *dst = 0x80;
1138 
1141 
1142  p_enc_frame->sei_total_len +=
1144  }
1145 
1146  // prep SEI for close caption
1147  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_A53_CC);
1148  if (aux_data)
1149  {
1150  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data sei_cc_len %d\n", aux_data->size);
1151 
1152  uint8_t cc_data_emu_prevent[NI_MAX_SEI_DATA];
1153  int cc_size = aux_data->size;
1154  if (cc_size > NI_MAX_SEI_DATA)
1155  {
1156  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data sei_cc_len %d > MAX %d !\n",
1157  aux_data->size, (int)NI_MAX_SEI_DATA);
1158  cc_size = NI_MAX_SEI_DATA;
1159  }
1160  memcpy(cc_data_emu_prevent, aux_data->data, cc_size);
1161  int cc_size_emu_prevent = cc_size +
1162  ni_insert_emulation_prevent_bytes(cc_data_emu_prevent, cc_size);
1163  if (cc_size_emu_prevent != cc_size)
1164  {
1165  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data: close caption "
1166  "emulation prevention bytes added: %d\n",
1167  cc_size_emu_prevent - cc_size);
1168  }
1169 
1170  dst = cc_data;
1171  // set header info fields and extra size based on codec
1172  if (NI_CODEC_FORMAT_H265 == codec_format)
1173  {
1174  p_enc_frame->sei_cc_len = NI_CC_SEI_HDR_HEVC_LEN +
1175  cc_size_emu_prevent + NI_CC_SEI_TRAILER_LEN;
1176  p_enc_frame->sei_total_len += p_enc_frame->sei_cc_len;
1177 
1178  p_enc_ctx->itu_t_t35_cc_sei_hdr_hevc[7] = cc_size + 11;
1179  p_enc_ctx->itu_t_t35_cc_sei_hdr_hevc[16] = (cc_size / 3) | 0xc0;
1180 
1181  memcpy(dst, p_enc_ctx->itu_t_t35_cc_sei_hdr_hevc,
1183  dst += NI_CC_SEI_HDR_HEVC_LEN;
1184  memcpy(dst, cc_data_emu_prevent, cc_size_emu_prevent);
1185  dst += cc_size_emu_prevent;
1186  memcpy(dst, p_enc_ctx->sei_trailer, NI_CC_SEI_TRAILER_LEN);
1187  } else // H.264
1188  {
1189  p_enc_frame->sei_cc_len = NI_CC_SEI_HDR_H264_LEN +
1190  cc_size_emu_prevent + NI_CC_SEI_TRAILER_LEN;
1191  p_enc_frame->sei_total_len += p_enc_frame->sei_cc_len;
1192 
1193  p_enc_ctx->itu_t_t35_cc_sei_hdr_h264[6] = cc_size + 11;
1194  p_enc_ctx->itu_t_t35_cc_sei_hdr_h264[15] = (cc_size / 3) | 0xc0;
1195 
1196  memcpy(dst, p_enc_ctx->itu_t_t35_cc_sei_hdr_h264,
1198  dst += NI_CC_SEI_HDR_H264_LEN;
1199  memcpy(dst, cc_data_emu_prevent, cc_size_emu_prevent);
1200  dst += cc_size_emu_prevent;
1201  memcpy(dst, p_enc_ctx->sei_trailer, NI_CC_SEI_TRAILER_LEN);
1202  }
1203  }
1204 
1205  // prep SEI for HDR+
1206  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_HDR_PLUS);
1207  if (aux_data)
1208  {
1209  ni_dynamic_hdr_plus_t *hdrp = (ni_dynamic_hdr_plus_t *)aux_data->data;
1210  int w, i, j;
1212  uint32_t ui_tmp;
1213 
1215 
1216  // HDR10+ SEI header bytes
1217 
1218  // itu_t_t35_provider_code and itu_t_t35_provider_oriented_code are
1219  // contained in the first 4 bytes of payload; pb has all the data until
1220  // start of trailer
1221  ni_bs_writer_put(&pb, 0, 8);
1222  ni_bs_writer_put(&pb, 0x3c,
1223  8); // u16 itu_t_t35_provider_code = 0x003c
1224  ni_bs_writer_put(&pb, 0, 8);
1225  // u16 itu_t_t35_provider_oriented_code = 0x0001
1226  ni_bs_writer_put(&pb, 0x01, 8);
1227  ni_bs_writer_put(&pb, 4, 8); // u8 application_identifier = 0x04
1228  ni_bs_writer_put(&pb, hdrp->application_version, 8);
1229  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ application_version %u\n", hdrp->application_version);
1230 
1231  ni_bs_writer_put(&pb, hdrp->num_windows, 2);
1232  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ num_windows %u\n", hdrp->num_windows);
1233  for (w = 1; w < hdrp->num_windows; w++)
1234  {
1236  &pb, hdrp->params[w - 1].window_upper_left_corner_x.num, 16);
1238  &pb, hdrp->params[w - 1].window_upper_left_corner_y.num, 16);
1240  &pb, hdrp->params[w - 1].window_lower_right_corner_x.num, 16);
1242  &pb, hdrp->params[w - 1].window_lower_right_corner_y.num, 16);
1243  ni_bs_writer_put(&pb, hdrp->params[w - 1].center_of_ellipse_x, 16);
1244  ni_bs_writer_put(&pb, hdrp->params[w - 1].center_of_ellipse_y, 16);
1245  ni_bs_writer_put(&pb, hdrp->params[w - 1].rotation_angle, 8);
1247  &pb, hdrp->params[w - 1].semimajor_axis_internal_ellipse, 16);
1249  &pb, hdrp->params[w - 1].semimajor_axis_external_ellipse, 16);
1251  &pb, hdrp->params[w - 1].semiminor_axis_external_ellipse, 16);
1253  1);
1254  }
1255 
1256  // values are scaled up according to standard spec
1257  ui_tmp = lrint(10000 *
1259  ni_bs_writer_put(&pb, ui_tmp, 27);
1262  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ targeted_system_display_maximum_luminance "
1263  "%u\n",
1264  ui_tmp);
1265  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1266  "hdr10+ targeted_system_display_actual_peak_luminance_"
1267  "flag %u\n",
1269 
1271  {
1273  &pb,
1275  5);
1277  &pb,
1279  5);
1280  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1281  "hdr10+ num_rows_targeted_system_display_actual_peak_luminance "
1282  "x num_cols_targeted_system_display_actual_peak_luminance %u x "
1283  "%u\n",
1286 
1287  for (i = 0; i <
1289  i++)
1290  for (
1291  j = 0; j <
1293  j++)
1294  {
1295  ui_tmp = lrint(
1296  15 *
1297  ni_q2d(
1299  [i][j]));
1300  ni_bs_writer_put(&pb, ui_tmp, 4);
1301  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ targeted_system_display_actual_peak_"
1302  "luminance[%d][%d] %u\n",
1303  i, j, ui_tmp);
1304  }
1305  }
1306 
1307  for (w = 0; w < hdrp->num_windows; w++)
1308  {
1309  for (i = 0; i < 3; i++)
1310  {
1311  ui_tmp = lrint(100000 * ni_q2d(hdrp->params[w].maxscl[i]));
1312  ni_bs_writer_put(&pb, ui_tmp, 17);
1313  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ maxscl[%d][%d] %u\n", w, i, ui_tmp);
1314  }
1315  ui_tmp = lrint(100000 * ni_q2d(hdrp->params[w].average_maxrgb));
1316  ni_bs_writer_put(&pb, ui_tmp, 17);
1317  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ average_maxrgb[%d] %u\n", w, ui_tmp);
1318 
1320  &pb, hdrp->params[w].num_distribution_maxrgb_percentiles, 4);
1321  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1322  "hdr10+ num_distribution_maxrgb_percentiles[%d] %d\n", w,
1324 
1325  for (i = 0; i < hdrp->params[w].num_distribution_maxrgb_percentiles;
1326  i++)
1327  {
1329  &pb, hdrp->params[w].distribution_maxrgb[i].percentage, 7);
1330  ui_tmp = lrint(
1331  100000 *
1332  ni_q2d(hdrp->params[w].distribution_maxrgb[i].percentile));
1333  ni_bs_writer_put(&pb, ui_tmp, 17);
1334  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1335  "hdr10+ distribution_maxrgb_percentage[%d][%d] %u\n", w, i,
1336  hdrp->params[w].distribution_maxrgb[i].percentage);
1337  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1338  "hdr10+ distribution_maxrgb_percentile[%d][%d] %u\n", w, i,
1339  ui_tmp);
1340  }
1341 
1342  ui_tmp =
1343  lrint(1000 * ni_q2d(hdrp->params[w].fraction_bright_pixels));
1344  ni_bs_writer_put(&pb, ui_tmp, 10);
1345  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ fraction_bright_pixels[%d] %u\n", w, ui_tmp);
1346  }
1347 
1348  ni_bs_writer_put(&pb,
1350  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1351  "hdr10+ mastering_display_actual_peak_luminance_flag %u\n",
1354  {
1359  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1360  "hdr10+ num_rows_mastering_display_actual_peak_luminance x "
1361  "num_cols_mastering_display_actual_peak_luminance %u x %u\n",
1364 
1365  for (i = 0;
1367  i++)
1368  for (j = 0;
1370  j++)
1371  {
1372  ui_tmp = lrint(
1373  15 *
1374  ni_q2d(
1376  [j]));
1377  ni_bs_writer_put(&pb, ui_tmp, 4);
1378  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1379  "hdr10+ "
1380  "mastering_display_actual_peak_luminance[%d][%d] %u\n",
1381  i, j, ui_tmp);
1382  }
1383  }
1384 
1385  for (w = 0; w < hdrp->num_windows; w++)
1386  {
1387  ni_bs_writer_put(&pb, hdrp->params[w].tone_mapping_flag, 1);
1388  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ tone_mapping_flag[%d] %u\n", w,
1389  hdrp->params[w].tone_mapping_flag);
1390 
1391  if (hdrp->params[w].tone_mapping_flag)
1392  {
1393  ui_tmp = lrint(4095 * ni_q2d(hdrp->params[w].knee_point_x));
1394  ni_bs_writer_put(&pb, ui_tmp, 12);
1395  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ knee_point_x[%d] %u\n", w, ui_tmp);
1396 
1397  ui_tmp = lrint(4095 * ni_q2d(hdrp->params[w].knee_point_y));
1398  ni_bs_writer_put(&pb, ui_tmp, 12);
1399  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ knee_point_y[%d] %u\n", w, ui_tmp);
1400 
1402  4);
1403  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ num_bezier_curve_anchors[%d] %u\n", w,
1404  hdrp->params[w].num_bezier_curve_anchors);
1405  for (i = 0; i < hdrp->params[w].num_bezier_curve_anchors; i++)
1406  {
1407  ui_tmp = lrint(
1408  1023 * ni_q2d(hdrp->params[w].bezier_curve_anchors[i]));
1409  ni_bs_writer_put(&pb, ui_tmp, 10);
1410  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ bezier_curve_anchors[%d][%d] %u\n",
1411  w, i, ui_tmp);
1412  }
1413  }
1414 
1416  1);
1417  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ color_saturation_mapping_flag[%d] %u\n", w,
1420  {
1421  ui_tmp =
1422  lrint(8 * ni_q2d(hdrp->params[w].color_saturation_weight));
1423  ni_bs_writer_put(&pb, 6, ui_tmp);
1424  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ color_saturation_weight[%d] %u\n", w,
1425  ui_tmp);
1426  }
1427  } // num_windows
1428 
1429  uint64_t hdr10p_num_bytes = (ni_bs_writer_tell(&pb) + 7) / 8;
1430  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ total bits: %d -> bytes %" PRIu64 "\n",
1431  (int)ni_bs_writer_tell(&pb), hdr10p_num_bytes);
1433 
1434  dst = hdrp_data;
1435 
1436  // emulation prevention checking of payload
1437  int emu_bytes_inserted;
1438 
1439  // set header info fields and extra size based on codec
1440  if (NI_CODEC_FORMAT_H265 == codec_format)
1441  {
1442  p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_hevc[7] =
1443  (uint8_t)hdr10p_num_bytes + NI_RBSP_TRAILING_BITS_LEN;
1444 
1445  memcpy(dst, p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_hevc,
1448  ni_bs_writer_copy(dst, &pb);
1449 
1450  emu_bytes_inserted =
1451  ni_insert_emulation_prevent_bytes(dst, (int)hdr10p_num_bytes);
1452  dst += hdr10p_num_bytes + emu_bytes_inserted;
1453  *dst = p_enc_ctx->sei_trailer[1];
1454  //dst += NI_RBSP_TRAILING_BITS_LEN;
1455 
1457  (uint32_t)hdr10p_num_bytes + emu_bytes_inserted +
1459  p_enc_frame->sei_total_len += p_enc_frame->sei_hdr_plus_len;
1460  } else if (NI_CODEC_FORMAT_H264 == codec_format)
1461  {
1462  p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_h264[6] =
1463  (uint8_t)hdr10p_num_bytes + NI_RBSP_TRAILING_BITS_LEN;
1464 
1465  memcpy(dst, p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_h264,
1468  ni_bs_writer_copy(dst, &pb);
1469 
1470  emu_bytes_inserted =
1471  ni_insert_emulation_prevent_bytes(dst, (int)hdr10p_num_bytes);
1472  dst += hdr10p_num_bytes + emu_bytes_inserted;
1473  *dst = p_enc_ctx->sei_trailer[1];
1474  //dst += NI_RBSP_TRAILING_BITS_LEN;
1475 
1477  (uint8_t)hdr10p_num_bytes + emu_bytes_inserted +
1479  p_enc_frame->sei_total_len += p_enc_frame->sei_hdr_plus_len;
1480  } else
1481  {
1482  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1483  "ni_enc_prep_aux_data: codec %d not supported for HDR10+ "
1484  "SEI !\n",
1485  codec_format);
1486  p_enc_frame->sei_hdr_plus_len = 0;
1487  }
1488 
1489  ni_bs_writer_clear(&pb);
1490  } // hdr10+
1491 
1492  // prep SEI for User Data Unregistered
1493  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_UDU_SEI);
1494  if (aux_data)
1495  {
1496  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data sei_user_data_unreg_len %d\n",
1497  aux_data->size);
1498 
1499  // emulation prevention checking: a working buffer of size in worst case
1500  // that each two bytes comes with 1B emulation prevention byte
1501  int udu_sei_size = aux_data->size;
1502  int ext_udu_sei_size, sei_len;
1503 
1504  uint8_t *sei_data = malloc(udu_sei_size * 3 / 2);
1505  if (sei_data)
1506  {
1507  memcpy(sei_data, (uint8_t *)aux_data->data, udu_sei_size);
1508  int emu_bytes_inserted =
1509  ni_insert_emulation_prevent_bytes(sei_data, udu_sei_size);
1510 
1511  ext_udu_sei_size = udu_sei_size + emu_bytes_inserted;
1512 
1513  if (NI_CODEC_FORMAT_H264 == codec_format)
1514  {
1515  /* 4B long start code + 1B nal header + 1B SEI type + Bytes of
1516  payload length + Bytes of SEI payload + 1B trailing */
1517  sei_len =
1518  6 + ((udu_sei_size + 0xFE) / 0xFF) + ext_udu_sei_size + 1;
1519  } else
1520  {
1521  /* 4B long start code + 2B nal header + 1B SEI type + Bytes of
1522  payload length + Bytes of SEI payload + 1B trailing */
1523  sei_len =
1524  7 + ((udu_sei_size + 0xFE) / 0xFF) + ext_udu_sei_size + 1;
1525  }
1526 
1527  // discard this UDU SEI if the total SEI size exceeds the max size
1528  if (p_enc_frame->sei_total_len + sei_len > NI_ENC_MAX_SEI_BUF_SIZE)
1529  {
1530  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1531  "ni_enc_prep_aux_data sei total length %u + sei_len %d "
1532  "exceeds maximum sei size %u, discarding it !\n",
1533  p_enc_frame->sei_total_len, sei_len,
1535  } else
1536  {
1537  int payload_size = udu_sei_size;
1538 
1539  dst = udu_data;
1540  *dst++ = 0x00; // long start code
1541  *dst++ = 0x00;
1542  *dst++ = 0x00;
1543  *dst++ = 0x01;
1544 
1545  if (NI_CODEC_FORMAT_H264 == codec_format)
1546  {
1547  *dst++ = 0x06; // nal type: SEI
1548  } else
1549  {
1550  *dst++ = 0x4e; // nal type: SEI
1551  *dst++ = 0x01;
1552  }
1553  *dst++ = 0x05; // SEI type: user data unregistered
1554 
1555  // original payload size
1556  while (payload_size > 0)
1557  {
1558  *dst++ =
1559  (payload_size > 0xFF ? 0xFF : (uint8_t)payload_size);
1560  payload_size -= 0xFF;
1561  }
1562 
1563  // payload data after emulation prevention checking
1564  memcpy(dst, sei_data, ext_udu_sei_size);
1565  dst += ext_udu_sei_size;
1566 
1567  // trailing byte
1568  *dst = 0x80;
1569  dst++;
1570 
1571  // save UDU data length
1572  p_enc_frame->sei_user_data_unreg_len = sei_len;
1573  p_enc_frame->sei_total_len += sei_len;
1574  }
1575 
1576  free(sei_data);
1577  sei_data = NULL;
1578  }
1579  }
1580 
1581  // supply QP map if ROI enabled and if ROIs passed in as aux data
1582  aux_data = ni_frame_get_aux_data(p_dec_frame,
1584  if (api_params->cfg_enc_params.roi_enable && aux_data)
1585  {
1586  int is_new_rois = 1;
1587  const ni_region_of_interest_t *roi = NULL;
1588  uint32_t self_size = 0;
1589 
1590  roi = (const ni_region_of_interest_t *)aux_data->data;
1591  self_size = roi->self_size;
1592  if (!self_size || aux_data->size % self_size)
1593  {
1594  ni_log2(p_enc_ctx, NI_LOG_ERROR, "Invalid ni_region_of_interest_t.self_size, "
1595  "aux_data size %d self_size %u\n",
1596  aux_data->size, self_size);
1597  } else
1598  {
1599  int nb_roi = aux_data->size / (int)self_size;
1600 
1601  // update ROI(s) if new/different from last one
1602  if (0 == p_enc_ctx->nb_rois || 0 == p_enc_ctx->roi_side_data_size ||
1603  !p_enc_ctx->av_rois || p_enc_ctx->nb_rois != nb_roi ||
1604  p_enc_ctx->roi_side_data_size != aux_data->size ||
1605  memcmp(p_enc_ctx->av_rois, aux_data->data, aux_data->size) != 0)
1606  {
1607  p_enc_ctx->roi_side_data_size = aux_data->size;
1608  p_enc_ctx->nb_rois = nb_roi;
1609 
1610  free(p_enc_ctx->av_rois);
1611  p_enc_ctx->av_rois = malloc(aux_data->size);
1612  if (!p_enc_ctx->av_rois)
1613  {
1614  ni_log2(p_enc_ctx, NI_LOG_ERROR, "malloc ROI aux_data failed.\n");
1615  is_new_rois = 0;
1616  } else
1617  {
1618  memcpy(p_enc_ctx->av_rois, aux_data->data, aux_data->size);
1619  }
1620  } else
1621  {
1622  is_new_rois = 0;
1623  }
1624 
1625  if (is_new_rois)
1626  {
1627  if (set_roi_map(p_enc_ctx, codec_format, aux_data, nb_roi,
1628  api_params->source_width,
1629  api_params->source_height,
1630  api_params->cfg_enc_params.rc.intra_qp))
1631  {
1632  ni_log2(p_enc_ctx, NI_LOG_ERROR, "set_roi_map failed\n");
1633  }
1634  }
1635  }
1636 
1637  // ROI data in the frame
1638  p_enc_frame->roi_len = p_enc_ctx->roi_len;
1639  }
1640 
1641  // when ROI is enabled, a QP map is always supplied with each frame, and
1642  // we use frame->roi_len value to: when 0, supply a zeroed map; when non-0,
1643  // supply the map stored in p_enc_ctx->roi_map.
1644  // - if ROI aux data is present, use it, otherwise:
1645  // - if cacheRoi, use map if exists, use 0 map otherwise
1646  // - if !cacheRoi, use 0 map
1647  // Note: the above excludes the demo modes which is handled separately in
1648  // application (e.g. nienc, xcoder)
1649  if (api_params->cfg_enc_params.roi_enable && !api_params->roi_demo_mode)
1650  {
1651  if (aux_data && p_enc_ctx->roi_map)
1652  {
1653  p_enc_frame->roi_len = p_enc_ctx->roi_len;
1654  } else
1655  {
1656  if (api_params->cacheRoi)
1657  {
1658  p_enc_frame->roi_len =
1659  (p_enc_ctx->roi_map ? p_enc_ctx->roi_len : 0);
1660  } else
1661  {
1662  p_enc_frame->roi_len = 0;
1663  }
1664  }
1665 
1666  p_enc_frame->extra_data_len += p_enc_ctx->roi_len;
1667 
1668  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data: supply QP map, cacheRoi %d "
1669  "aux_data %d ctx->roi_map %d frame->roi_len %u ctx->roi_len %u\n",
1670  api_params->cacheRoi, aux_data != NULL,
1671  p_enc_ctx->roi_map != NULL, p_enc_frame->roi_len, p_enc_ctx->roi_len);
1672  }
1673 
1674  // prep for NetInt long term reference frame support setting: when this has
1675  // been requested by both frame and API, API takes priority
1676  ni_long_term_ref_t ltr = {0};
1677  aux_data =
1679  if (aux_data)
1680  {
1681  ltr = *((ni_long_term_ref_t *)aux_data->data);
1682  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1683  "%s(): frame aux data LTR use_cur_src_as_ltr %u "
1684  "use_ltr %u\n",
1685  __func__, ltr.use_cur_src_as_long_term_pic,
1686  ltr.use_long_term_ref);
1687  }
1688 
1689  if (p_enc_ctx->ltr_to_set.use_cur_src_as_long_term_pic > 0)
1690  {
1691  ltr = p_enc_ctx->ltr_to_set;
1693  p_enc_ctx->ltr_to_set.use_long_term_ref = 0;
1694 
1695  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1696  "%s(): frame API set LTR use_cur_src_as_ltr %u "
1697  "use_ltr %u\n",
1698  __func__, ltr.use_cur_src_as_long_term_pic,
1699  ltr.use_long_term_ref);
1700  }
1701 
1702  if (ltr.use_cur_src_as_long_term_pic > 0)
1703  {
1704  p_enc_frame->use_cur_src_as_long_term_pic =
1706  p_enc_frame->use_long_term_ref = ltr.use_long_term_ref;
1707  }
1708 
1709  // prep for NetInt target max/min QP reconfiguration support: when max/min QP
1710  // setting has been requested by both frame and API, API takes priority
1711  ni_rc_min_max_qp qp_info = {0};
1712  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_MAX_MIN_QP);
1713  if (aux_data)
1714  {
1715  qp_info = *(ni_rc_min_max_qp *)aux_data->data;
1716  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1717  "%s(): frame aux data qp info max/min I qp <%d %d> maxDeltaQp <%d> max/min PB qp <%d %d>",
1718  __func__, qp_info.maxQpI, qp_info.minQpI, qp_info.maxDeltaQp, qp_info.maxQpPB, qp_info.minQpPB);
1719  }
1720  if (qp_info.maxQpI > 0)
1721  {
1722  p_enc_ctx->enc_change_params->minQpI = qp_info.minQpI;
1723  p_enc_ctx->enc_change_params->maxQpI = qp_info.maxQpI;
1724  p_enc_ctx->enc_change_params->maxDeltaQp = qp_info.maxDeltaQp;
1725  p_enc_ctx->enc_change_params->minQpPB = qp_info.minQpPB;
1726  p_enc_ctx->enc_change_params->maxQpPB = qp_info.maxQpPB;
1727  p_enc_ctx->enc_change_params->enable_option |=
1729  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1730  }
1731 
1732  // prep for NetInt target bitrate reconfiguration support: when bitrate
1733  // setting has been requested by both frame and API, API takes priority
1734  int32_t bitrate = -1;
1735  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_BITRATE);
1736  if (aux_data)
1737  {
1738  bitrate = *((int32_t *)aux_data->data);
1739  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data bitrate %d\n", __func__,
1740  bitrate);
1741  }
1742 
1743  if (p_enc_ctx->target_bitrate > 0)
1744  {
1745  bitrate = p_enc_ctx->target_bitrate;
1746  p_enc_ctx->target_bitrate = -1;
1747  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set bitrate %d\n", __func__, bitrate);
1748  }
1749 
1750  if (bitrate > 0)
1751  {
1752  p_enc_ctx->enc_change_params->enable_option |=
1754 
1755  p_enc_ctx->enc_change_params->bitRate = bitrate;
1756  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1757 
1758  // update last bitrate with reconfigured bitrate
1759  p_enc_ctx->last_bitrate = bitrate;
1760  ni_log2(p_enc_ctx, NI_LOG_INFO, "%s: bitrate %d updated for reconfig\n", __func__, bitrate);
1761  }
1762 
1763  // prep for NetInt API force frame type
1764  if (p_enc_ctx->force_idr_frame)
1765  {
1766  p_enc_frame->force_key_frame = 1;
1767  p_enc_frame->ni_pict_type = PIC_TYPE_IDR;
1768 
1769  p_enc_ctx->force_idr_frame = 0;
1770  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API force IDR frame\n", __func__);
1771  }
1772 
1773  // prep for NetInt VUI reconfiguration support: when VUI HRD
1774  // setting has been requested by both frame and API, API takes priority
1775  ni_vui_hrd_t vui = {0};
1776  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_VUI);
1777  if (aux_data)
1778  {
1779  ni_vui_hrd_t *aux_vui_ptr = (ni_vui_hrd_t *)aux_data->data;
1780 
1781  if (aux_vui_ptr->colorDescPresent < 0 || aux_vui_ptr->colorDescPresent > 1)
1782  {
1783  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid colorDescPresent in aux data %d\n",
1784  __func__, aux_vui_ptr->colorDescPresent);
1785  }
1786  else
1787  {
1788  vui.colorDescPresent = aux_vui_ptr->colorDescPresent;
1789  }
1790 
1791  if((aux_vui_ptr->aspectRatioWidth > NI_MAX_ASPECTRATIO) || (aux_vui_ptr->aspectRatioHeight > NI_MAX_ASPECTRATIO))
1792  {
1793  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid aspect ratio in aux data %dx%d\n",
1794  __func__, aux_vui_ptr->aspectRatioWidth, aux_vui_ptr->aspectRatioHeight);
1795  }
1796  else
1797  {
1798  vui.colorDescPresent = aux_vui_ptr->colorDescPresent;
1799  vui.colorPrimaries = aux_vui_ptr->colorPrimaries;
1800  vui.colorTrc = aux_vui_ptr->colorTrc;
1801  vui.colorSpace = aux_vui_ptr->colorSpace;
1802  vui.aspectRatioWidth = aux_vui_ptr->aspectRatioWidth;
1803  vui.aspectRatioHeight = aux_vui_ptr->aspectRatioHeight;
1804  }
1805 
1806  if (aux_vui_ptr->videoFullRange < 0 || aux_vui_ptr->videoFullRange > 1)
1807  {
1808  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid videoFullRange in aux data %d\n",
1809  __func__, aux_vui_ptr->videoFullRange);
1810  }
1811  else
1812  {
1813  vui.videoFullRange = aux_vui_ptr->videoFullRange;
1814  }
1815  }
1816 
1817  if (p_enc_ctx->vui.aspectRatioWidth > 0)
1818  {
1819  vui = p_enc_ctx->vui;
1820  p_enc_ctx->vui.colorDescPresent =
1821  p_enc_ctx->vui.colorPrimaries =
1822  p_enc_ctx->vui.colorTrc =
1823  p_enc_ctx->vui.colorSpace =
1824  p_enc_ctx->vui.aspectRatioWidth =
1825  p_enc_ctx->vui.aspectRatioHeight =
1826  p_enc_ctx->vui.videoFullRange = 0;
1827  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set VUI "
1828  "colorDescPresent %d colorPrimaries %d "
1829  "colorTrc %d colorSpace %d aspectRatioWidth %d "
1830  "aspectRatioHeight %d videoFullRange %d\n",
1831  __func__, vui.colorDescPresent,
1832  vui.colorPrimaries, vui.colorTrc,
1833  vui.colorSpace, vui.aspectRatioWidth,
1835  }
1836 
1837  if (vui.aspectRatioWidth > 0)
1838  {
1839  p_enc_ctx->enc_change_params->enable_option |=
1841 
1844  p_enc_ctx->enc_change_params->colorTrc = vui.colorTrc;
1845  p_enc_ctx->enc_change_params->colorSpace = vui.colorSpace;
1849  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1850  }
1851 
1852  // prep for NetInt long term reference interval reconfiguration support:
1853  // when LTR has been requested by both frame and API, API takes priority
1854  int32_t ltr_interval = -1;
1855  aux_data =
1857  if (aux_data)
1858  {
1859  ltr_interval = *((int32_t *)aux_data->data);
1860  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data LTR interval %d\n", __func__,
1861  ltr_interval);
1862  }
1863 
1864  if (p_enc_ctx->ltr_interval > 0)
1865  {
1866  ltr_interval = p_enc_ctx->ltr_interval;
1867  p_enc_ctx->ltr_interval = -1;
1868  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set LTR interval %d\n", __func__,
1869  ltr_interval);
1870  }
1871 
1872  if (ltr_interval > 0)
1873  {
1874  p_enc_ctx->enc_change_params->enable_option |=
1876 
1877  p_enc_ctx->enc_change_params->ltrInterval = ltr_interval;
1878  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1879  }
1880 
1881  // prep for NetInt target framerate reconfiguration support: when framerate
1882  // setting has been requested by both frame aux data and API, API takes priority
1883  ni_framerate_t framerate = {0};
1884  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_FRAMERATE);
1885  if (aux_data)
1886  {
1887  ni_framerate_t *aux_framerate_ptr = (ni_framerate_t *)aux_data->data;
1888  int32_t framerate_num = aux_framerate_ptr->framerate_num;
1889  int32_t framerate_denom = aux_framerate_ptr->framerate_denom;
1890  if ((framerate_num <= 0) || (framerate_denom <= 0))
1891  {
1892  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1893  "ERROR: %s(): invalid framerate in aux data (%d/%d)\n",
1894  __func__, framerate_num, framerate_denom);
1895  } else
1896  {
1897  if ((framerate_num % framerate_denom) != 0)
1898  {
1899  uint32_t numUnitsInTick = 1000;
1900  framerate_num = framerate_num / framerate_denom;
1901  framerate_denom = numUnitsInTick + 1;
1902  framerate_num += 1;
1903  framerate_num *= numUnitsInTick;
1904  } else
1905  {
1906  framerate_num = framerate_num / framerate_denom;
1907  framerate_denom = 1;
1908  }
1909  if (((framerate_num + framerate_denom - 1) / framerate_denom) >
1911  {
1912  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1913  "ERROR: %s(): invalid framerate in aux data (%d/%d)\n",
1914  __func__, aux_framerate_ptr->framerate_num,
1915  aux_framerate_ptr->framerate_denom);
1916  } else
1917  {
1918  framerate.framerate_num = framerate_num;
1919  framerate.framerate_denom = framerate_denom;
1920  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data framerate (%d/%d)\n",
1921  __func__, framerate_num, framerate_denom);
1922  }
1923  }
1924  }
1925 
1926  if (p_enc_ctx->framerate.framerate_num > 0)
1927  {
1928  framerate = p_enc_ctx->framerate;
1929  p_enc_ctx->framerate.framerate_num =
1930  p_enc_ctx->framerate.framerate_denom = 0;
1931  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set framerate (%d/%d)\n", __func__,
1932  framerate.framerate_num, framerate.framerate_denom);
1933  }
1934 
1935  if (framerate.framerate_num > 0)
1936  {
1937  p_enc_ctx->enc_change_params->enable_option |=
1939 
1940  p_enc_ctx->enc_change_params->frameRateNum = framerate.framerate_num;
1941  p_enc_ctx->enc_change_params->frameRateDenom =
1942  framerate.framerate_denom;
1943  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1944 
1945  // update last framerate with reconfigured framerate
1946  p_enc_ctx->last_framerate.framerate_num = framerate.framerate_num;
1947  p_enc_ctx->last_framerate.framerate_denom = framerate.framerate_denom;
1948  ni_log2(p_enc_ctx, NI_LOG_INFO, "%s: framerate num %d denom %d updated for reconfig\n",
1949  __func__, framerate.framerate_num, framerate.framerate_denom);
1950  }
1951 
1952  // prep for NetInt frame reference invalidation support: when this setting
1953  // has been requested by both frame and API, API takes priority
1954  int32_t frame_num = -1;
1955  aux_data =
1957  if (aux_data)
1958  {
1959  frame_num = *((int32_t *)aux_data->data);
1960  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data frame ref invalid %d\n",
1961  __func__, frame_num);
1962  }
1963 
1964  if (p_enc_ctx->ltr_frame_ref_invalid > 0)
1965  {
1966  frame_num = p_enc_ctx->ltr_frame_ref_invalid;
1967  p_enc_ctx->ltr_frame_ref_invalid = -1;
1968  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s(): API set frame ref invalid %d\n", __func__,
1969  frame_num);
1970  }
1971 
1972  if (frame_num >= 0)
1973  {
1974  p_enc_ctx->enc_change_params->enable_option |=
1976 
1977  p_enc_ctx->enc_change_params->invalidFrameNum = frame_num;
1978  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1979  }
1980 
1981  // prep for alternative preferred transfer characteristics SEI
1982  if (api_params->cfg_enc_params.preferred_transfer_characteristics >= 0 &&
1983  should_send_sei_with_frame)
1984  {
1985  if (NI_CODEC_FORMAT_H264 == codec_format)
1986  {
1987  p_enc_frame->preferred_characteristics_data_len = 9;
1988  } else
1989  {
1990  p_enc_frame->preferred_characteristics_data_len = 10;
1991  }
1992 
1993  p_enc_ctx->preferred_characteristics_data =
1994  (uint8_t)
1996  p_enc_frame->sei_total_len +=
1998  }
1999 
2000  // prep for NetInt maxFrameSize reconfiguration support: when maxFrameSize
2001  // setting has been requested by both frame aux data and API, API takes priority
2002  int32_t max_frame_size = 0;
2004  if (aux_data)
2005  {
2006  max_frame_size = *((int32_t *)aux_data->data);
2007  uint32_t maxFrameSize = (uint32_t)max_frame_size / 2000;
2008  uint32_t min_maxFrameSize;
2009  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data max_frame_size %d\n", __func__,
2010  max_frame_size);
2011 
2012  if (!api_params->low_delay_mode)
2013  {
2014  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is valid only when lowDelay mode is enabled\n",
2015  __func__, max_frame_size);
2016  max_frame_size = 0;
2017  }
2018  else
2019  {
2020  int32_t tmp_bitrate, tmp_framerate_num, tmp_framerate_denom;
2021  tmp_bitrate = (p_enc_ctx->enc_change_params->bitRate > 0) ? p_enc_ctx->enc_change_params->bitRate : api_params->bitrate;
2022 
2023  if ((p_enc_ctx->enc_change_params->frameRateNum > 0) && (p_enc_ctx->enc_change_params->frameRateDenom > 0))
2024  {
2025  tmp_framerate_num = p_enc_ctx->enc_change_params->frameRateNum;
2026  tmp_framerate_denom = p_enc_ctx->enc_change_params->frameRateDenom;
2027  }
2028  else
2029  {
2030  tmp_framerate_num = (int32_t)api_params->fps_number;
2031  tmp_framerate_denom = (int32_t)api_params->fps_denominator;
2032  }
2033 
2034  min_maxFrameSize = (((uint32_t)tmp_bitrate / tmp_framerate_num * tmp_framerate_denom) / 8) / 2000;
2035 
2036  if (maxFrameSize < min_maxFrameSize)
2037  {
2038  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is too small (invalid)\n",
2039  __func__, max_frame_size);
2040  max_frame_size = 0;
2041  }
2042 
2043  if (max_frame_size > NI_MAX_FRAME_SIZE) {
2044  max_frame_size = NI_MAX_FRAME_SIZE;
2045  }
2046  }
2047  }
2048 
2049  if (p_enc_ctx->max_frame_size > 0)
2050  {
2051  max_frame_size = p_enc_ctx->max_frame_size;
2052  p_enc_ctx->max_frame_size = 0;
2053  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set max_frame_size %d\n", __func__, max_frame_size);
2054  }
2055 
2056  if (max_frame_size > 0)
2057  {
2058  p_enc_ctx->enc_change_params->enable_option |=
2060 
2061  p_enc_ctx->enc_change_params->maxFrameSize = (uint16_t)(max_frame_size / 2000);
2062  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2063  }
2064 
2065  // prep for NetInt crf reconfiguration support: when crf
2066  // setting has been requested by both frame aux data and API, API takes priority
2067  float crf = -1.0f;
2068  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_CRF);
2069  if (aux_data)
2070  {
2071  crf = (float)(*((int32_t *)aux_data->data));
2072  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data crf %d\n", __func__,
2073  crf);
2074 
2075  if (api_params->cfg_enc_params.crf < 0)
2076  {
2077  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %d is valid only in CRF mode\n",
2078  __func__, crf);
2079  crf = -1;
2080  }
2081  else
2082  {
2083  if (crf < 0 || crf > 51)
2084  {
2085  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %d is invalid (valid range in [0..51])\n",
2086  __func__, crf);
2087  crf = -1;
2088  }
2089  }
2090  }
2091  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_CRF_FLOAT);
2092  if (aux_data)
2093  {
2094  crf = *((float *)aux_data->data);
2095  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data crf %f\n", __func__,
2096  crf);
2097 
2098  if (api_params->cfg_enc_params.crfFloat < 0)
2099  {
2100  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %f is valid only in CRF mode\n",
2101  __func__, crf);
2102  crf = -1;
2103  }
2104  else
2105  {
2106  if (crf < 0 || crf > 51)
2107  {
2108  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %f is invalid (valid range in [0..51])\n",
2109  __func__, crf);
2110  crf = -1;
2111  }
2112  }
2113  }
2114 
2115  if (p_enc_ctx->reconfig_crf >= 0 || p_enc_ctx->reconfig_crf_decimal > 0)
2116  {
2117  crf = (float)(p_enc_ctx->reconfig_crf +
2118  (float)p_enc_ctx->reconfig_crf_decimal / 100.0);
2119  p_enc_ctx->reconfig_crf = -1;
2120  p_enc_ctx->reconfig_crf_decimal = 0;
2121  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_crf %f\n", __func__, crf);
2122  }
2123 
2124  if (crf >= 0)
2125  {
2126  p_enc_ctx->enc_change_params->enable_option |=
2128 
2129  p_enc_ctx->enc_change_params->crf = (uint8_t)crf;
2130  p_enc_ctx->enc_change_params->crfDecimal =
2131  (float)((crf - (float)p_enc_ctx->enc_change_params->crf) * 100);
2132  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2133  }
2134 
2135  int32_t vbvMaxRate = 0;
2136  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_VBV_MAX_RATE);
2137  if (aux_data)
2138  {
2139  vbvMaxRate = *((int32_t *)aux_data->data);
2140  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data vbvMaxRate %d\n", __func__,
2141  vbvMaxRate);
2142  }
2143 
2144  if (p_enc_ctx->reconfig_vbv_max_rate > 0)
2145  {
2146  vbvMaxRate = p_enc_ctx->reconfig_vbv_max_rate;
2147  p_enc_ctx->reconfig_vbv_max_rate = 0;
2148  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_vbv_max_rate %d\n", __func__, vbvMaxRate);
2149  }
2150 
2151  if (vbvMaxRate)
2152  {
2153  p_enc_ctx->enc_change_params->enable_option |=
2155 
2156  p_enc_ctx->enc_change_params->vbvMaxRate = vbvMaxRate;
2157  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2158  }
2159 
2160  int32_t vbvBufferSize = 0;
2162  if (aux_data)
2163  {
2164  vbvBufferSize = *((int32_t *)aux_data->data);
2165  if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
2166  {
2167  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s(): invalid frame aux data vbvBufferSize %d\n", __func__,
2168  vbvBufferSize);
2169  vbvBufferSize = 0;
2170  }
2171  else
2172  {
2173  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data vbvBufferSize %d\n", __func__,
2174  vbvBufferSize);
2175  }
2176  }
2177 
2178  if (p_enc_ctx->reconfig_vbv_buffer_size > 0)
2179  {
2180  vbvBufferSize = p_enc_ctx->reconfig_vbv_buffer_size;
2181  p_enc_ctx->reconfig_vbv_buffer_size = 0;
2182  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_vbv_max_rate %d\n", __func__, vbvBufferSize);
2183  }
2184 
2185  if (vbvBufferSize)
2186  {
2187  p_enc_ctx->enc_change_params->enable_option |=
2189 
2190  p_enc_ctx->enc_change_params->vbvBufferSize = vbvBufferSize;
2191  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2192  }
2193 
2194  int16_t sliceArg = 0;
2195  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_SLICE_ARG);
2196  if (aux_data)
2197  {
2198  sliceArg = *((int16_t *)aux_data->data);
2199  ni_encoder_cfg_params_t *p_enc = &api_params->cfg_enc_params;
2200  if (p_enc->slice_mode == 0)
2201  {
2202  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s():not support to reconfig slice_arg when slice_mode disable.\n",
2203  __func__);
2204  sliceArg = 0;
2205  }
2206  if (NI_CODEC_FORMAT_JPEG == p_enc_ctx->codec_format || NI_CODEC_FORMAT_AV1 == p_enc_ctx->codec_format)
2207  {
2208  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s():sliceArg is only supported for H.264 or H.265.\n",
2209  __func__);
2210  sliceArg = 0;
2211  }
2212  int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_enc_ctx->codec_format) ? 16 : 64;
2213  int max_num_ctu_mb_row = (api_params->source_height + ctu_mb_size - 1) / ctu_mb_size;
2214  if (sliceArg < 1 || sliceArg > max_num_ctu_mb_row)
2215  {
2216  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s(): invalid frame aux data sliceArg %d\n", __func__,
2217  sliceArg);
2218  sliceArg = 0;
2219  }
2220  else
2221  {
2222  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data sliceArg %d\n", __func__,
2223  sliceArg);
2224  }
2225  }
2226 
2227  if (p_enc_ctx->reconfig_slice_arg > 0)
2228  {
2229  sliceArg = p_enc_ctx->reconfig_slice_arg;
2230  p_enc_ctx->reconfig_slice_arg = 0;
2231  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_slice_arg %d\n", __func__, sliceArg);
2232  }
2233 
2234  if (sliceArg)
2235  {
2236  if (sliceArg > NI_MAX_SLICE_SIZE) {
2237  ni_log2(p_enc_ctx, NI_LOG_INFO, "%s(): slice arg > NI_MAX_SLICE_SIZE, change from %d to %d\n",
2238  __func__, sliceArg, NI_MAX_SLICE_SIZE);
2239  sliceArg = NI_MAX_SLICE_SIZE;
2240  }
2241  p_enc_ctx->enc_change_params->enable_option |=
2243 
2244  p_enc_ctx->enc_change_params->sliceArg = sliceArg;
2245  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2246  }
2247 }
2248 
2249 /*!*****************************************************************************
2250  * \brief Copy auxiliary data that should be sent together with this frame
2251  * to encoder.
2252  *
2253  * \param[in] p_enc_ctx encoder session context
2254  * \param[out] p_enc_frame frame to be sent to encoder
2255  * \param[in] p_dec_frame frame returned by decoder
2256  * \param[in] mdcv_data SEI for HDR mastering display color volume info
2257  * \param[in] cll_data SEI for HDR content light level info
2258  * \param[in] cc_data SEI for close caption
2259  * \param[in] udu_data SEI for User data unregistered
2260  * \param[in] hdrp_data SEI for HDR10+
2261  * \param[in] is_hwframe, must be 0 (sw frame) or 1 (hw frame)
2262  * \param[in] is_semiplanar, must be 1 (semiplanar frame) or 0 (not)
2263  *
2264  * \return NONE
2265  ******************************************************************************/
2267  ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame,
2268  ni_codec_format_t codec_format,
2269  const uint8_t *mdcv_data, const uint8_t *cll_data,
2270  const uint8_t *cc_data, const uint8_t *udu_data,
2271  const uint8_t *hdrp_data, int is_hwframe,
2272  int is_semiplanar)
2273 {
2274  ni_xcoder_params_t *api_params =
2275  (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
2276 
2277  // fill in extra data (skipping meta data header)
2278  if (is_hwframe != 0 && is_hwframe != 1 && is_semiplanar != 0 &&
2279  is_semiplanar != 1)
2280  {
2281  ni_log2(p_enc_ctx, NI_LOG_ERROR,
2282  "ni_enc_copy_aux_data: error, illegal hwframe or nv12frame\n");
2283  return;
2284  }
2285 
2286  uint32_t frame_metadata_size = NI_APP_ENC_FRAME_META_DATA_SIZE;
2288  "6Q") < 0)
2289  {
2291  }
2292  else if (ni_cmp_fw_api_ver((char*) &p_enc_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
2293  "6rc") < 0)
2294  {
2296  }
2297 
2298 
2299  uint8_t *dst = (uint8_t *)p_enc_frame->p_data[2 + is_hwframe] +
2300  p_enc_frame->data_len[2 + is_hwframe] + frame_metadata_size;
2301 
2302  if (!is_hwframe)
2303  {
2304  dst = (uint8_t *)p_enc_frame->p_data[2 - is_semiplanar] +
2305  p_enc_frame->data_len[2 - is_semiplanar] +
2306  frame_metadata_size;
2307  }
2308 
2309  // Separate metadata buffer (not contiguous with YUV buffer)
2310  if (p_enc_frame->separate_metadata)
2311  {
2312  dst = p_enc_frame->p_metadata_buffer + frame_metadata_size;
2313  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: p_metadata_buffer %p frame_metadata_size %u dst %p\n",
2314  p_enc_frame->p_metadata_buffer, frame_metadata_size, dst);
2315  }
2316 
2317  // fill in reconfig data if enabled; even if it's disabled, keep the space
2318  // for it if SEI or ROI is present;
2319  if (p_enc_frame->reconf_len || api_params->cfg_enc_params.roi_enable ||
2320  p_enc_frame->sei_total_len)
2321  {
2322  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: keep reconfig space: %"
2323  PRId64 " to %p\n", sizeof(ni_encoder_change_params_t), dst);
2324 
2325  memset(dst, 0, sizeof(ni_encoder_change_params_t));
2326 
2327  if (p_enc_frame->reconf_len && p_enc_ctx->enc_change_params)
2328  {
2329  memcpy(dst, p_enc_ctx->enc_change_params, p_enc_frame->reconf_len);
2330  }
2331 
2332  dst += sizeof(ni_encoder_change_params_t);
2333  }
2334 
2335  // fill in ROI map, if ROI is enabled; the ROI map could be:
2336  // - a zeroed one, e.g. in the case of no any ROI specified yet at session
2337  // start, or
2338  // - one generated by ROI auxiliary data coming with the frame, or
2339  // - a hardcoded one created in nienc/xcoder by ROI demo modes
2340  if (api_params->cfg_enc_params.roi_enable)
2341  {
2342  if (p_enc_frame->roi_len && p_enc_ctx->roi_map)
2343  {
2344  memcpy(dst, p_enc_ctx->roi_map, p_enc_frame->roi_len);
2345  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: ROI size: %u to %p\n",
2346  p_enc_frame->roi_len, dst);
2347 
2348  } else
2349  {
2350  memset(dst, 0, p_enc_ctx->roi_len);
2351  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: zeroed ROI size: %u to %p\n",
2352  p_enc_ctx->roi_len, dst);
2353  }
2354  // for QUADRA, when ROI enabled, requires ROI map included in input buffer and data transferred for every frame
2355  dst += p_enc_ctx->roi_len;
2356  // reset frame ROI len to the actual map size
2357  p_enc_frame->roi_len = p_enc_ctx->roi_len;
2358  }
2359 
2360  // HDR SEI: mastering display color volume
2361  if (p_enc_frame->sei_hdr_mastering_display_color_vol_len)
2362  {
2363  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: HDR SEI mdcv size: %u to %p\n",
2364  p_enc_frame->sei_hdr_mastering_display_color_vol_len, dst);
2365  memcpy(dst, mdcv_data,
2367  dst += p_enc_frame->sei_hdr_mastering_display_color_vol_len;
2368  }
2369 
2370  // HDR SEI: content light level info
2371  if (p_enc_frame->sei_hdr_content_light_level_info_len)
2372  {
2373  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: HDR SEI cll size: %u to %p\n",
2374  p_enc_frame->sei_hdr_content_light_level_info_len, dst);
2375 
2376  memcpy(dst, cll_data,
2378  dst += p_enc_frame->sei_hdr_content_light_level_info_len;
2379  }
2380 
2381  // HLG SEI: preferred characteristics
2382  if (p_enc_frame->preferred_characteristics_data_len)
2383  {
2384  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: preferred characteristics size: %u to %p\n",
2385  p_enc_frame->preferred_characteristics_data_len, dst);
2386 
2387  dst[0] = dst[1] = dst[2] = 0;
2388  dst[3] = 1;
2389  if (NI_CODEC_FORMAT_H265 == codec_format)
2390  {
2391  dst[4] = 0x4e;
2392  dst[5] = 1;
2393  dst[6] = 0x93; // payload type=147
2394  dst[7] = 1; // payload size=1
2395  dst += 8;
2396  } else
2397  {
2398  dst[4] = 0x6;
2399  dst[5] = 0x93; // payload type=147
2400  dst[6] = 1; // payload size=1
2401  dst += 7;
2402  }
2403  *dst = p_enc_ctx->preferred_characteristics_data;
2404  dst++;
2405  *dst = 0x80;
2406  dst++;
2407  }
2408 
2409  // close caption
2410  if (p_enc_frame->sei_cc_len)
2411  {
2412  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: close caption size: %u to %p\n",
2413  p_enc_frame->sei_cc_len, dst);
2414 
2415  memcpy(dst, cc_data, p_enc_frame->sei_cc_len);
2416  dst += p_enc_frame->sei_cc_len;
2417  }
2418 
2419  // HDR10+
2420  if (p_enc_frame->sei_hdr_plus_len)
2421  {
2422  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: HDR10+ size: %u to %p\n",
2423  p_enc_frame->sei_hdr_plus_len, dst);
2424 
2425  memcpy(dst, hdrp_data, p_enc_frame->sei_hdr_plus_len);
2426  dst += p_enc_frame->sei_hdr_plus_len;
2427  }
2428 
2429  // User data unregistered SEI
2430  if (p_enc_frame->sei_user_data_unreg_len)
2431  {
2432  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: UDU size: %u to %p\n",
2433  p_enc_frame->sei_user_data_unreg_len, dst);
2434  memcpy(dst, udu_data, p_enc_frame->sei_user_data_unreg_len);
2435  //dst += p_enc_frame->sei_user_data_unreg_len;
2436  }
2437 }
2438 
2439 /*!*****************************************************************************
2440  * \brief Insert timecode data into picture timing SEI (H264) or time code SEI (H265)
2441  *
2442  * \note This function must be callled after all other aux data has been processed by
2443  * ni_enc_prep_aux_data and ni_enc_copy_aux_data. Otherwise the timecode SEI data
2444  * might be overwritten
2445  *
2446  * \param[in] p_enc_ctx encoder session context
2447  * \param[out] p_enc_frame frame to be sent to encoder
2448  * \param[in] p_timecode the timecode data to be written along with the frame
2449  *
2450  * \return NI_RETCODE_SUCCESS on success, NI_RETCODE_FAILURE on failure
2451  ******************************************************************************/
2453  ni_timecode_t *p_timecode)
2454 {
2455  uint8_t timecode_data[NI_MAX_SEI_DATA];
2456  uint8_t *dst = timecode_data;
2458  uint32_t header_len, payload_len, total_len;
2459  int emu_bytes_inserted, is_hwframe, is_semiplanar;
2460 
2461  if (!p_enc_ctx || !p_enc_frame || !p_timecode) {
2462  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s received NULL parameter\n", __func__);
2463  return NI_RETCODE_FAILURE;
2464  }
2465 
2466  if (p_enc_ctx->codec_format != NI_CODEC_FORMAT_H264 && p_enc_ctx->codec_format != NI_CODEC_FORMAT_H265) {
2467  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s insertion of timecode in SEI is only supported on H264 and H265 encoder\n", __func__);
2468  return NI_RETCODE_FAILURE;
2469  }
2470 
2472 
2473  // NAL start code
2474  ni_bs_writer_put(&pb, 0x00, 8);
2475  ni_bs_writer_put(&pb, 0x00, 8);
2476  ni_bs_writer_put(&pb, 0x00, 8);
2477  ni_bs_writer_put(&pb, 0x01, 8);
2478 
2479  // NAL type: SEI
2480  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2481  ni_bs_writer_put(&pb, 0x06, 8);
2482  } else {
2483  ni_bs_writer_put(&pb, 0x4e, 8);
2484  ni_bs_writer_put(&pb, 0x01, 8);
2485  }
2486 
2487  // SEI type: picture timing (1) for H264, time code (136) for H265
2488  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2489  ni_bs_writer_put(&pb, 0x01, 8);
2490  header_len = 7;
2491  } else {
2492  ni_bs_writer_put(&pb, 0x88, 8);
2493  header_len = 8;
2494  }
2495 
2496  // SEI payload size, to be set later
2497  ni_bs_writer_put(&pb, 0x00, 8);
2498 
2499  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2500  ni_bs_writer_put(&pb, 0x0, 4); // pic_struct, always 0 (progressive)
2501  } else {
2502  ni_bs_writer_put(&pb, 0x1, 2); // num_clock_ts, only support inserting 1
2503  }
2504 
2505  // actual timestamp data below, retrieve the values from ni_timecode_t passed in
2506  ni_bs_writer_put(&pb, 0x1, 1); // clock_timestamp_flag = 1
2507  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2508  ni_bs_writer_put(&pb, 0x0, 2); // ct_type, always 0 (progressive)
2509  }
2510  ni_bs_writer_put(&pb, p_timecode->nuit_field_based_flag, 1);
2511  ni_bs_writer_put(&pb, p_timecode->counting_type, 5);
2512  ni_bs_writer_put(&pb, p_timecode->full_timestamp_flag, 1);
2513  ni_bs_writer_put(&pb, p_timecode->discontinuity_flag, 1);
2514  ni_bs_writer_put(&pb, p_timecode->cnt_dropped_flag, 1);
2515  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2516  ni_bs_writer_put(&pb, p_timecode->n_frames, 8);
2517  } else {
2518  ni_bs_writer_put(&pb, p_timecode->n_frames, 9);
2519  }
2520  if (p_timecode->full_timestamp_flag) {
2521  ni_bs_writer_put(&pb, p_timecode->seconds_value, 6);
2522  ni_bs_writer_put(&pb, p_timecode->minutes_value, 6);
2523  ni_bs_writer_put(&pb, p_timecode->hours_value, 5);
2524  } else {
2525  ni_bs_writer_put(&pb, p_timecode->seconds_flag, 1);
2526  if (p_timecode->seconds_flag) {
2527  ni_bs_writer_put(&pb, p_timecode->seconds_value, 6);
2528  ni_bs_writer_put(&pb, p_timecode->minutes_flag, 1);
2529  if (p_timecode->minutes_flag) {
2530  ni_bs_writer_put(&pb, p_timecode->minutes_value, 6);
2531  ni_bs_writer_put(&pb, p_timecode->hours_flag, 1);
2532  if (p_timecode->hours_flag) {
2533  ni_bs_writer_put(&pb, p_timecode->hours_value, 5);
2534  }
2535  }
2536  }
2537  }
2538  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265) {
2539  ni_bs_writer_put(&pb, p_timecode->time_offset_length, 5);
2540  if (p_timecode->time_offset_length) {
2541  ni_bs_writer_put(&pb, p_timecode->time_offset_value, p_timecode->time_offset_length);
2542  }
2543  } else {
2544  // for H264, time_offset_length is stored in HRD parameters in VUI, which can only be set
2545  // in the FW when HRD is enabled, so we assume that it is not present, in which case it
2546  // should be intepreted as 24 by default
2547  ni_bs_writer_put(&pb, p_timecode->time_offset_value, 24);
2548  }
2549 
2550  ni_bs_writer_put(&pb, 1, 1);
2552  payload_len = ((ni_bs_writer_tell(&pb) + 7) / 8) - header_len;
2553  ni_bs_writer_copy(dst, &pb);
2554  ni_bs_writer_clear(&pb);
2555 
2556  // set the SEI payload size
2557  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2558  dst[6] = payload_len;
2559  } else {
2560  dst[7] = payload_len;
2561  }
2562  dst += header_len;
2563 
2564  // insert emulation prevention bytes to the SEI payload data and write trailing bits
2565  emu_bytes_inserted = ni_insert_emulation_prevent_bytes(dst, (int)payload_len);
2566  dst += payload_len + emu_bytes_inserted;
2567  *dst = 0x80;
2568 
2569  // total size of the timecode_data buffer to be copied
2570  total_len = header_len + payload_len + emu_bytes_inserted + 1;
2571 
2572  is_hwframe = p_enc_ctx->hw_action != NI_CODEC_HW_NONE;
2573  is_semiplanar = p_enc_ctx->pixel_format == NI_PIX_FMT_NV12 ||
2574  p_enc_ctx->pixel_format == NI_PIX_FMT_P010LE;
2575  dst = (uint8_t *)p_enc_frame->p_data[2 + is_hwframe] +
2576  p_enc_frame->data_len[2 + is_hwframe] + p_enc_frame->extra_data_len;
2577  if (!is_hwframe)
2578  {
2579  dst = (uint8_t *)p_enc_frame->p_data[2 - is_semiplanar] +
2580  p_enc_frame->data_len[2 - is_semiplanar] + p_enc_frame->extra_data_len;
2581  }
2582 
2583  // separate metadata buffer (not contiguous with YUV buffer)
2584  if (p_enc_frame->separate_metadata)
2585  {
2586  dst = p_enc_frame->p_metadata_buffer + p_enc_frame->extra_data_len;
2587  }
2588 
2589  // copy formatted SEI NAL unit data to the proper buffer
2590  memcpy(dst, timecode_data, total_len);
2591 
2592  // finally, update the relevant data size counters in ni_frame_t
2593  p_enc_frame->sei_total_len += total_len;
2594  p_enc_frame->extra_data_len += total_len;
2595 
2596  return NI_RETCODE_SUCCESS;
2597 }
2598 
2599 /*!*****************************************************************************
2600  * \brief Send an input data frame to the encoder with YUV data given in
2601  * the inputs.
2602  *
2603  * For ideal performance memory should be 4k aligned. If it is not 4K aligned
2604  * then a temporary 4k aligned memory will be used to copy data to and from
2605  * when writing and reading. This will negatively impact performance.
2606  *
2607  * Any metadata to be sent with the frame should be attached to p_enc_frame
2608  * as aux data (e.g. using ni_frame_new_aux_data()).
2609  *
2610  * \param[in] p_ctx Encoder session context
2611  * \param[in] p_enc_frame Struct holding information about the frame
2612  * to be sent to the encoder
2613  * \param[in] p_yuv_buffer Caller allocated buffer holding YUV data
2614  * for the frame
2615  *
2616  * \return On success
2617  * Total number of bytes written
2618  * On failure
2619  * NI_RETCODE_INVALID_PARAM
2620  * NI_RETCODE_ERROR_MEM_ALOC
2621  * NI_RETCODE_ERROR_NVME_CMD_FAILED
2622  * NI_RETCODE_ERROR_INVALID_SESSION
2623  *****************************************************************************/
2625  ni_frame_t *p_enc_frame, uint8_t *p_yuv_buffer)
2626 {
2627  int frame_width;
2628  int frame_height;
2629  bool need_copy = true;
2630  ni_xcoder_params_t *p_param;
2632  bool alignment_2pass_wa = false;
2633  int is_hwframe;
2634 
2635  if (!p_ctx || !p_enc_frame)
2636  {
2637  ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2638  __func__);
2639  return NI_RETCODE_INVALID_PARAM;
2640  }
2641 
2642  if (!p_yuv_buffer)
2643  {
2644  // send EOS
2645  p_enc_frame->end_of_stream = 1;
2646  goto send_frame;
2647  }
2648 
2649  if (((uintptr_t)p_yuv_buffer) % NI_MEM_PAGE_ALIGNMENT)
2650  {
2651  ni_log2(p_ctx, NI_LOG_INFO, "WARNING: %s passed buffer ptr %p is not 4k aligned\n",
2652  __func__, p_yuv_buffer);
2653 
2654  }
2655 
2656  is_hwframe = p_ctx->hw_action != NI_CODEC_HW_NONE;
2657  frame_width = p_enc_frame->video_width;
2658  frame_height = p_enc_frame->video_height;
2659  p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2660 
2661  // extra data starts with metadata header
2663 
2664  if (!p_enc_frame->start_of_stream &&
2665  (p_enc_frame->video_width != p_ctx->actual_video_width ||
2666  p_enc_frame->video_height != p_ctx->active_video_height ||
2667  p_enc_frame->pixel_format != p_ctx->pixel_format))
2668  {
2669  ni_log2(p_ctx, NI_LOG_INFO,
2670  "%s: resolution change %dx%d -> %dx%d "
2671  "or pixel format change %d -> %d\n",
2672  __func__, p_ctx->actual_video_width, p_ctx->active_video_height,
2673  p_enc_frame->video_width, p_enc_frame->video_height,
2674  p_ctx->pixel_format, p_enc_frame->pixel_format);
2675 
2676  // change run state
2678 
2679  ni_log2(p_ctx, NI_LOG_DEBUG, "%s: session_run_state change to %d \n", __func__,
2680  p_ctx->session_run_state);
2681 
2682  // send EOS
2683  p_enc_frame->end_of_stream = 1;
2684  goto send_frame;
2685  }
2686 
2687  // ROI demo mode takes higher priority over aux data
2688  // Note: when ROI demo modes enabled, supply ROI map for the specified range
2689  // frames, and 0 map for others
2690  if (p_param->roi_demo_mode && p_param->cfg_enc_params.roi_enable)
2691  {
2692  if (p_ctx->frame_num > 90 && p_ctx->frame_num < 300)
2693  {
2694  p_enc_frame->roi_len = p_ctx->roi_len;
2695  } else
2696  {
2697  p_enc_frame->roi_len = 0;
2698  }
2699  // when ROI enabled, always have a data buffer for ROI
2700  // Note: this is handled separately from ROI through side/aux data
2701  p_enc_frame->extra_data_len += p_ctx->roi_len;
2702  }
2703 
2704  int should_send_sei_with_frame =
2705  ni_should_send_sei_with_frame(p_ctx, PIC_TYPE_P, p_param);
2706 
2707  uint8_t mdcv_data[NI_MAX_SEI_DATA];
2708  uint8_t cll_data[NI_MAX_SEI_DATA];
2709  uint8_t cc_data[NI_MAX_SEI_DATA];
2710  uint8_t udu_data[NI_MAX_SEI_DATA];
2711  uint8_t hdrp_data[NI_MAX_SEI_DATA];
2712 
2713  // Convert aux data attached to input frame into required format,
2714  // and store in local arrays
2715  ni_enc_prep_aux_data(p_ctx, p_enc_frame, p_enc_frame, p_ctx->codec_format,
2716  should_send_sei_with_frame, mdcv_data, cll_data,
2717  cc_data, udu_data, hdrp_data);
2718 
2719  p_enc_frame->extra_data_len += p_enc_frame->sei_total_len;
2720 
2721  // data layout requirement: leave space for reconfig data if at least one of
2722  // reconfig, SEI or ROI is present
2723  // Note: ROI is present when enabled, so use encode config flag instead of
2724  // frame's roi_len as it can be 0 indicating a 0'd ROI map setting !
2725  if (p_enc_frame->reconf_len || p_enc_frame->sei_total_len ||
2726  (p_param->roi_demo_mode && p_param->cfg_enc_params.roi_enable))
2727  {
2728  p_enc_frame->extra_data_len += sizeof(ni_encoder_change_params_t);
2729  }
2730 
2731  // Check whether line-by-line copy is needed
2732  int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0};
2733  int dst_height_aligned[NI_MAX_NUM_DATA_POINTERS] = {0};
2734  int is_semiplanar = !ni_get_planar_from_pixfmt(p_ctx->pixel_format);
2735  ni_get_hw_yuv420p_dim(frame_width, frame_height, p_ctx->bit_depth_factor,
2736  is_semiplanar, dst_stride, dst_height_aligned);
2737 
2738  int src_stride[NI_MAX_NUM_DATA_POINTERS];
2739  int src_height[NI_MAX_NUM_DATA_POINTERS];
2740  uint8_t *p_src[NI_MAX_NUM_DATA_POINTERS];
2741 
2742  bool isrgba = (p_ctx->pixel_format == NI_PIX_FMT_ABGR || p_ctx->pixel_format == NI_PIX_FMT_ARGB
2743  || p_ctx->pixel_format == NI_PIX_FMT_RGBA || p_ctx->pixel_format == NI_PIX_FMT_BGRA);
2744 
2745  // NOTE - FFmpeg / Gstreamer users should use linesize array in frame structure instead of src_stride in the following sample code
2746  src_stride[0] = frame_width * p_ctx->bit_depth_factor;
2747  src_height[0] = frame_height;
2748  p_src[0] = p_yuv_buffer;
2749 
2750  if (isrgba)
2751  {
2752  src_stride[1] = 0;
2753  src_stride[2] = 0;
2754 
2755  src_height[1] = 0;
2756  src_height[2] = 0;
2757 
2758  p_src[1] = NULL;
2759  p_src[2] = NULL;
2760  }
2761  else
2762  {
2763  src_stride[1] = is_semiplanar ? src_stride[0] : src_stride[0] / 2;
2764  src_stride[2] = is_semiplanar ? 0 : src_stride[0] / 2;
2765 
2766  src_height[1] = src_height[0] / 2;
2767  src_height[2] = is_semiplanar ? 0 : src_height[1];
2768 
2769  p_src[1] = p_src[0] + src_stride[0] * src_height[0];
2770  p_src[2] = p_src[1] + src_stride[1] * src_height[1];
2771  }
2772 
2773  alignment_2pass_wa = (
2774  (p_param->cfg_enc_params.lookAheadDepth ||
2775  p_param->cfg_enc_params.crf >= 0 ||
2776  p_param->cfg_enc_params.crfFloat >= 0) &&
2777  (p_ctx->codec_format == NI_CODEC_FORMAT_H265 ||
2778  p_ctx->codec_format == NI_CODEC_FORMAT_AV1));
2779 
2780  if (alignment_2pass_wa && !is_hwframe) {
2781  if (is_semiplanar) {
2782  // for 2-pass encode output mismatch WA, need to extend (and
2783  // pad) CbCr plane height, because 1st pass assume input 32
2784  // align
2785  dst_height_aligned[1] = (((dst_height_aligned[0] + 31) / 32) * 32) / 2;
2786  } else {
2787  // for 2-pass encode output mismatch WA, need to extend (and
2788  // pad) Cr plane height, because 1st pass assume input 32 align
2789  dst_height_aligned[2] = (((dst_height_aligned[0] + 31) / 32) * 32) / 2;
2790  }
2791  }
2792 
2793  // check input resolution zero copy compatible or not
2795  p_param, frame_width, frame_height,
2796  (const int *)src_stride, false) == NI_RETCODE_SUCCESS)
2797  {
2798  need_copy = false;
2799  //alloc metadata buffer etc. (if needed)
2801  p_enc_frame, frame_width,
2802  frame_height, (const int *)src_stride, (const uint8_t **)p_src,
2803  (int)(p_enc_frame->extra_data_len));
2804  if (retval != NI_RETCODE_SUCCESS)
2805  goto end;
2806  }
2807  else
2808  {
2809  // if linesize changes (while resolution remains the same), copy to previously configured linesizes
2810  if (p_param->luma_linesize && p_param->chroma_linesize)
2811  {
2812  dst_stride[0] = p_param->luma_linesize;
2813  dst_stride[1] = p_param->chroma_linesize;
2814  dst_stride[2] = is_semiplanar ? 0 : p_param->chroma_linesize;
2815  }
2817  p_param->cfg_enc_params.planar, p_enc_frame, frame_width,
2818  dst_height_aligned[0], dst_stride,
2820  (int)(p_enc_frame->extra_data_len), alignment_2pass_wa);
2821  if (retval != NI_RETCODE_SUCCESS)
2822  {
2823  return retval;
2824  }
2825  }
2826 
2827  ni_log2(p_ctx, NI_LOG_TRACE,
2828  "%s: src_stride %d dst_stride "
2829  "%d dst_height_aligned %d src_height %d need_copy %d\n",
2830  __func__, src_stride[0],
2831  dst_stride[0], dst_height_aligned[0],
2832  src_height[0], need_copy);
2833 
2834  if (need_copy)
2835  {
2836  ni_copy_hw_yuv420p((uint8_t **)(p_enc_frame->p_data), p_src,
2837  frame_width, frame_height, p_ctx->bit_depth_factor,
2838  is_semiplanar,
2839  p_param->cfg_enc_params.conf_win_right, dst_stride,
2840  dst_height_aligned, src_stride, src_height);
2841  p_enc_frame->separate_metadata = 0;
2842  }
2843 
2844  ni_log2(p_ctx, NI_LOG_DEBUG,
2845  "p_dst alloc linesize = %d/%d/%d src height=%d "
2846  "dst height aligned = %d/%d/%d force_key_frame=%d, "
2847  "extra_data_len=%u"
2848  " sei_size=%u (hdr_content_light_level %u hdr_mastering_display_"
2849  "color_vol %u hdr10+ %u hrd %d) reconf_size=%u roi_size=%u "
2850  "force_pic_qp=%u udu_sei_size=%u "
2851  "use_cur_src_as_long_term_pic %u use_long_term_ref %u\n",
2852  dst_stride[0], dst_stride[1], dst_stride[2], frame_height,
2853  dst_height_aligned[0], dst_height_aligned[1], dst_height_aligned[2],
2854  p_enc_frame->force_key_frame, p_enc_frame->extra_data_len,
2855  p_enc_frame->sei_total_len,
2858  p_enc_frame->sei_hdr_plus_len, 0, /* hrd is 0 size for now */
2859  p_enc_frame->reconf_len, p_enc_frame->roi_len,
2860  p_enc_frame->force_pic_qp, p_enc_frame->sei_user_data_unreg_len,
2861  p_enc_frame->use_cur_src_as_long_term_pic,
2862  p_enc_frame->use_long_term_ref);
2863 
2864  ni_enc_copy_aux_data(p_ctx, p_enc_frame, p_enc_frame, p_ctx->codec_format,
2865  mdcv_data, cll_data, cc_data, udu_data, hdrp_data,
2866  0 /*swframe*/, is_semiplanar);
2867 
2868 send_frame:
2869  retval = ni_device_session_write(p_ctx, (ni_session_data_io_t *)p_enc_frame,
2871 end:
2872  if (!need_copy)
2873  {
2874  // Don't want to accidentally free or reuse user-allocated YUV buffer, so remove from frame
2875  p_enc_frame->p_buffer = NULL;
2876  p_enc_frame->buffer_size = 0;
2877  for (int i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
2878  {
2879  p_enc_frame->data_len[i] = 0;
2880  p_enc_frame->p_data[i] = NULL;
2881  }
2882  }
2883 
2884  return retval;
2885 }
2886 
2887 /*!*****************************************************************************
2888  * \brief Find the next start code
2889  *
2890  * \param[in] p pointer to buffer start address.
2891  * \param[in] end pointer to buffer end address.
2892  * \param[state] state pointer to nalu type address
2893  *
2894  * \return search end address
2895  ******************************************************************************/
2896 const uint8_t *ni_find_start_code (const uint8_t *p, const uint8_t *end, uint32_t *state)
2897 {
2898  int i;
2899 
2900  if (p >= end)
2901  return end;
2902 
2903  for (i = 0; i < 3; i++) {
2904  uint32_t tmp = *state << 8;
2905  *state = tmp + *(p++);
2906  if (tmp == 0x100 || p == end)
2907  return p;
2908  }
2909 
2910  while (p < end) {
2911  if (p[-1] > 1)
2912  p += 3;
2913  else if (p[-2])
2914  p += 2;
2915  else if (p[-3] | (p[-1] - 1))
2916  p++;
2917  else {
2918  p++;
2919  break;
2920  }
2921  }
2922 
2923  p = ((p) < (end) ? (p - 4) : (end - 4)); // min
2924  *state =
2925  (((uint32_t) (p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | (p)[3]);
2926 
2927  return p + 4;
2928 }
2929 
2930 /*!******************************************************************************
2931  * \brief Extract custom sei payload data from pkt_data,
2932  * and save it to ni_packet_t
2933  *
2934  * \param uint8_t *pkt_data - FFmpeg AVPacket data
2935  * \param int pkt_size - packet size
2936  * \param long index - pkt data index of custom sei first byte after SEI type
2937  * \param ni_packet_t *p_packet - libxcoder internal packet
2938  * \param uint8_t sei_type - type of SEI
2939  * \param int vcl_found - whether got vcl in the pkt data, 1 means got
2940  *
2941  * \return - 0 on success, non-0 on failure
2942  ********************************************************************************/
2943 int ni_extract_custom_sei(uint8_t *pkt_data, int pkt_size, long index,
2944  ni_packet_t *p_packet, uint8_t sei_type, int vcl_found)
2945 {
2946  int i, len;
2947  uint8_t *udata;
2948  uint8_t *sei_data;
2949  int sei_size;
2950  int sei_index;
2951  ni_custom_sei_t *p_custom_sei;
2952 
2953  ni_log(NI_LOG_TRACE, "%s() enter\n", __FUNCTION__);
2954 
2955  if (p_packet->p_custom_sei_set == NULL)
2956  {
2957  /* max size */
2958  p_packet->p_custom_sei_set = (ni_custom_sei_set_t *)malloc(sizeof(ni_custom_sei_set_t));
2959  if (p_packet->p_custom_sei_set == NULL)
2960  {
2961  ni_log(NI_LOG_ERROR, "failed to allocate all custom sei buffer.\n");
2963  }
2964  memset(p_packet->p_custom_sei_set, 0, sizeof(ni_custom_sei_set_t));
2965  }
2966 
2967  sei_index = p_packet->p_custom_sei_set->count;
2968  p_custom_sei = &p_packet->p_custom_sei_set->custom_sei[sei_index];
2969  if (sei_index >= NI_MAX_CUSTOM_SEI_CNT)
2970  {
2971  ni_log(NI_LOG_INFO, "number of custom sei in current frame is out of limit(%d).\n",
2973  return 0;
2974  }
2975  sei_data = &p_custom_sei->data[0];
2976 
2984  sei_size = 0;
2985  while (index < pkt_size && pkt_data[index] == 0xff)
2986  {
2987  sei_size += pkt_data[index++];
2988  }
2989 
2990  if (index >= pkt_size)
2991  {
2992  ni_log(NI_LOG_INFO, "custom sei corrupted: length truncated.\n");
2993  return NI_RETCODE_FAILURE;
2994  }
2995  sei_size += pkt_data[index++];
2996 
2997  if (sei_size > NI_MAX_CUSTOM_SEI_DATA)
2998  {
2999  ni_log(NI_LOG_INFO, "custom sei corrupted: size(%d) out of limit(%d).\n",
3000  sei_size, NI_MAX_CUSTOM_SEI_DATA);
3001  return 0;
3002  }
3003 
3004  udata = &pkt_data[index];
3005 
3006  /* set SEI payload type at the first byte */
3007  sei_data[0] = sei_type;
3008 
3009  /* extract SEI payload data
3010  * SEI payload data in NAL is EBSP(Encapsulated Byte Sequence Payload),
3011  * need change EBSP to RBSP(Raw Byte Sequence Payload) for exact size
3012  */
3013  for (i = 0, len = 0; (i < pkt_size - index) && len < sei_size; i++, len++)
3014  {
3015  /* if the latest 3-byte data pattern matchs '00 00 03' which means udata[i] is an escaping byte,
3016  * discard udata[i]. */
3017  if (i >= 2 && udata[i - 2] == 0 && udata[i - 1] == 0 && udata[i] == 3)
3018  {
3019  len--;
3020  continue;
3021  }
3022  sei_data[len] = udata[i];
3023  }
3024 
3025  if (len != sei_size)
3026  {
3027  ni_log(NI_LOG_INFO, "custom sei corrupted: data truncated, "
3028  "required size:%d, actual size:%d.\n", sei_size, len);
3029  return NI_RETCODE_FAILURE;
3030  }
3031 
3032  p_custom_sei->type = sei_type;
3033  p_custom_sei->size = sei_size;
3035 
3036  p_packet->p_custom_sei_set->count++;
3037 
3038  ni_log(NI_LOG_TRACE, "%s() exit, custom sei size=%d type=%d\n",
3039  __FUNCTION__, sei_size, sei_type);
3040 
3041  return 0;
3042 }
3043 
3044 /*!******************************************************************************
3045  * \brief Decode parse packet
3046  *
3047  * \param[in] p_session_ctx Pointer to a caller allocated
3048  * ni_session_context_t struct
3049  * \param[in] p_param Pointer to a caller allocated
3050  * ni_xcoder_params_t struct
3051  * \param[in] *data FFmpeg AVPacket data
3052  * \param[in] size packet size
3053  * \param[in] p_packet Pointer to a caller allocated
3054  * ni_packet_t struct
3055  * \param[in] low_delay FFmpeg lowdelay
3056  * \param[in] codec_format enum ni_codec_format_t
3057  * \param[in] pkt_nal_bitmap pkt_nal_bitmap
3058  * \param[in] custom_sei_type custom_sei_type
3059  * \param[in] *svct_skip_next_packet svct_skip_next_packet int*
3060  * \param[in] *is_lone_sei_pkt is_lone_sei_pkt int*
3061  *
3062  * \return - 0 on success, non-0 on failure
3063  ********************************************************************************/
3065  uint8_t *data, int size, ni_packet_t *p_packet, int low_delay,
3066  int codec_format, int pkt_nal_bitmap, int custom_sei_type,
3067  int *svct_skip_next_packet, int *is_lone_sei_pkt)
3068 {
3069  int pkt_sei_alone = 1;
3070  int vcl_found = 0;
3071  int tmp_low_delay =
3072  (p_session_ctx->decoder_low_delay == -1) ? 0 : low_delay;
3073  int svct_layer = (codec_format == NI_CODEC_FORMAT_H264) ?
3076  // int pkt_nal_bitmap = ni_dec_ctx->pkt_nal_bitmap;
3077  const uint8_t *ptr = data;
3078  const uint8_t *end = data + size;
3079  uint32_t stc;
3080  int nalu_type;
3081  uint8_t sei_type = 0;
3082  int ret = 0;
3083  int nalu_count = 0;
3085  uint32_t temporal_id;
3086 
3087  if (pkt_nal_bitmap & NI_GENERATE_ALL_NAL_HEADER_BIT)
3088  {
3089  ni_log2(p_session_ctx, NI_LOG_TRACE,
3090  "ni_dec_packet_parse(): already find the header of streams.\n");
3091  low_delay = 0;
3092  }
3093 
3094  while (
3095  (custom_sei_type != NI_INVALID_SEI_TYPE ||
3097  svct_layer != NI_INVALID_SVCT_DECODING_LAYER || tmp_low_delay ||
3099  ptr < end)
3100  {
3101  stc = -1;
3102  ptr = ni_find_start_code(ptr, end, &stc);
3103  if (ptr == end)
3104  {
3105  if (0 == nalu_count)
3106  {
3107  pkt_sei_alone = 0;
3108  ni_log2(p_session_ctx, NI_LOG_TRACE, "%s(): no NAL found in pkt.\n",
3109  __FUNCTION__);
3110  }
3111  break;
3112  }
3113  nalu_count++;
3114 
3115  if (NI_CODEC_FORMAT_H264 == codec_format)
3116  {
3117  nalu_type = (int)stc & 0x1f;
3118 
3119  //check whether the packet is sei alone
3120  pkt_sei_alone = (pkt_sei_alone && 6 /*H264_NAL_SEI */ == nalu_type);
3121 
3122  // Enable decoder low delay mode on sequence change
3123  if (low_delay)
3124  {
3125  switch (nalu_type)
3126  {
3127  case 7 /*H264_NAL_SPS */:
3128  pkt_nal_bitmap |= NI_NAL_SPS_BIT;
3129  break;
3130  case 8 /*H264_NAL_PPS */:
3131  pkt_nal_bitmap |= NI_NAL_PPS_BIT;
3132  break;
3133  default:
3134  break;
3135  }
3136 
3137  if (pkt_nal_bitmap == (NI_NAL_SPS_BIT | NI_NAL_PPS_BIT))
3138  {
3139  ni_log2(p_session_ctx, NI_LOG_TRACE,
3140  "ni_dec_packet_parse(): Detect SPS, PPS and IDR, "
3141  "enable decoder low delay mode.\n");
3142  p_session_ctx->decoder_low_delay = low_delay;
3143  pkt_nal_bitmap |= NI_GENERATE_ALL_NAL_HEADER_BIT;
3144  low_delay = 0;
3145  }
3146  }
3147  // check whether the packet contains SEI NAL after VCL units
3148  if (6 /*H264_NAL_SEI */ == nalu_type)
3149  {
3150  sei_type = *ptr;
3151  if (vcl_found ||
3152  custom_sei_type == sei_type ||
3153  p_param->dec_input_params.custom_sei_passthru == sei_type ||
3155  {
3156  // SEI after VCL found or SEI type indicated then extract
3157  // the SEI unit;
3158  // ret = ni_quadra_extract_custom_sei(ni_dec_ctx, data, size,
3159  // ptr + 1 - data, p_packet,
3160  // sei_type, vcl_found);
3161  ret = ni_extract_custom_sei(data, size,
3162  ptr + 1 - data, p_packet,
3163  sei_type, vcl_found);
3164  if (ret != 0)
3165  {
3166  return ret;
3167  }
3168  }
3169  } else if (nalu_type >= 1 /* H264_NAL_SLICE */ &&
3170  nalu_type <= 5 /* H264_NAL_IDR_SLICE */)
3171  {
3172  vcl_found = 1;
3173  } else if (14 /*H264_NAL_PREFIX */ == nalu_type)
3174  {
3175  ni_bitstream_reader_init(&br, ptr,
3176  48); // 3 * 2 bytes * 8 = 48 bits
3177  // skip some header
3178  ni_bs_reader_skip_bits(&br, 16);
3179  temporal_id = ni_bs_reader_get_bits(&br, 3);
3180  if (temporal_id > svct_layer)
3181  {
3182  // H264_NAL_PREFIX UNIT will be sent with the last packet.
3183  // So, the H264_NAL_PREFIX here is used for the next packet.
3184  *svct_skip_next_packet = 1;
3185  ni_log2(p_session_ctx, NI_LOG_TRACE,
3186  "ni_dec_packet_parse(): temporal_id %d"
3187  " is bigger than decoded layer %d, skip the next "
3188  "packet\n",
3189  temporal_id, svct_layer);
3190  }
3191  }
3192  } else if (NI_CODEC_FORMAT_H265 == codec_format)
3193  {
3194  nalu_type = (int)(stc >> 1) & 0x3F;
3195 
3196  //check whether the packet is sei alone
3197  pkt_sei_alone = (pkt_sei_alone &&
3198  (39 /* HEVC_NAL_SEI_PREFIX */ == nalu_type ||
3199  40 /* HEVC_NAL_SEI_SUFFIX */ == nalu_type));
3200 
3201  // Enable decoder low delay mode on sequence change
3202  if (low_delay)
3203  {
3204  switch (nalu_type)
3205  {
3206  case 32 /* HEVC_NAL_VPS */:
3207  pkt_nal_bitmap |= NI_NAL_VPS_BIT;
3208  break;
3209  case 33 /* HEVC_NAL_SPS */:
3210  pkt_nal_bitmap |= NI_NAL_SPS_BIT;
3211  break;
3212  case 34 /* HEVC_NAL_PPS */:
3213  pkt_nal_bitmap |= NI_NAL_PPS_BIT;
3214  break;
3215  default:
3216  break;
3217  }
3218 
3219  if (pkt_nal_bitmap ==
3221  {
3222  // Packets before the header is sent cannot be decoded.
3223  // So set packet num to zero here.
3224  ni_log2(p_session_ctx, NI_LOG_TRACE,
3225  "ni_dec_packet_parse(): Detect VPS, SPS, PPS and "
3226  "IDR enable decoder low delay mode.\n");
3227  p_session_ctx->decoder_low_delay = low_delay;
3228  pkt_nal_bitmap |= NI_GENERATE_ALL_NAL_HEADER_BIT;
3229  low_delay = 0;
3230  }
3231  }
3232  // check whether the packet contains SEI NAL after VCL units
3233  if (39 /* HEVC_NAL_SEI_PREFIX */ == nalu_type ||
3234  40 /* HEVC_NAL_SEI_SUFFIX */ == nalu_type)
3235  {
3236  sei_type = *(ptr + 1);
3237  if (vcl_found ||
3238  custom_sei_type == sei_type ||
3239  p_param->dec_input_params.custom_sei_passthru == sei_type ||
3241  {
3242  // SEI after VCL found or SEI type indicated then extract
3243  // the SEI unit;
3244  // ret = ni_quadra_extract_custom_sei(ni_dec_ctx, data, size,
3245  // ptr + 2 - data, p_packet,
3246  // sei_type, vcl_found);
3247  ret = ni_extract_custom_sei(data, size, ptr + 2 - data, p_packet,
3248  sei_type, vcl_found);
3249  if (ret != 0)
3250  {
3251  return ret;
3252  }
3253  }
3254  } else if (nalu_type >= 0 /* HEVC_NAL_TRAIL_N */ &&
3255  nalu_type <= 31 /* HEVC_NAL_RSV_VCL31 */)
3256  {
3257  vcl_found = 1;
3258  }
3259  } else
3260  {
3261  ni_log2(p_session_ctx,NI_LOG_DEBUG, "%s() wrong codec %d !\n", __FUNCTION__, codec_format);
3262  pkt_sei_alone = 0;
3263  break;
3264  }
3265  }
3266 
3267  if (nalu_count > 0)
3268  {
3269  *is_lone_sei_pkt = pkt_sei_alone;
3270  }
3271 
3272  return 0;
3273 }
3274 
3275 /*!******************************************************************************
3276  * \brief Expand frame form src frame
3277  *
3278  * \param[in] dst Pointer to a caller allocated ni_frame_t struct
3279  * \param[in] src Pointer to a caller allocated ni_frame_t struct
3280  * \param[in] dst_stride int dst_stride[]
3281  * \param[in] raw_width frame width
3282  * \param[in] raw_height frame height
3283  * \param[in] ni_fmt ni_pix_fmt_t type for ni pix_fmt
3284  * \param[in] nb_planes int nb_planes
3285  *
3286  * \return - 0 on success, NI_RETCODE_FAILURE on failure
3287  ********************************************************************************/
3288 int ni_expand_frame(ni_frame_t *dst, ni_frame_t *src, int dst_stride[],
3289  int raw_width, int raw_height, int ni_fmt, int nb_planes)
3290 {
3291  int i, j, h, tenBit = 0;
3292  int vpad[3], hpad[3], src_height[3], src_width[3], src_stride[3];
3293  uint8_t *src_line, *dst_line, *sample, *dest, YUVsample;
3294  uint16_t lastidx;
3295 
3296  switch (ni_fmt)
3297  {
3298  case NI_PIX_FMT_YUV420P:
3299  /* width of source frame for each plane in pixels */
3300  src_width[0] = NIALIGN(raw_width, 2);
3301  src_width[1] = NIALIGN(raw_width, 2) / 2;
3302  src_width[2] = NIALIGN(raw_width, 2) / 2;
3303 
3304  /* height of source frame for each plane in pixels */
3305  src_height[0] = NIALIGN(raw_height, 2);
3306  src_height[1] = NIALIGN(raw_height, 2) / 2;
3307  src_height[2] = NIALIGN(raw_height, 2) / 2;
3308 
3309  /* stride of source frame for each plane in bytes */
3310  src_stride[0] = NIALIGN(src_width[0], 128);
3311  src_stride[1] = NIALIGN(src_width[1], 128);
3312  src_stride[2] = NIALIGN(src_width[2], 128);
3313 
3314  tenBit = 0;
3315 
3316  /* horizontal padding needed for each plane in bytes */
3317  hpad[0] = dst_stride[0] - src_width[0];
3318  hpad[1] = dst_stride[1] - src_width[1];
3319  hpad[2] = dst_stride[2] - src_width[2];
3320 
3321  /* vertical padding needed for each plane in pixels */
3322  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3323  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3324  vpad[2] = NI_MIN_HEIGHT / 2 - src_height[2];
3325 
3326  break;
3327 
3329  /* width of source frame for each plane in pixels */
3330  src_width[0] = NIALIGN(raw_width, 2);
3331  src_width[1] = NIALIGN(raw_width, 2) / 2;
3332  src_width[2] = NIALIGN(raw_width, 2) / 2;
3333 
3334  /* height of source frame for each plane in pixels */
3335  src_height[0] = NIALIGN(raw_height, 2);
3336  src_height[1] = NIALIGN(raw_height, 2) / 2;
3337  src_height[2] = NIALIGN(raw_height, 2) / 2;
3338 
3339  /* stride of source frame for each plane in bytes */
3340  src_stride[0] = NIALIGN(src_width[0] * 2, 128);
3341  src_stride[1] = NIALIGN(src_width[1] * 2, 128);
3342  src_stride[2] = NIALIGN(src_width[2] * 2, 128);
3343 
3344  tenBit = 1;
3345 
3346  /* horizontal padding needed for each plane in bytes */
3347  hpad[0] = dst_stride[0] - src_width[0] * 2;
3348  hpad[1] = dst_stride[1] - src_width[1] * 2;
3349  hpad[2] = dst_stride[2] - src_width[2] * 2;
3350 
3351  /* vertical padding needed for each plane in pixels */
3352  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3353  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3354  vpad[2] = NI_MIN_HEIGHT / 2 - src_height[2];
3355 
3356  break;
3357 
3358  case NI_PIX_FMT_NV12:
3359  /* width of source frame for each plane in pixels */
3360  src_width[0] = NIALIGN(raw_width, 2);
3361  src_width[1] = NIALIGN(raw_width, 2);
3362  src_width[2] = 0;
3363 
3364  /* height of source frame for each plane in pixels */
3365  src_height[0] = NIALIGN(raw_height, 2);
3366  src_height[1] = NIALIGN(raw_height, 2) / 2;
3367  src_height[2] = 0;
3368 
3369  /* stride of source frame for each plane in bytes */
3370  src_stride[0] = NIALIGN(src_width[0], 128);
3371  src_stride[1] = NIALIGN(src_width[1], 128);
3372  src_stride[2] = 0;
3373 
3374  tenBit = 0;
3375 
3376  /* horizontal padding needed for each plane in bytes */
3377  hpad[0] = dst_stride[0] - src_width[0];
3378  hpad[1] = dst_stride[1] - src_width[1];
3379  hpad[2] = 0;
3380 
3381  /* vertical padding for each plane in pixels */
3382  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3383  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3384  vpad[2] = 0;
3385 
3386  break;
3387 
3388  case NI_PIX_FMT_P010LE:
3389  /* width of source frame for each plane in pixels */
3390  src_width[0] = NIALIGN(raw_width, 2);
3391  src_width[1] = NIALIGN(raw_width, 2);
3392  src_width[2] = 0;
3393 
3394  /* height of source frame for each plane in pixels */
3395  src_height[0] = NIALIGN(raw_height, 2);
3396  src_height[1] = NIALIGN(raw_height, 2) / 2;
3397  src_height[2] = 0;
3398 
3399  /* stride of source frame for each plane in bytes */
3400  src_stride[0] = NIALIGN(src_width[0] * 2, 128);
3401  src_stride[1] = NIALIGN(src_width[1] * 2, 128);
3402  src_stride[2] = 0;
3403 
3404  tenBit = 1;
3405 
3406  /* horizontal padding needed for each plane in bytes */
3407  hpad[0] = dst_stride[0] - src_width[0] * 2;
3408  hpad[1] = dst_stride[1] - src_width[1] * 2;
3409  hpad[2] = 0;
3410 
3411  /* vertical padding for each plane in pixels */
3412  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3413  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3414  vpad[2] = 0;
3415 
3416  break;
3417 
3418  default:
3419  ni_log(NI_LOG_ERROR, "Invalid pixel format %d\n",ni_fmt);
3420  return NI_RETCODE_FAILURE;
3421  }
3422 
3423  for (i = 0; i < nb_planes && nb_planes < NI_MAX_NUM_DATA_POINTERS; i++)
3424  {
3425  dst_line = dst->p_data[i];
3426  src_line = src->p_data[i];
3427 
3428  for (h = 0; i < 3 && h < src_height[i]; h++)
3429  {
3430  memcpy(dst_line, src_line, src_width[i] * (tenBit + 1));
3431 
3432  /* Add horizontal padding */
3433  if (hpad[i])
3434  {
3435  lastidx = src_width[i];
3436 
3437  if (tenBit)
3438  {
3439  sample = &src_line[(lastidx - 1) * 2];
3440  dest = &dst_line[lastidx * 2];
3441 
3442  /* two bytes per sample */
3443  for (j = 0; j < hpad[i] / 2; j++)
3444  {
3445  memcpy(dest, sample, 2);
3446  dest += 2;
3447  }
3448  } else
3449  {
3450  YUVsample = dst_line[lastidx - 1];
3451  memset(&dst_line[lastidx], YUVsample, hpad[i]);
3452  }
3453  }
3454 
3455  src_line += src_stride[i];
3456  dst_line += dst_stride[i];
3457  }
3458 
3459  /* Pad the height by duplicating the last line */
3460  src_line = dst_line - dst_stride[i];
3461 
3462  for (h = 0; h < vpad[i]; h++)
3463  {
3464  memcpy(dst_line, src_line, dst_stride[i]);
3465  dst_line += dst_stride[i];
3466  }
3467  }
3468 
3469  return 0;
3470 }
3471 
3472 /*!******************************************************************************
3473  * \brief Reset decoder ppu resolution
3474  *
3475  * \param[in] p_session_ctx Pointer to a caller allocated
3476  * ni_session_context_t struct
3477  * \param[in] p_param Pointer to a caller allocated
3478  * ni_xcoder_params_t struct
3479  * \param[in] ppu_config Pointer to a caller allocated
3480  * ni_ppu_config_t struct
3481  *
3482  * \return - 0 on success, NI_RETCODE_FAILURE on failure
3483  ********************************************************************************/
3485  ni_xcoder_params_t *p_param, ni_ppu_config_t *ppu_config)
3486 {
3487  int sei_size, size, len;
3488  int ret = 0, i = 0, j = 0;
3489  uint8_t *p_src_sei_data, *p_dst_sei_data;
3490  ni_custom_sei_t *p_dst_custom_sei;
3491 
3492  if (!p_session_ctx || !p_param || !ppu_config)
3493  {
3495  return ret;
3496  }
3497 
3498  // check fw revision
3499  if (ni_cmp_fw_api_ver(
3500  (char*) &p_session_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
3501  "6rx") < 0)
3502  {
3503  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: not supported on device with FW API version < 6rx\n", __func__);
3505  }
3506 
3507  if (NI_CODEC_FORMAT_H264 != p_session_ctx->codec_format &&
3508  NI_CODEC_FORMAT_H265 != p_session_ctx->codec_format)
3509  {
3510  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Ppu reconfig only support "
3511  "h264 and h265 decoder\n", __func__);
3513  }
3514 
3515  ni_decoder_input_params_t *p_dec_input_param = &(p_param->dec_input_params);
3516  if (p_dec_input_param->hwframes != 1)
3517  {
3518  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Not hw mode, "
3519  "So can't reconfig ppu\n", __func__);
3521  }
3522  if (p_dec_input_param->enable_out1 == 0 &&
3523  ppu_config->ppu_set_enable & (0x01 << 1))
3524  {
3525  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Warning Not enable ppu1, "
3526  "So can't reconfig ppu1\n", __func__);
3528  }
3529  if (p_dec_input_param->enable_out2 == 0 &&
3530  ppu_config->ppu_set_enable & (0x01 << 2))
3531  {
3532  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Warning Not enable ppu2, "
3533  "So can't reconfig ppu2\n", __func__);
3535  }
3536  for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
3537  {
3538  if (ppu_config->ppu_set_enable & (0x01 << i))
3539  {
3540  if (ppu_config->ppu_w[i] > NI_MAX_RESOLUTION_WIDTH ||
3541  ppu_config->ppu_h[i] > NI_MAX_RESOLUTION_HEIGHT ||
3542  ppu_config->ppu_w[i] < NI_MIN_RESOLUTION_WIDTH_SCALER ||
3543  ppu_config->ppu_h[i] < NI_MIN_RESOLUTION_WIDTH_SCALER)
3544  {
3545  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu width x height %dx%d "
3546  "out of range\n", __func__, ppu_config->ppu_w[i], ppu_config->ppu_h[i]);
3548  return ret;
3549  }
3550  if ((ppu_config->ppu_w[i] & 1) || (ppu_config->ppu_h[i] & 1))
3551  {
3552  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu wxh %dx%d not align to 2!\n",
3553  __func__, ppu_config->ppu_w[i], ppu_config->ppu_h[i]);
3555  return ret;
3556  }
3557  }
3558  }
3559  p_dst_custom_sei = malloc(sizeof(ni_custom_sei_t));
3560  if (p_dst_custom_sei == NULL)
3561  {
3562  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): failed "
3563  "to allocate memory for custom sei data\n", __func__);
3565  return ret;
3566  }
3567  memset(p_dst_custom_sei, 0, sizeof(ni_custom_sei_t));
3568 
3569 
3570  sei_size = sizeof(ni_ppu_config_t);
3571 
3572  p_src_sei_data = (uint8_t *)ppu_config;
3573  p_dst_sei_data = &p_dst_custom_sei->data[0];
3574  size = 0;
3575 
3576  // long start code
3577  p_dst_sei_data[size++] = 0x00;
3578  p_dst_sei_data[size++] = 0x00;
3579  p_dst_sei_data[size++] = 0x00;
3580  p_dst_sei_data[size++] = 0x01;
3581 
3582  if (NI_CODEC_FORMAT_H264 == p_session_ctx->codec_format)
3583  {
3584  p_dst_sei_data[size++] = 0x06; //nal type: SEI
3585  }
3586  else
3587  {
3588  p_dst_sei_data[size++] = 0x4e; //nal type: SEI
3589  p_dst_sei_data[size++] = 0x01;
3590  }
3591 
3592  // SEI type
3593  p_dst_sei_data[size++] = NI_SEI_TYPE_PPU_RECONFIG;
3594 
3595  // original payload size
3596  len = sei_size;
3597  while (len >= 0)
3598  {
3599  p_dst_sei_data[size++] = len > 0xff ? 0xff : len;
3600  len -= 0xff;
3601  }
3602 
3603  // payload data
3604  for (j = 0; j < sei_size && size < NI_MAX_CUSTOM_SEI_DATA - 1; j++)
3605  {
3606  if (j >= 2 && !p_dst_sei_data[size - 2] && !p_dst_sei_data[size - 1] && p_src_sei_data[j] <= 0x03)
3607  {
3608  /* insert 0x3 as emulation_prevention_three_byte */
3609  p_dst_sei_data[size++] = 0x03;
3610  }
3611  p_dst_sei_data[size++] = p_src_sei_data[j];
3612  }
3613 
3614  if (j != sei_size)
3615  {
3616  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): sei RBSP size out of limit(%d), "
3617  "idx=%u, size=%d\n", __func__,
3618  NI_MAX_CUSTOM_SEI_DATA, i, sei_size);
3619  free(p_dst_custom_sei);
3620  return NI_RETCODE_FAILURE;
3621  }
3622 
3623  // trailing byte
3624  p_dst_sei_data[size++] = 0x80;
3625 
3626  memcpy(p_session_ctx->p_leftover + p_session_ctx->prev_size,
3627  p_dst_sei_data, size);
3628  p_session_ctx->prev_size += size;
3629  free(p_dst_custom_sei);
3630 
3631  return ret;
3632 }
_ni_ppu_config
Definition: ni_av_codec.h:473
_ni_hdr_plus_color_transform_params::center_of_ellipse_y
uint16_t center_of_ellipse_y
Definition: ni_av_codec.h:295
NI_MAX_FRAMERATE
#define NI_MAX_FRAMERATE
Definition: ni_device_api.h:116
_ni_long_term_ref::use_long_term_ref
uint8_t use_long_term_ref
Definition: ni_device_api.h:693
_ni_mastering_display_metadata::max_luminance
ni_rational_t max_luminance
Definition: ni_av_codec.h:208
_ni_xcoder_params::fps_denominator
uint32_t fps_denominator
Definition: ni_device_api.h:2749
_ni_region_of_interest::left
int left
Definition: ni_device_api.h:638
_ni_xcoder_params::luma_linesize
int luma_linesize
Definition: ni_device_api.h:2814
NI_PIX_FMT_BGRA
@ NI_PIX_FMT_BGRA
Definition: ni_device_api.h:268
_ni_session_context::force_idr_frame
int force_idr_frame
Definition: ni_device_api.h:1602
NI_CODEC_FORMAT_JPEG
@ NI_CODEC_FORMAT_JPEG
Definition: ni_device_api.h:916
NI_FRAME_AUX_DATA_MAX_FRAME_SIZE
@ NI_FRAME_AUX_DATA_MAX_FRAME_SIZE
Definition: ni_device_api.h:568
ni_frame_get_aux_data
ni_aux_data_t * ni_frame_get_aux_data(const ni_frame_t *frame, ni_aux_data_type_t type)
Retrieve from the frame auxiliary data of a given type if exists.
Definition: ni_device_api.c:4067
_ni_session_context::sei_hdr_mastering_display_color_vol_len
int sei_hdr_mastering_display_color_vol_len
Definition: ni_device_api.h:1431
_ni_timecode::nuit_field_based_flag
uint8_t nuit_field_based_flag
Definition: ni_av_codec.h:450
NI_SET_CHANGE_PARAM_RC_TARGET_RATE
@ NI_SET_CHANGE_PARAM_RC_TARGET_RATE
Definition: ni_device_api.h:957
NI_MAX_RESOLUTION_HEIGHT
#define NI_MAX_RESOLUTION_HEIGHT
Definition: ni_device_api.h:101
NI_UNUSED
#define NI_UNUSED
Definition: ni_defs.h:67
NI_DEVICE_TYPE_ENCODER
@ NI_DEVICE_TYPE_ENCODER
Definition: ni_defs.h:359
_ni_timecode::seconds_flag
uint8_t seconds_flag
Definition: ni_av_codec.h:456
_ni_packet::p_custom_sei_set
ni_custom_sei_set_t * p_custom_sei_set
Definition: ni_device_api.h:2883
_ni_dynamic_hdr_plus::mastering_display_actual_peak_luminance
ni_rational_t mastering_display_actual_peak_luminance[25][25]
Definition: ni_av_codec.h:443
NI_GENERATE_ALL_NAL_HEADER_BIT
#define NI_GENERATE_ALL_NAL_HEADER_BIT
Definition: ni_av_codec.h:42
MASTERING_DISP_CHROMA_DEN
#define MASTERING_DISP_CHROMA_DEN
Definition: ni_av_codec.h:217
_ni_timecode::discontinuity_flag
uint8_t discontinuity_flag
Definition: ni_av_codec.h:453
_ni_session_context::ltr_interval
int32_t ltr_interval
Definition: ni_device_api.h:1604
_ni_session_context::decoder_low_delay
int decoder_low_delay
Definition: ni_device_api.h:1596
_ni_dynamic_hdr_plus::targeted_system_display_actual_peak_luminance
ni_rational_t targeted_system_display_actual_peak_luminance[25][25]
Definition: ni_av_codec.h:426
ni_bitstream.h
Utility definitions to operate on bits in a bitstream.
_ni_content_light_level_info_bytes
payload format of HDR SEI content light level info
Definition: ni_device_api.h:1076
NI_SET_CHANGE_PARAM_CRF
@ NI_SET_CHANGE_PARAM_CRF
Definition: ni_device_api.h:975
_ni_timecode::minutes_flag
uint8_t minutes_flag
Definition: ni_av_codec.h:458
_ni_frame::vui_len
unsigned int vui_len
Definition: ni_device_api.h:2676
_ni_frame::sei_hdr_content_light_level_info_offset
unsigned int sei_hdr_content_light_level_info_offset
Definition: ni_device_api.h:2663
_ni_dynamic_hdr_plus::targeted_system_display_maximum_luminance
ni_rational_t targeted_system_display_maximum_luminance
Definition: ni_av_codec.h:408
_ni_decoder_input_params_t::enable_out1
int enable_out1
Definition: ni_device_api.h:2521
_ni_session_context::nb_rois
int nb_rois
Definition: ni_device_api.h:1583
_ni_frame::sar_width
uint16_t sar_width
Definition: ni_device_api.h:2713
_ni_session_context::itu_t_t35_cc_sei_hdr_h264
uint8_t itu_t_t35_cc_sei_hdr_h264[NI_CC_SEI_HDR_H264_LEN]
Definition: ni_device_api.h:1420
_ni_hdr_plus_color_transform_params::fraction_bright_pixels
ni_rational_t fraction_bright_pixels
Definition: ni_av_codec.h:352
_ni_session_context::mdcv_max_min_lum_data_len
int mdcv_max_min_lum_data_len
Definition: ni_device_api.h:1432
SLICE_TYPE_P
@ SLICE_TYPE_P
Definition: ni_av_codec.c:46
_ni_custom_sei::size
uint32_t size
Definition: ni_device_api.h:1123
_ni_timecode::cnt_dropped_flag
uint8_t cnt_dropped_flag
Definition: ni_av_codec.h:454
_ni_session_context::preferred_characteristics_data
uint8_t preferred_characteristics_data
Definition: ni_device_api.h:1435
_ni_frame::aspect_ratio_idc
uint8_t aspect_ratio_idc
Definition: ni_device_api.h:2712
SLICE_TYPE_I
@ SLICE_TYPE_I
Definition: ni_av_codec.c:47
NI_ENC_MAX_SEI_BUF_SIZE
#define NI_ENC_MAX_SEI_BUF_SIZE
Definition: ni_device_api.h:401
_ni_hdr_plus_color_transform_params::maxscl
ni_rational_t maxscl[3]
Definition: ni_av_codec.h:334
ni_encoder_change_params_t
struct _ni_encoder_change_params_t ni_encoder_change_params_t
This is a data structure for encoding parameters that have changed.
NI_SET_CHANGE_PARAM_VBV
@ NI_SET_CHANGE_PARAM_VBV
Definition: ni_device_api.h:976
_ni_session_context::itu_t_t35_hdr10p_sei_hdr_h264
uint8_t itu_t_t35_hdr10p_sei_hdr_h264[NI_HDR10P_SEI_HDR_H264_LEN]
Definition: ni_device_api.h:1422
_ni_dec_mastering_display_colour_volume_bytes
decoded payload format of HDR SEI mastering display colour volume
Definition: ni_device_api.h:1063
ni_device_api_priv.h
Private definitions used by ni_device_api.c for video processing tasks.
ni_enc_copy_aux_data
void ni_enc_copy_aux_data(ni_session_context_t *p_enc_ctx, ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame, ni_codec_format_t codec_format, const uint8_t *mdcv_data, const uint8_t *cll_data, const uint8_t *cc_data, const uint8_t *udu_data, const uint8_t *hdrp_data, int is_hwframe, int is_semiplanar)
Copy auxiliary data that should be sent together with this frame to encoder.
Definition: ni_av_codec.c:2266
_ni_vui_hrd
Definition: ni_device_api.h:656
_ni_session_context::ui8_mdcv_max_min_lum_data
uint8_t ui8_mdcv_max_min_lum_data[9]
Definition: ni_device_api.h:1433
_ni_rc_min_max_qp::minQpI
int32_t minQpI
Definition: ni_device_api.h:708
_ni_hdr_plus_color_transform_params::distribution_maxrgb
ni_hdr_plus_percentile_t distribution_maxrgb[15]
Definition: ni_av_codec.h:347
_ni_dynamic_hdr_plus::num_windows
uint8_t num_windows
Definition: ni_av_codec.h:400
SLICE_TYPE_B
@ SLICE_TYPE_B
Definition: ni_av_codec.c:45
_ni_session_context::roi_side_data_size
int roi_side_data_size
Definition: ni_device_api.h:1580
_ni_extended_dec_metadata
Definition: ni_device_api.h:723
_ni_xcoder_params::source_width
int source_width
Definition: ni_device_api.h:2753
_ni_frame::reconf_len
unsigned int reconf_len
Definition: ni_device_api.h:2681
ni_enc_insert_timecode
LIB_API int ni_enc_insert_timecode(ni_session_context_t *p_enc_ctx, ni_frame_t *p_enc_frame, ni_timecode_t *p_timecode)
Insert timecode data into picture timing SEI (H264) or time code SEI (H265)
Definition: ni_av_codec.c:2452
_ni_dynamic_hdr_plus::itu_t_t35_country_code
uint8_t itu_t_t35_country_code
Definition: ni_av_codec.h:392
_ni_session_context::target_bitrate
int32_t target_bitrate
Definition: ni_device_api.h:1601
_ni_timecode::full_timestamp_flag
uint8_t full_timestamp_flag
Definition: ni_av_codec.h:452
_ni_custom_sei::location
ni_custom_sei_location_t location
Definition: ni_device_api.h:1122
NI_HDR10P_SEI_HDR_H264_LEN
#define NI_HDR10P_SEI_HDR_H264_LEN
Definition: ni_device_api.h:465
_ni_mastering_display_metadata::has_primaries
int has_primaries
Definition: ni_av_codec.h:211
PIC_TYPE_P
@ PIC_TYPE_P
Definition: ni_device_api.h:387
NI_CODEC_HW_NONE
@ NI_CODEC_HW_NONE
Definition: ni_device_api.h:941
NI_PIX_FMT_YUV420P
@ NI_PIX_FMT_YUV420P
Definition: ni_device_api.h:263
_ni_rc_min_max_qp
Definition: ni_device_api.h:706
_ni_mastering_display_metadata::min_luminance
ni_rational_t min_luminance
Definition: ni_av_codec.h:205
_ni_session_context::p_leftover
uint8_t * p_leftover
Definition: ni_device_api.h:1508
_ni_session_context::ltr_to_set
ni_long_term_ref_t ltr_to_set
Definition: ni_device_api.h:1603
_ni_encoder_change_params_t::frameRateDenom
int32_t frameRateDenom
Definition: ni_device_api.h:1053
GOP_PRESET_BBBBBBBSP_8
@ GOP_PRESET_BBBBBBBSP_8
Definition: ni_av_codec.c:72
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:439
_ni_content_light_level::max_fall
uint16_t max_fall
Definition: ni_av_codec.h:227
_ni_framerate::framerate_denom
int32_t framerate_denom
Definition: ni_device_api.h:703
ni_bs_writer_clear
void ni_bs_writer_clear(ni_bitstream_writer_t *stream)
clear and reset bitstream
Definition: ni_bitstream.c:310
_ni_dynamic_hdr_plus
Definition: ni_av_codec.h:389
ni_encoder_sw_frame_buffer_alloc
ni_retcode_t ni_encoder_sw_frame_buffer_alloc(bool planar, ni_frame_t *p_frame, int video_width, int video_height, int linesize[], int alignment, int extra_len, bool alignment_2pass_wa)
This API is a wrapper for ni_encoder_frame_buffer_alloc(), used for planar pixel formats,...
Definition: ni_device_api.c:3532
_ni_session_context::av_rois
ni_region_of_interest_t * av_rois
Definition: ni_device_api.h:1582
_ni_frame::color_trc
uint8_t color_trc
Definition: ni_device_api.h:2709
NI_FRAME_AUX_DATA_CRF
@ NI_FRAME_AUX_DATA_CRF
Definition: ni_device_api.h:576
_ni_region_of_interest
Definition: ni_device_api.h:628
_ni_timecode::hours_value
uint8_t hours_value
Definition: ni_av_codec.h:461
_ni_session_context::last_bitrate
int32_t last_bitrate
Definition: ni_device_api.h:1676
_ni_session_context::actual_video_width
uint32_t actual_video_width
Definition: ni_device_api.h:1555
ni_enc_write_from_yuv_buffer
int ni_enc_write_from_yuv_buffer(ni_session_context_t *p_ctx, ni_frame_t *p_enc_frame, uint8_t *p_yuv_buffer)
Send an input data frame to the encoder with YUV data given in the inputs.
Definition: ni_av_codec.c:2624
_ni_hdr_plus_color_transform_params::rotation_angle
uint8_t rotation_angle
Definition: ni_av_codec.h:302
_ni_encoder_change_params_t::bitRate
int32_t bitRate
Definition: ni_device_api.h:989
_ni_custom_sei::data
uint8_t data[NI_MAX_CUSTOM_SEI_DATA]
Definition: ni_device_api.h:1124
_ni_hdr_plus_color_transform_params::center_of_ellipse_x
uint16_t center_of_ellipse_x
Definition: ni_av_codec.h:289
_ni_frame::vui_num_units_in_tick
uint32_t vui_num_units_in_tick
Definition: ni_device_api.h:2715
_ni_region_of_interest::right
int right
Definition: ni_device_api.h:639
ni_av_codec.h
Audio/video related utility definitions.
NUM_GOP_PRESET_NUM
@ NUM_GOP_PRESET_NUM
Definition: ni_av_codec.c:73
NI_HDR10P_SEI_HDR_HEVC_LEN
#define NI_HDR10P_SEI_HDR_HEVC_LEN
Definition: ni_device_api.h:464
_ni_encoder_cfg_params::roi_enable
int roi_enable
Definition: ni_device_api.h:2271
_ni_encoder_cfg_params::intra_period
int intra_period
Definition: ni_device_api.h:2274
_ni_hdr_plus_color_transform_params::color_saturation_weight
ni_rational_t color_saturation_weight
Definition: ni_av_codec.h:384
NI_NAL_SPS_BIT
#define NI_NAL_SPS_BIT
Definition: ni_av_codec.h:40
_ni_frame::separate_metadata
uint8_t separate_metadata
Definition: ni_device_api.h:2724
_ni_session_context::reconfig_slice_arg
int16_t reconfig_slice_arg
Definition: ni_device_api.h:1708
_ni_bitstream_writer_t
Definition: ni_bitstream.h:75
ni_encoder_frame_zerocopy_check
ni_retcode_t ni_encoder_frame_zerocopy_check(ni_session_context_t *p_enc_ctx, ni_xcoder_params_t *p_enc_params, int width, int height, const int linesize[], bool set_linesize)
Check if incoming frame is encoder zero copy compatible or not.
Definition: ni_device_api.c:2733
_ni_session_context::light_level_data_len
int light_level_data_len
Definition: ni_device_api.h:1429
NI_INVALID_SEI_TYPE
#define NI_INVALID_SEI_TYPE
Definition: ni_defs.h:312
_ni_encoder_change_params_t::minQpPB
int32_t minQpPB
Definition: ni_device_api.h:1005
NI_FRAME_AUX_DATA_SLICE_ARG
@ NI_FRAME_AUX_DATA_SLICE_ARG
Definition: ni_device_api.h:592
_ni_encoder_cfg_params::gop_preset_index
int gop_preset_index
Definition: ni_device_api.h:2265
_ni_frame::sei_user_data_unreg_len
unsigned int sei_user_data_unreg_len
Definition: ni_device_api.h:2670
ni_pic_type_t
ni_pic_type_t
Definition: ni_device_api.h:384
_ni_xcoder_params::roi_demo_mode
int roi_demo_mode
Definition: ni_device_api.h:2760
_ni_encoder_cfg_params::intra_mb_refresh_mode
int intra_mb_refresh_mode
Definition: ni_device_api.h:2275
NI_MIN_RESOLUTION_WIDTH_SCALER
#define NI_MIN_RESOLUTION_WIDTH_SCALER
Definition: ni_device_api.h:94
_ni_frame::sei_total_len
unsigned int sei_total_len
Definition: ni_device_api.h:2655
_ni_encoder_change_params_t::aspectRatioHeight
uint16_t aspectRatioHeight
Definition: ni_device_api.h:1026
_ni_encoder_change_params_t::enable_option
uint32_t enable_option
Definition: ni_device_api.h:986
NI_RETCODE_INVALID_PARAM
@ NI_RETCODE_INVALID_PARAM
Definition: ni_defs.h:441
ni_bitstream_writer_init
void ni_bitstream_writer_init(ni_bitstream_writer_t *stream)
init a bitstream writer
Definition: ni_bitstream.c:158
_ni_timecode::time_offset_length
uint8_t time_offset_length
Definition: ni_av_codec.h:462
ni_ppu_config_t
struct _ni_ppu_config ni_ppu_config_t
_ni_encoder_cfg_params::rc
struct _ni_encoder_cfg_params::@16 rc
GOP_PRESET_RA_8
@ GOP_PRESET_RA_8
Definition: ni_av_codec.c:61
_ni_mastering_display_metadata
Definition: ni_av_codec.h:196
_ni_content_light_level
Definition: ni_av_codec.h:221
_ni_frame::preferred_characteristics_data_len
uint8_t preferred_characteristics_data_len
Definition: ni_device_api.h:2697
_ni_session_context::bit_depth_factor
int bit_depth_factor
Definition: ni_device_api.h:1496
GOP_PRESET_BBBSP_3
@ GOP_PRESET_BBBSP_3
Definition: ni_av_codec.c:65
_ni_session_context::reconfig_crf_decimal
int reconfig_crf_decimal
Definition: ni_device_api.h:1688
_ni_encoder_change_params_t
This is a data structure for encoding parameters that have changed.
Definition: ni_device_api.h:984
ni_bs_reader_get_bits
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
Definition: ni_bitstream.c:481
_ni_frame::force_pic_qp
uint16_t force_pic_qp
Definition: ni_device_api.h:2685
NI_FRAME_AUX_DATA_HDR_PLUS
@ NI_FRAME_AUX_DATA_HDR_PLUS
Definition: ni_device_api.h:516
_ni_hdr_plus_color_transform_params::window_lower_right_corner_x
ni_rational_t window_lower_right_corner_x
Definition: ni_av_codec.h:276
_ni_aux_data::size
int size
Definition: ni_device_api.h:624
_ni_encoder_cfg_params::crf
int crf
Definition: ni_device_api.h:2283
ni_copy_hw_yuv420p
void ni_copy_hw_yuv420p(uint8_t *p_dst[NI_MAX_NUM_DATA_POINTERS], uint8_t *p_src[NI_MAX_NUM_DATA_POINTERS], int frame_width, int frame_height, int factor, int is_semiplanar, int conf_win_right, int dst_stride[NI_MAX_NUM_DATA_POINTERS], int dst_height[NI_MAX_NUM_DATA_POINTERS], int src_stride[NI_MAX_NUM_DATA_POINTERS], int src_height[NI_MAX_NUM_DATA_POINTERS])
Copy YUV data to Netint HW YUV420p frame layout to be sent to encoder for encoding....
Definition: ni_util.c:2352
_ni_region_of_interest::self_size
uint32_t self_size
Definition: ni_device_api.h:631
NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE
@ NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE
Definition: ni_device_api.h:588
_ni_xcoder_params::fps_number
uint32_t fps_number
Definition: ni_device_api.h:2748
NI_FRAME_AUX_DATA_VBV_MAX_RATE
@ NI_FRAME_AUX_DATA_VBV_MAX_RATE
Definition: ni_device_api.h:584
_ni_enc_quad_roi_custom_map::roiAbsQp_flag
uint8_t roiAbsQp_flag
Definition: ni_device_api.h:889
ni_cmp_fw_api_ver
int ni_cmp_fw_api_ver(const char ver1[], const char ver2[])
Compare two 3 character strings containing a FW API version. Handle comparision when FW API version f...
Definition: ni_util.c:3674
_ni_ppu_config::ppu_w
uint16_t ppu_w[NI_MAX_NUM_OF_DECODER_OUTPUTS]
Definition: ni_av_codec.h:475
NI_SET_CHANGE_PARAM_VUI_HRD_PARAM
@ NI_SET_CHANGE_PARAM_VUI_HRD_PARAM
Definition: ni_device_api.h:970
_ni_session_context::reconfig_intra_period
int reconfig_intra_period
Definition: ni_device_api.h:1706
NI_RETCODE_ERROR_MEM_ALOC
@ NI_RETCODE_ERROR_MEM_ALOC
Definition: ni_defs.h:443
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:437
NI_FRAME_AUX_DATA_MAX_MIN_QP
@ NI_FRAME_AUX_DATA_MAX_MIN_QP
Definition: ni_device_api.h:572
_ni_content_light_level::max_cll
uint16_t max_cll
Definition: ni_av_codec.h:224
_ni_vui_hrd::colorPrimaries
int32_t colorPrimaries
Definition: ni_device_api.h:663
ni_hdr_plus_overlap_process_option_t
enum _ni_hdr_plus_overlap_process_option ni_hdr_plus_overlap_process_option_t
SESSION_RUN_STATE_SEQ_CHANGE_DRAINING
@ SESSION_RUN_STATE_SEQ_CHANGE_DRAINING
Definition: ni_device_api.h:1180
NI_FRAME_AUX_DATA_UDU_SEI
@ NI_FRAME_AUX_DATA_UDU_SEI
Definition: ni_device_api.h:527
NI_CC_SEI_HDR_H264_LEN
#define NI_CC_SEI_HDR_H264_LEN
Definition: ni_device_api.h:466
_ni_enc_mastering_display_colour_volume::white_point_y
uint16_t white_point_y
Definition: ni_device_api.h:1090
_ni_session_context::fw_rev
uint8_t fw_rev[8]
Definition: ni_device_api.h:1627
_ni_enc_mastering_display_colour_volume::display_primaries
uint16_t display_primaries[3][2]
Definition: ni_device_api.h:1088
ni_enc_prep_aux_data
void ni_enc_prep_aux_data(ni_session_context_t *p_enc_ctx, ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame, ni_codec_format_t codec_format, int should_send_sei_with_frame, uint8_t *mdcv_data, uint8_t *cll_data, uint8_t *cc_data, uint8_t *udu_data, uint8_t *hdrp_data)
Prepare auxiliary data that should be sent together with this frame to encoder based on the auxiliary...
Definition: ni_av_codec.c:857
ni_frame_new_aux_data
ni_aux_data_t * ni_frame_new_aux_data(ni_frame_t *frame, ni_aux_data_type_t type, int data_size)
Add a new auxiliary data to a frame.
Definition: ni_device_api.c:4006
NI_RETCODE_PARAM_INVALID_VALUE
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition: ni_defs.h:449
_ni_encoder_change_params_t::colorPrimaries
uint8_t colorPrimaries
Definition: ni_device_api.h:1022
_ni_frame::sei_hdr_mastering_display_color_vol_offset
unsigned int sei_hdr_mastering_display_color_vol_offset
Definition: ni_device_api.h:2661
_ni_frame::sei_cc_offset
unsigned int sei_cc_offset
Definition: ni_device_api.h:2658
_ni_session_context::reconfig_vbv_buffer_size
int reconfig_vbv_buffer_size
Definition: ni_device_api.h:1690
_ni_session_context::framerate
ni_framerate_t framerate
Definition: ni_device_api.h:1606
_ni_hdr_plus_color_transform_params::window_upper_left_corner_y
ni_rational_t window_upper_left_corner_y
Definition: ni_av_codec.h:269
_ni_encoder_change_params_t::crf
uint8_t crf
Definition: ni_device_api.h:1040
GOP_PRESET_BSP_2
@ GOP_PRESET_BSP_2
Definition: ni_av_codec.c:64
_ni_rational
Definition: ni_device_api.h:600
_ni_long_term_ref
Definition: ni_device_api.h:685
NI_LOG_INFO
@ NI_LOG_INFO
Definition: ni_log.h:61
_ni_vui_hrd::colorDescPresent
int32_t colorDescPresent
Definition: ni_device_api.h:659
_ni_timecode::time_offset_value
uint32_t time_offset_value
Definition: ni_av_codec.h:463
_ni_session_context::reconfig_vbv_max_rate
int reconfig_vbv_max_rate
Definition: ni_device_api.h:1691
GOP_PRESET_P_1
@ GOP_PRESET_P_1
Definition: ni_av_codec.c:55
ni_bs_writer_copy
void ni_bs_writer_copy(uint8_t *dst, const ni_bitstream_writer_t *stream)
copy bitstream data to dst Note: caller must ensure sufficient space in dst
Definition: ni_bitstream.c:292
GOP_PRESET_BBP_3
@ GOP_PRESET_BBP_3
Definition: ni_av_codec.c:69
_ni_xcoder_params::source_height
int source_height
Definition: ni_device_api.h:2758
MASTERING_DISP_LUMA_DEN
#define MASTERING_DISP_LUMA_DEN
Definition: ni_av_codec.h:218
NI_APP_ENC_FRAME_META_DATA_SIZE
#define NI_APP_ENC_FRAME_META_DATA_SIZE
Definition: ni_defs.h:320
_ni_encoder_change_params_t::colorSpace
uint8_t colorSpace
Definition: ni_device_api.h:1024
_ni_encoder_change_params_t::maxDeltaQp
int32_t maxDeltaQp
Definition: ni_device_api.h:1003
NI_MAX_CUSTOM_SEI_CNT
#define NI_MAX_CUSTOM_SEI_CNT
Definition: ni_defs.h:315
NI_LOG_ERROR
@ NI_LOG_ERROR
Definition: ni_log.h:60
NI_SEI_TYPE_PPU_RECONFIG
#define NI_SEI_TYPE_PPU_RECONFIG
Definition: ni_av_codec.h:50
_ni_hdr_plus_percentile::percentile
ni_rational_t percentile
Definition: ni_av_codec.h:250
_ni_frame::ni_pict_type
ni_pic_type_t ni_pict_type
Definition: ni_device_api.h:2653
_ni_ppu_config::ppu_set_enable
uint8_t ppu_set_enable
Definition: ni_av_codec.h:474
NI_FRAME_AUX_DATA_VUI
@ NI_FRAME_AUX_DATA_VUI
Definition: ni_device_api.h:545
_ni_vui_hrd::colorTrc
int32_t colorTrc
Definition: ni_device_api.h:667
NI_MAX_RESOLUTION_WIDTH
#define NI_MAX_RESOLUTION_WIDTH
Definition: ni_device_api.h:100
_ni_framerate::framerate_num
int32_t framerate_num
Definition: ni_device_api.h:700
NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
@ NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
Definition: ni_defs.h:533
_ni_timecode::hours_flag
uint8_t hours_flag
Definition: ni_av_codec.h:460
_ni_xcoder_params::cfg_enc_params
ni_encoder_cfg_params_t cfg_enc_params
Definition: ni_device_api.h:2795
ni_bs_writer_put
void ni_bs_writer_put(ni_bitstream_writer_t *stream, uint32_t data, uint8_t bits)
write a specified number (<= 32) of bits to bitstream, buffer individual bits until a full byte is ma...
Definition: ni_bitstream.c:183
NI_PIX_FMT_NV12
@ NI_PIX_FMT_NV12
Definition: ni_device_api.h:265
NI_SET_CHANGE_PARAM_SLICE_ARG
@ NI_SET_CHANGE_PARAM_SLICE_ARG
Definition: ni_device_api.h:961
_ni_frame::data_len
uint32_t data_len[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2690
NI_MAX_SLICE_SIZE
#define NI_MAX_SLICE_SIZE
Definition: ni_device_api.h:220
_ni_frame::extra_data_len
unsigned int extra_data_len
Definition: ni_device_api.h:2683
_ni_encoder_change_params_t::maxFrameSize
uint16_t maxFrameSize
Definition: ni_device_api.h:1043
_ni_encoder_cfg_params::intra_qp
int intra_qp
Definition: ni_device_api.h:2382
_ni_hdr_plus_percentile::percentage
uint8_t percentage
Definition: ni_av_codec.h:245
_ni_encoder_change_params_t::crfDecimal
uint8_t crfDecimal
Definition: ni_device_api.h:1039
_ni_decoder_input_params_t::hwframes
int hwframes
Definition: ni_device_api.h:2520
NI_MAX_QP_DELTA
#define NI_MAX_QP_DELTA
Definition: ni_device_api.h:172
_ni_encoder_change_params_t::colorDescPresent
uint8_t colorDescPresent
Definition: ni_device_api.h:1021
ni_frame_new_aux_data_from_raw_data
ni_aux_data_t * ni_frame_new_aux_data_from_raw_data(ni_frame_t *frame, ni_aux_data_type_t type, const uint8_t *raw_data, int data_size)
Add a new auxiliary data to a frame and copy in the raw data.
Definition: ni_device_api.c:4046
NI_FRAME_AUX_DATA_FRAMERATE
@ NI_FRAME_AUX_DATA_FRAMERATE
Definition: ni_device_api.h:564
GOP_PRESET_B_1
@ GOP_PRESET_B_1
Definition: ni_av_codec.c:56
_ni_decoder_input_params_t
Definition: ni_device_api.h:2466
NI_RBSP_TRAILING_BITS_LEN
#define NI_RBSP_TRAILING_BITS_LEN
Definition: ni_device_api.h:468
NI_MEM_PAGE_ALIGNMENT
#define NI_MEM_PAGE_ALIGNMENT
Definition: ni_defs.h:263
NI_LOG_TRACE
@ NI_LOG_TRACE
Definition: ni_log.h:63
NI_FRAME_AUX_DATA_A53_CC
@ NI_FRAME_AUX_DATA_A53_CC
Definition: ni_device_api.h:504
_ni_frame::end_of_stream
uint32_t end_of_stream
Definition: ni_device_api.h:2634
_ni_dynamic_hdr_plus::mastering_display_actual_peak_luminance_flag
uint8_t mastering_display_actual_peak_luminance_flag
Definition: ni_av_codec.h:430
PIC_TYPE_IDR
@ PIC_TYPE_IDR
Definition: ni_device_api.h:391
_ni_session_context::prev_size
int prev_size
Definition: ni_device_api.h:1509
_ni_session_context::enc_change_params
ni_encoder_change_params_t * enc_change_params
Definition: ni_device_api.h:1594
_ni_session_context::p_session_config
void * p_session_config
Definition: ni_device_api.h:1475
NI_CODEC_FORMAT_AV1
@ NI_CODEC_FORMAT_AV1
Definition: ni_device_api.h:917
_ni_mastering_display_metadata::has_luminance
int has_luminance
Definition: ni_av_codec.h:214
_ni_frame::sei_hdr_plus_len
unsigned int sei_hdr_plus_len
Definition: ni_device_api.h:2667
_ni_hdr_plus_color_transform_params::color_saturation_mapping_flag
uint8_t color_saturation_mapping_flag
Definition: ni_av_codec.h:379
GOP_PRESET_LP_4
@ GOP_PRESET_LP_4
Definition: ni_av_codec.c:59
GOP_PRESET_BP_2
@ GOP_PRESET_BP_2
Definition: ni_av_codec.c:57
_ni_encoder_change_params_t::intraPeriod
int32_t intraPeriod
Definition: ni_device_api.h:1016
_ni_custom_sei_set
Definition: ni_device_api.h:1127
_ni_region_of_interest::top
int top
Definition: ni_device_api.h:636
ni_dec_packet_parse
int ni_dec_packet_parse(ni_session_context_t *p_session_ctx, ni_xcoder_params_t *p_param, uint8_t *data, int size, ni_packet_t *p_packet, int low_delay, int codec_format, int pkt_nal_bitmap, int custom_sei_type, int *svct_skip_next_packet, int *is_lone_sei_pkt)
Decode parse packet.
Definition: ni_av_codec.c:3064
_ni_session_data_io
Definition: ni_device_api.h:2896
_ni_enc_quad_roi_custom_map::ipcm_flag
uint8_t ipcm_flag
Definition: ni_device_api.h:893
_ni_decoder_input_params_t::svct_decoding_layer
int svct_decoding_layer
Definition: ni_device_api.h:2543
ni_find_start_code
const uint8_t * ni_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state)
Find the next start code.
Definition: ni_av_codec.c:2896
_ni_enc_quad_roi_custom_map::field
struct _ni_enc_quad_roi_custom_map::@6 field
_ni_rational::num
int num
Definition: ni_device_api.h:602
NI_PIX_FMT_YUV420P10LE
@ NI_PIX_FMT_YUV420P10LE
Definition: ni_device_api.h:264
_ni_enc_mastering_display_colour_volume
encoded payload format of HDR SEI mastering display colour volume
Definition: ni_device_api.h:1086
ni_log
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition: ni_log.c:183
NI_XCODER_REVISION_API_MAJOR_VER_IDX
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
Definition: ni_defs.h:99
_ni_frame::vui_time_scale
uint32_t vui_time_scale
Definition: ni_device_api.h:2716
NI_FRAME_AUX_DATA_REGIONS_OF_INTEREST
@ NI_FRAME_AUX_DATA_REGIONS_OF_INTEREST
Definition: ni_device_api.h:521
NI_APP_ENC_FRAME_META_DATA_SIZE_UNDER_MAJOR_6_MINOR_Q
#define NI_APP_ENC_FRAME_META_DATA_SIZE_UNDER_MAJOR_6_MINOR_Q
Definition: ni_defs.h:322
_ni_encoder_change_params_t::frameRateNum
int32_t frameRateNum
Definition: ni_device_api.h:1052
_ni_encoder_cfg_params
Definition: ni_device_api.h:2067
GOP_PRESET_LSP_4
@ GOP_PRESET_LSP_4
Definition: ni_av_codec.c:66
GOP_PRESET_BBBBBBBP_8
@ GOP_PRESET_BBBBBBBP_8
Definition: ni_av_codec.c:71
SLICE_TYPE_MP
@ SLICE_TYPE_MP
Definition: ni_av_codec.c:48
_ni_session_context::ui8_light_level_data
uint8_t ui8_light_level_data[5]
Definition: ni_device_api.h:1430
_ni_frame::force_key_frame
int force_key_frame
Definition: ni_device_api.h:2650
ni_encoder_frame_zerocopy_buffer_alloc
ni_retcode_t ni_encoder_frame_zerocopy_buffer_alloc(ni_frame_t *p_frame, int video_width, int video_height, const int linesize[], const uint8_t *data[], int extra_len)
Allocate memory for encoder zero copy (metadata, etc.) for encoding based on given parameters,...
Definition: ni_device_api.c:2880
ni_expand_frame
int ni_expand_frame(ni_frame_t *dst, ni_frame_t *src, int dst_stride[], int raw_width, int raw_height, int ni_fmt, int nb_planes)
Expand frame form src frame.
Definition: ni_av_codec.c:3288
_ni_aux_data::data
void * data
Definition: ni_device_api.h:623
ni_dec_retrieve_aux_data
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...
Definition: ni_av_codec.c:237
_ni_xcoder_params::chroma_linesize
int chroma_linesize
Definition: ni_device_api.h:2815
_ni_packet
Definition: ni_device_api.h:2855
_ni_session_context::frame_num
uint64_t frame_num
Definition: ni_device_api.h:1533
_ni_frame::sei_cc_len
unsigned int sei_cc_len
Definition: ni_device_api.h:2659
_ni_session_context::roi_map
ni_enc_quad_roi_custom_map * roi_map
Definition: ni_device_api.h:1584
NI_MAX_CUSTOM_SEI_DATA
#define NI_MAX_CUSTOM_SEI_DATA
Definition: ni_device_api.h:430
_ni_custom_sei::type
uint8_t type
Definition: ni_device_api.h:1121
ni_bs_writer_tell
uint64_t ni_bs_writer_tell(const ni_bitstream_writer_t *const stream)
return the number of bits written to bitstream so far
Definition: ni_bitstream.c:169
_ni_hdr_plus_color_transform_params::window_lower_right_corner_y
ni_rational_t window_lower_right_corner_y
Definition: ni_av_codec.h:283
_ni_frame::vui_offset
unsigned int vui_offset
Definition: ni_device_api.h:2675
_ni_session_context::force_idr_intra_offset
uint32_t force_idr_intra_offset
Definition: ni_device_api.h:1650
_ni_frame::p_data
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2689
NI_DEFAULT_INTRA_QP
#define NI_DEFAULT_INTRA_QP
Definition: ni_device_api.h:169
_ni_frame::roi_len
unsigned int roi_len
Definition: ni_device_api.h:2679
_ni_decoder_input_params_t::enable_all_sei_passthru
bool enable_all_sei_passthru
Definition: ni_device_api.h:2551
_ni_dynamic_hdr_plus::params
ni_hdr_plus_color_transform_params_t params[3]
Definition: ni_av_codec.h:403
NI_COL_TRC_UNSPECIFIED
@ NI_COL_TRC_UNSPECIFIED
Definition: ni_av_codec.h:125
_ni_session_context::vui
ni_vui_hrd_t vui
Definition: ni_device_api.h:1607
_ni_frame::sei_hdr_plus_offset
unsigned int sei_hdr_plus_offset
Definition: ni_device_api.h:2666
_ni_session_context::hw_action
int hw_action
Definition: ni_device_api.h:1611
_ni_session_context
Definition: ni_device_api.h:1410
_ni_session_context::itu_t_t35_cc_sei_hdr_hevc
uint8_t itu_t_t35_cc_sei_hdr_hevc[NI_CC_SEI_HDR_HEVC_LEN]
Definition: ni_device_api.h:1419
_ni_rc_min_max_qp::minQpPB
int32_t minQpPB
Definition: ni_device_api.h:711
ni_get_planar_from_pixfmt
int ni_get_planar_from_pixfmt(int pix_fmt)
Grab planar info from NI_PIX_FMT.
Definition: ni_device_api_priv.c:15942
NI_PIX_FMT_P010LE
@ NI_PIX_FMT_P010LE
Definition: ni_device_api.h:266
_ni_region_of_interest::qoffset
ni_rational_t qoffset
Definition: ni_device_api.h:644
NI_MAX_NUM_DATA_POINTERS
#define NI_MAX_NUM_DATA_POINTERS
Definition: ni_defs.h:244
_ni_timecode::n_frames
uint16_t n_frames
Definition: ni_av_codec.h:455
NI_MIN_QP_DELTA
#define NI_MIN_QP_DELTA
Definition: ni_device_api.h:171
_ni_frame
Definition: ni_device_api.h:2627
_ni_timecode::minutes_value
uint8_t minutes_value
Definition: ni_av_codec.h:459
NI_PIX_FMT_RGBA
@ NI_PIX_FMT_RGBA
Definition: ni_device_api.h:267
_ni_encoder_change_params_t::maxQpPB
int32_t maxQpPB
Definition: ni_device_api.h:1006
_ni_frame::color_space
uint8_t color_space
Definition: ni_device_api.h:2710
_ni_session_context::roi_len
uint32_t roi_len
Definition: ni_device_api.h:1498
ni_reconfig_ppu_output
int ni_reconfig_ppu_output(ni_session_context_t *p_session_ctx, ni_xcoder_params_t *p_param, ni_ppu_config_t *ppu_config)
Reset decoder ppu resolution.
Definition: ni_av_codec.c:3484
NI_SET_CHANGE_PARAM_MAX_FRAME_SIZE
@ NI_SET_CHANGE_PARAM_MAX_FRAME_SIZE
Definition: ni_device_api.h:974
NI_PIX_FMT_ABGR
@ NI_PIX_FMT_ABGR
Definition: ni_device_api.h:270
_ni_frame::color_primaries
uint8_t color_primaries
Definition: ni_device_api.h:2708
GOP_PRESET_BBBP_3
@ GOP_PRESET_BBBP_3
Definition: ni_av_codec.c:58
NI_PIX_FMT_ARGB
@ NI_PIX_FMT_ARGB
Definition: ni_device_api.h:269
_ni_xcoder_params
Definition: ni_device_api.h:2743
_ni_frame::sei_hdr_content_light_level_info_len
unsigned int sei_hdr_content_light_level_info_len
Definition: ni_device_api.h:2664
_ni_enc_mastering_display_colour_volume::white_point_x
uint16_t white_point_x
Definition: ni_device_api.h:1089
gop_preset_t
gop_preset_t
Definition: ni_av_codec.c:51
NI_NAL_VPS_BIT
#define NI_NAL_VPS_BIT
Definition: ni_av_codec.h:39
_ni_frame::sei_hdr_mastering_display_color_vol_len
unsigned int sei_hdr_mastering_display_color_vol_len
Definition: ni_device_api.h:2662
NI_COL_PRI_UNSPECIFIED
@ NI_COL_PRI_UNSPECIFIED
Definition: ni_av_codec.h:99
_ni_frame::video_full_range_flag
int video_full_range_flag
Definition: ni_device_api.h:2711
_ni_dynamic_hdr_plus::targeted_system_display_actual_peak_luminance_flag
uint8_t targeted_system_display_actual_peak_luminance_flag
Definition: ni_av_codec.h:412
_ni_encoder_change_params_t::invalidFrameNum
int32_t invalidFrameNum
Definition: ni_device_api.h:1046
_ni_encoder_cfg_params::slice_mode
int slice_mode
Definition: ni_device_api.h:2371
_ni_session_context::codec_format
uint32_t codec_format
Definition: ni_device_api.h:1488
_ni_session_context::max_frame_size
int32_t max_frame_size
Definition: ni_device_api.h:1657
NI_MAX_NUM_OF_DECODER_OUTPUTS
#define NI_MAX_NUM_OF_DECODER_OUTPUTS
Definition: ni_defs.h:255
_ni_rc_min_max_qp::maxQpPB
int32_t maxQpPB
Definition: ni_device_api.h:712
_ni_session_context::itu_t_t35_hdr10p_sei_hdr_hevc
uint8_t itu_t_t35_hdr10p_sei_hdr_hevc[NI_HDR10P_SEI_HDR_HEVC_LEN]
Definition: ni_device_api.h:1421
slice_type_t
slice_type_t
Definition: ni_av_codec.c:43
ni_log2
void ni_log2(const void *p_context, ni_log_level_t level, const char *fmt,...)
print log message and additional information using ni_log_callback,
Definition: ni_log.c:337
ni_bs_writer_align_zero
void ni_bs_writer_align_zero(ni_bitstream_writer_t *stream)
align the bitstream with zero
Definition: ni_bitstream.c:276
NI_APP_ENC_FRAME_META_DATA_SIZE_UNDER_MAJOR_6_MINOR_rc
#define NI_APP_ENC_FRAME_META_DATA_SIZE_UNDER_MAJOR_6_MINOR_rc
Definition: ni_defs.h:323
_ni_encoder_cfg_params::crfFloat
float crfFloat
Definition: ni_device_api.h:2424
NI_CC_SEI_HDR_HEVC_LEN
#define NI_CC_SEI_HDR_HEVC_LEN
Definition: ni_device_api.h:463
ni_nvme.h
Private definitions for interfacing with NETINT video processing devices over NVMe.
_ni_timecode::seconds_value
uint8_t seconds_value
Definition: ni_av_codec.h:457
NI_SET_CHANGE_PARAM_INTRA_PERIOD
@ NI_SET_CHANGE_PARAM_INTRA_PERIOD
Definition: ni_device_api.h:977
_ni_hdr_plus_color_transform_params::semimajor_axis_external_ellipse
uint16_t semimajor_axis_external_ellipse
Definition: ni_av_codec.h:315
_ni_frame::sar_height
uint16_t sar_height
Definition: ni_device_api.h:2714
_ni_frame::sei_alt_transfer_characteristics_offset
unsigned int sei_alt_transfer_characteristics_offset
Definition: ni_device_api.h:2672
ni_extract_custom_sei
int ni_extract_custom_sei(uint8_t *pkt_data, int pkt_size, long index, ni_packet_t *p_packet, uint8_t sei_type, int vcl_found)
Extract custom sei payload data from pkt_data, and save it to ni_packet_t.
Definition: ni_av_codec.c:2943
_ni_decoder_input_params_t::enable_out2
int enable_out2
Definition: ni_device_api.h:2522
NI_FRAME_AUX_DATA_LTR_INTERVAL
@ NI_FRAME_AUX_DATA_LTR_INTERVAL
Definition: ni_device_api.h:555
NI_MAX_QP_INFO
#define NI_MAX_QP_INFO
Definition: ni_device_api.h:173
NI_INVALID_SVCT_DECODING_LAYER
#define NI_INVALID_SVCT_DECODING_LAYER
Definition: ni_device_api.h:319
_ni_encoder_change_params_t::ltrInterval
int32_t ltrInterval
Definition: ni_device_api.h:1049
_ni_session_context::reconfig_crf
int reconfig_crf
Definition: ni_device_api.h:1687
NI_SET_CHANGE_PARAM_LTR_INTERVAL
@ NI_SET_CHANGE_PARAM_LTR_INTERVAL
Definition: ni_device_api.h:972
_ni_encoder_change_params_t::minQpI
int32_t minQpI
Definition: ni_device_api.h:1000
ni_insert_emulation_prevent_bytes
int ni_insert_emulation_prevent_bytes(uint8_t *buf, int size)
Insert emulation prevention byte(s) as needed into the data buffer.
Definition: ni_util.c:2591
ni_get_hw_yuv420p_dim
void ni_get_hw_yuv420p_dim(int width, int height, int factor, int is_semiplanar, int plane_stride[NI_MAX_NUM_DATA_POINTERS], int plane_height[NI_MAX_NUM_DATA_POINTERS])
Get dimension information of Netint HW YUV420p frame to be sent to encoder for encoding....
Definition: ni_util.c:2040
_ni_frame::sei_user_data_unreg_offset
unsigned int sei_user_data_unreg_offset
Definition: ni_device_api.h:2669
_ni_timecode
Definition: ni_av_codec.h:448
_ni_frame::video_height
uint32_t video_height
Definition: ni_device_api.h:2637
_ni_vui_hrd::colorSpace
int32_t colorSpace
Definition: ni_device_api.h:670
_ni_hdr_plus_color_transform_params::knee_point_x
ni_rational_t knee_point_x
Definition: ni_av_codec.h:361
NI_NAL_PPS_BIT
#define NI_NAL_PPS_BIT
Definition: ni_av_codec.h:41
NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL
#define NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL
Max number of lines supported for qpoffset level.
Definition: ni_device_api.h:481
_ni_hdr_plus_color_transform_params::num_distribution_maxrgb_percentiles
uint8_t num_distribution_maxrgb_percentiles
Definition: ni_av_codec.h:343
_ni_decoder_input_params_t::custom_sei_passthru
int custom_sei_passthru
Definition: ni_device_api.h:2542
_ni_ppu_config::ppu_h
uint16_t ppu_h[NI_MAX_NUM_OF_DECODER_OUTPUTS]
Definition: ni_av_codec.h:476
_ni_session_context::active_video_height
uint32_t active_video_height
Definition: ni_device_api.h:1553
_ni_hdr_plus_color_transform_params::knee_point_y
ni_rational_t knee_point_y
Definition: ni_av_codec.h:366
_ni_dynamic_hdr_plus::num_cols_mastering_display_actual_peak_luminance
uint8_t num_cols_mastering_display_actual_peak_luminance
Definition: ni_av_codec.h:438
NI_FRAME_AUX_DATA_LONG_TERM_REF
@ NI_FRAME_AUX_DATA_LONG_TERM_REF
Definition: ni_device_api.h:550
NI_MAX_SEI_DATA
#define NI_MAX_SEI_DATA
Definition: ni_device_api.h:428
NI_COL_SPC_UNSPECIFIED
@ NI_COL_SPC_UNSPECIFIED
Definition: ni_av_codec.h:161
_ni_custom_sei
custom sei payload passthrough
Definition: ni_device_api.h:1119
NI_MAX_FRAME_SIZE
#define NI_MAX_FRAME_SIZE
Definition: ni_device_api.h:178
_ni_encoder_cfg_params::conf_win_right
int conf_win_right
Definition: ni_device_api.h:2314
ni_bitstream_reader_init
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
Definition: ni_bitstream.c:327
_ni_session_context::session_run_state
ni_session_run_state_t session_run_state
Definition: ni_device_api.h:1549
_ni_long_term_ref::use_cur_src_as_long_term_pic
uint8_t use_cur_src_as_long_term_pic
Definition: ni_device_api.h:689
_ni_timecode::counting_type
uint8_t counting_type
Definition: ni_av_codec.h:451
NI_CC_SEI_TRAILER_LEN
#define NI_CC_SEI_TRAILER_LEN
Definition: ni_device_api.h:467
ni_device_session_write
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...
Definition: ni_device_api.c:1668
_ni_enc_quad_roi_custom_map
encoder AVC ROI custom map (1 MB = 8bits)
Definition: ni_device_api.h:885
NI_SET_CHANGE_PARAM_RC_FRAMERATE
@ NI_SET_CHANGE_PARAM_RC_FRAMERATE
Definition: ni_device_api.h:973
_ni_xcoder_params::cacheRoi
int cacheRoi
Definition: ni_device_api.h:2777
_ni_encoder_change_params_t::maxQpI
int32_t maxQpI
Definition: ni_device_api.h:1001
_ni_region_of_interest::bottom
int bottom
Definition: ni_device_api.h:637
_ni_mastering_display_metadata::white_point
ni_rational_t white_point[2]
Definition: ni_av_codec.h:202
NI_FRAME_AUX_DATA_MASTERING_DISPLAY_METADATA
@ NI_FRAME_AUX_DATA_MASTERING_DISPLAY_METADATA
Definition: ni_device_api.h:507
NI_MIN_HEIGHT
#define NI_MIN_HEIGHT
Definition: ni_device_api.h:126
NI_RETCODE_FAILURE
@ NI_RETCODE_FAILURE
Definition: ni_defs.h:440
_ni_dynamic_hdr_plus::num_cols_targeted_system_display_actual_peak_luminance
uint8_t num_cols_targeted_system_display_actual_peak_luminance
Definition: ni_av_codec.h:421
_ni_encoder_change_params_t::vbvMaxRate
int32_t vbvMaxRate
Definition: ni_device_api.h:1035
NI_CUSTOM_SEI_LOC_BEFORE_VCL
@ NI_CUSTOM_SEI_LOC_BEFORE_VCL
Definition: ni_device_api.h:1112
GOP_PRESET_BBSP_3
@ GOP_PRESET_BBSP_3
Definition: ni_av_codec.c:70
_ni_encoder_cfg_params::planar
int planar
Definition: ni_device_api.h:2256
_ni_rational::den
int den
Definition: ni_device_api.h:603
_ni_frame::start_of_stream
uint32_t start_of_stream
Definition: ni_device_api.h:2635
_ni_encoder_change_params_t::colorTrc
uint8_t colorTrc
Definition: ni_device_api.h:1023
NI_SET_CHANGE_PARAM_RC_MIN_MAX_QP
@ NI_SET_CHANGE_PARAM_RC_MIN_MAX_QP
Definition: ni_device_api.h:959
_ni_vui_hrd::videoFullRange
int32_t videoFullRange
Definition: ni_device_api.h:681
_ni_vui_hrd::aspectRatioHeight
int32_t aspectRatioHeight
Definition: ni_device_api.h:677
NI_SET_CHANGE_PARAM_INVALID_REF_FRAME
@ NI_SET_CHANGE_PARAM_INVALID_REF_FRAME
Definition: ni_device_api.h:971
LIB_API
#define LIB_API
Definition: ni_libxcoder_dynamic_loading.h:52
NI_CUSTOM_SEI_LOC_AFTER_VCL
@ NI_CUSTOM_SEI_LOC_AFTER_VCL
Definition: ni_device_api.h:1113
_ni_session_context::last_framerate
ni_framerate_t last_framerate
Definition: ni_device_api.h:1677
_ni_session_context::ltr_frame_ref_invalid
int32_t ltr_frame_ref_invalid
Definition: ni_device_api.h:1605
_ni_hdr_plus_color_transform_params::window_upper_left_corner_x
ni_rational_t window_upper_left_corner_x
Definition: ni_av_codec.h:262
_ni_frame::pixel_format
int pixel_format
Definition: ni_device_api.h:2698
_ni_hdr_plus_color_transform_params::tone_mapping_flag
uint8_t tone_mapping_flag
Definition: ni_av_codec.h:356
_ni_encoder_change_params_t::sliceArg
int16_t sliceArg
Definition: ni_device_api.h:1033
ni_codec_format_t
enum _ni_codec_format ni_codec_format_t
This is an enumeration for supported codec formats.
ni_util.h
Utility definitions.
GOP_PRESET_CUSTOM
@ GOP_PRESET_CUSTOM
Definition: ni_av_codec.c:53
_ni_custom_sei_set::count
int count
Definition: ni_device_api.h:1130
_ni_frame::p_metadata_buffer
uint8_t * p_metadata_buffer
Definition: ni_device_api.h:2721
_ni_dynamic_hdr_plus::num_rows_mastering_display_actual_peak_luminance
uint8_t num_rows_mastering_display_actual_peak_luminance
Definition: ni_av_codec.h:434
_ni_rc_min_max_qp::maxQpI
int32_t maxQpI
Definition: ni_device_api.h:709
_ni_custom_sei_set::custom_sei
ni_custom_sei_t custom_sei[NI_MAX_CUSTOM_SEI_CNT]
Definition: ni_device_api.h:1129
_ni_encoder_cfg_params::lookAheadDepth
int lookAheadDepth
Definition: ni_device_api.h:2281
GOP_PRESET_I_1
@ GOP_PRESET_I_1
Definition: ni_av_codec.c:54
NIALIGN
#define NIALIGN(x, a)
Definition: ni_util.h:100
_ni_encoder_change_params_t::vbvBufferSize
int32_t vbvBufferSize
Definition: ni_device_api.h:996
_ni_hdr_plus_color_transform_params::semimajor_axis_internal_ellipse
uint16_t semimajor_axis_internal_ellipse
Definition: ni_av_codec.h:308
NI_FRAME_AUX_DATA_CRF_FLOAT
@ NI_FRAME_AUX_DATA_CRF_FLOAT
Definition: ni_device_api.h:580
_ni_frame::sei_alt_transfer_characteristics_len
unsigned int sei_alt_transfer_characteristics_len
Definition: ni_device_api.h:2673
NI_FRAME_AUX_DATA_CONTENT_LIGHT_LEVEL
@ NI_FRAME_AUX_DATA_CONTENT_LIGHT_LEVEL
Definition: ni_device_api.h:511
_ni_xcoder_params::low_delay_mode
int low_delay_mode
Definition: ni_device_api.h:2763
ni_bs_reader_skip_bits
void ni_bs_reader_skip_bits(ni_bitstream_reader_t *br, int n)
skip a number of bits ahead in the bitstream reader
Definition: ni_bitstream.c:371
_ni_bitstream_reader_t
Definition: ni_bitstream.h:119
NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_H264
Definition: ni_device_api.h:913
_ni_frame::use_cur_src_as_long_term_pic
uint8_t use_cur_src_as_long_term_pic
Definition: ni_device_api.h:2647
GOP_PRESET_SP_1
@ GOP_PRESET_SP_1
Definition: ni_av_codec.c:63
NI_FRAME_AUX_DATA_INVALID_REF_FRAME
@ NI_FRAME_AUX_DATA_INVALID_REF_FRAME
Definition: ni_device_api.h:560
_ni_frame::video_width
uint32_t video_width
Definition: ni_device_api.h:2636
ni_should_send_sei_with_frame
int ni_should_send_sei_with_frame(ni_session_context_t *p_enc_ctx, ni_pic_type_t pic_type, ni_xcoder_params_t *p_param)
Whether SEI (HDR) should be sent together with this frame to encoder.
Definition: ni_av_codec.c:186
_ni_hdr_plus_color_transform_params::num_bezier_curve_anchors
uint8_t num_bezier_curve_anchors
Definition: ni_av_codec.h:370
_ni_xcoder_params::bitrate
int bitrate
Definition: ni_device_api.h:2759
NI_INTRA_QP_RANGE
#define NI_INTRA_QP_RANGE
Definition: ni_device_api.h:170
_ni_session_context::sei_hdr_content_light_level_info_len
int sei_hdr_content_light_level_info_len
Definition: ni_device_api.h:1428
_ni_hdr_plus_color_transform_params::average_maxrgb
ni_rational_t average_maxrgb
Definition: ni_av_codec.h:339
_ni_encoder_cfg_params::preferred_transfer_characteristics
int preferred_transfer_characteristics
Definition: ni_device_api.h:2279
_ni_session_context::pixel_format
int pixel_format
Definition: ni_device_api.h:1618
_ni_hdr_plus_color_transform_params::overlap_process_option
ni_hdr_plus_overlap_process_option_t overlap_process_option
Definition: ni_av_codec.h:327
_ni_session_context::sei_trailer
uint8_t sei_trailer[NI_CC_SEI_TRAILER_LEN]
Definition: ni_device_api.h:1424
_ni_aux_data
Definition: ni_device_api.h:620
NI_LOG_DEBUG
@ NI_LOG_DEBUG
Definition: ni_log.h:62
_ni_framerate
Definition: ni_device_api.h:697
_ni_vui_hrd::aspectRatioWidth
int32_t aspectRatioWidth
Definition: ni_device_api.h:674
_ni_mastering_display_metadata::display_primaries
ni_rational_t display_primaries[3][2]
Definition: ni_av_codec.h:199
_ni_encoder_change_params_t::aspectRatioWidth
uint16_t aspectRatioWidth
Definition: ni_device_api.h:1025
GOP_PRESET_LD_4
@ GOP_PRESET_LD_4
Definition: ni_av_codec.c:60
NI_FRAME_AUX_DATA_INTRAPRD
@ NI_FRAME_AUX_DATA_INTRAPRD
Definition: ni_device_api.h:541
_ni_dynamic_hdr_plus::num_rows_targeted_system_display_actual_peak_luminance
uint8_t num_rows_targeted_system_display_actual_peak_luminance
Definition: ni_av_codec.h:416
_ni_xcoder_params::dec_input_params
ni_decoder_input_params_t dec_input_params
Definition: ni_device_api.h:2796
_ni_enc_quad_roi_custom_map::qp_info
uint8_t qp_info
Definition: ni_device_api.h:891
_ni_hdr_plus_color_transform_params::bezier_curve_anchors
ni_rational_t bezier_curve_anchors[15]
Definition: ni_av_codec.h:375
_ni_rc_min_max_qp::maxDeltaQp
int32_t maxDeltaQp
Definition: ni_device_api.h:710
_ni_session_context::roi_avg_qp
uint32_t roi_avg_qp
Definition: ni_device_api.h:1499
NI_MAX_ASPECTRATIO
#define NI_MAX_ASPECTRATIO
Definition: ni_device_api.h:117
_ni_hdr_plus_color_transform_params::semiminor_axis_external_ellipse
uint16_t semiminor_axis_external_ellipse
Definition: ni_av_codec.h:321
_ni_dynamic_hdr_plus::application_version
uint8_t application_version
Definition: ni_av_codec.h:396
_ni_session_context::p_master_display_meta_data
void * p_master_display_meta_data
Definition: ni_device_api.h:1434
_ni_encoder_cfg_params::forced_header_enable
int forced_header_enable
Definition: ni_device_api.h:2272
NI_FRAME_AUX_DATA_BITRATE
@ NI_FRAME_AUX_DATA_BITRATE
Definition: ni_device_api.h:537
_ni_encoder_change_params_t::videoFullRange
uint8_t videoFullRange
Definition: ni_device_api.h:1027
NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_H265
Definition: ni_device_api.h:914
_ni_frame::use_long_term_ref
uint8_t use_long_term_ref
Definition: ni_device_api.h:2648