libxcoder  5.2.0
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 =
828  (sumQp + (numMbs >> 1)) / numMbs + NI_DEFAULT_INTRA_QP; // round off
829 
830  return 0;
831 }
832 
833 /*!*****************************************************************************
834  * \brief Prepare auxiliary data that should be sent together with this frame
835  * to encoder based on the auxiliary data of the decoded frame.
836  *
837  * Note: Some of the SEI (e.g. HDR) will be updated and stored in encoder
838  * context whenever received through decoded frame; they will be sent
839  * out with the encoded frame to encoder only when appropriate, i.e.
840  * should_send_sei_with_frame is true. When a type of aux data is to be
841  * sent, its associated length will be set in the encoder frame.
842  *
843  * \param[in/out] p_enc_ctx encoder session contextwhose various SEI type
844  * header can be updated as the result of this function
845  * \param[out] p_enc_frame frame to be sent to encoder
846  * \param[in] p_dec_frame frame that is returned by decoder
847  * \param[in] codec_format H.264 or H.265
848  * \param[in] should_send_sei_with_frame if need to send a certain type of
849  * SEI with this frame
850  * \param[out] mdcv_data SEI for HDR mastering display color volume info
851  * \param[out] cll_data SEI for HDR content light level info
852  * \param[out] cc_data SEI for close caption
853  * \param[out] udu_data SEI for User data unregistered
854  * \param[out] hdrp_data SEI for HDR10+
855  *
856  * \return NONE
857  ******************************************************************************/
859  ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame,
860  ni_codec_format_t codec_format,
861  int should_send_sei_with_frame, uint8_t *mdcv_data,
862  uint8_t *cll_data, uint8_t *cc_data,
863  uint8_t *udu_data, uint8_t *hdrp_data)
864 {
865  uint8_t *dst = NULL;
866  ni_aux_data_t *aux_data = NULL;
867  ni_xcoder_params_t *api_params =
868  (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
869 
870  // reset all auxiliary data flag and length of encode frame
872  p_enc_frame->use_cur_src_as_long_term_pic =
873  p_enc_frame->use_long_term_ref = 0;
874 
875  p_enc_frame->sei_total_len = p_enc_frame->sei_cc_offset =
876  p_enc_frame->sei_cc_len =
881  p_enc_frame->sei_user_data_unreg_offset =
882  p_enc_frame->sei_user_data_unreg_len =
883  p_enc_frame->sei_hdr_plus_offset =
884  p_enc_frame->sei_hdr_plus_len = 0;
885 
886  // prep for NetInt intra period reconfiguration support: when intra period
887  // setting has been requested by both frame and API, API takes priority
888  int intraprd = -1;
889  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_INTRAPRD);
890  if (aux_data)
891  {
892  intraprd = *((int32_t *)aux_data->data);
893  if (intraprd < 0 || intraprd > 1024)
894  {
895  ni_log(NI_LOG_ERROR, "ERROR: %s(): invalid intraperiod in aux data %d\n",
896  __func__, intraprd);
897  intraprd = -1;
898  }
899  }
900 
901  if (p_enc_ctx->reconfig_intra_period >= 0)
902  {
903  intraprd = p_enc_ctx->reconfig_intra_period;
904  p_enc_ctx->reconfig_intra_period = -1;
905  ni_log(NI_LOG_DEBUG, "%s(): API set intraPeriod %d\n", __func__,
906  intraprd);
907  }
908 
909  if (intraprd >= 0)
910  {
911  if (api_params->cfg_enc_params.intra_mb_refresh_mode ||
912  api_params->cfg_enc_params.gop_preset_index == 1)
913  {
914  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",
915  __func__,
916  intraprd,
918  api_params->cfg_enc_params.gop_preset_index);
919  }
920  else
921  {
922  // 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)
923  should_send_sei_with_frame = 1;
924  api_params->cfg_enc_params.intra_period = intraprd;
925 
926  if (intraprd)
927  {
928  p_enc_ctx->force_idr_intra_offset =
929  intraprd - (p_enc_ctx->frame_num % intraprd);
930  }
931  else
932  {
933  p_enc_ctx->force_idr_intra_offset = 0;
934  }
935 
936  p_enc_ctx->enc_change_params->enable_option |=
938  p_enc_ctx->enc_change_params->intraPeriod = intraprd;
939  ni_log(NI_LOG_INFO, "%s(): set intraPeriod %d on frame %u, update intra offset %u\n", __func__,
940  intraprd, p_enc_ctx->frame_num, p_enc_ctx->force_idr_intra_offset);
941  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
942  }
943  }
944 
945  // prep SEI for HDR (mastering display color volume)
946  aux_data = ni_frame_get_aux_data(
948  if (aux_data)
949  {
950  p_enc_ctx->mdcv_max_min_lum_data_len = 8;
952  8 + 6 * 2 + 2 * 2 + 2 * 4 + 1;
953  if (NI_CODEC_FORMAT_H264 == codec_format)
954  {
956  }
957 
960 
961  // save a copy
962  if (!p_enc_ctx->p_master_display_meta_data)
963  {
964  p_enc_ctx->p_master_display_meta_data = malloc(sizeof(ni_mastering_display_metadata_t));
965  }
966  if (!p_enc_ctx->p_master_display_meta_data)
967  {
968  ni_log2(p_enc_ctx, NI_LOG_ERROR, "Error mem alloc for mastering display color vol\n");
969  } else
970  {
971  memcpy(p_enc_ctx->p_master_display_meta_data, p_src,
973 
974  const int luma_den = MASTERING_DISP_LUMA_DEN;
975 
976  uint32_t uint32_t_tmp = htonl(
977  (uint32_t)(lrint(luma_den * ni_q2d(p_src->max_luminance))));
978  memcpy(p_enc_ctx->ui8_mdcv_max_min_lum_data, &uint32_t_tmp,
979  sizeof(uint32_t));
980  uint32_t_tmp = htonl(
981  (uint32_t)(lrint(luma_den * ni_q2d(p_src->min_luminance))));
982  memcpy(p_enc_ctx->ui8_mdcv_max_min_lum_data + 4, &uint32_t_tmp,
983  sizeof(uint32_t));
984 
985  // emulation prevention checking of luminance data
986  int emu_bytes_inserted = ni_insert_emulation_prevent_bytes(
987  p_enc_ctx->ui8_mdcv_max_min_lum_data, 2 * 4);
988 
989  p_enc_ctx->mdcv_max_min_lum_data_len += emu_bytes_inserted;
991  emu_bytes_inserted;
992  }
993  }
994 
996  p_enc_ctx->p_master_display_meta_data && should_send_sei_with_frame)
997  {
998  dst = mdcv_data;
999  dst[0] = dst[1] = dst[2] = 0;
1000  dst[3] = 1;
1001 
1002  if (NI_CODEC_FORMAT_H264 == codec_format)
1003  {
1004  dst[4] = 0x6;
1005  dst[5] = 0x89; // payload type=137
1006  dst[6] = 0x18; // payload size=24
1007  dst += 7;
1008  } else
1009  {
1010  dst[4] = 0x4e;
1011  dst[5] = 1;
1012  dst[6] = 0x89; // payload type=137
1013  dst[7] = 0x18; // payload size=24
1014  dst += 8;
1015  }
1016 
1021  p_enc_ctx->p_master_display_meta_data;
1022 
1023  const int chroma_den = MASTERING_DISP_CHROMA_DEN;
1024  const int luma_den = MASTERING_DISP_LUMA_DEN;
1025 
1026  uint16_t dp00 = 0, dp01 = 0, dp10 = 0, dp11 = 0, dp20 = 0, dp21 = 0,
1027  wpx = 0, wpy = 0;
1028  // assuming p_src->has_primaries is always true
1029  // this is stored in r,g,b order and needs to be in g.b,r order
1030  // when sent to encoder
1031  dp00 = (uint16_t)lrint(chroma_den *
1032  ni_q2d(p_src->display_primaries[1][0]));
1033  p_mdcv->display_primaries[0][0] = htons(dp00);
1034  dp01 = (uint16_t)lrint(chroma_den *
1035  ni_q2d(p_src->display_primaries[1][1]));
1036  p_mdcv->display_primaries[0][1] = htons(dp01);
1037  dp10 = (uint16_t)lrint(chroma_den *
1038  ni_q2d(p_src->display_primaries[2][0]));
1039  p_mdcv->display_primaries[1][0] = htons(dp10);
1040  dp11 = (uint16_t)lrint(chroma_den *
1041  ni_q2d(p_src->display_primaries[2][1]));
1042  p_mdcv->display_primaries[1][1] = htons(dp11);
1043  dp20 = (uint16_t)lrint(chroma_den *
1044  ni_q2d(p_src->display_primaries[0][0]));
1045  p_mdcv->display_primaries[2][0] = htons(dp20);
1046  dp21 = (uint16_t)lrint(chroma_den *
1047  ni_q2d(p_src->display_primaries[0][1]));
1048  p_mdcv->display_primaries[2][1] = htons(dp21);
1049 
1050  wpx = (uint16_t)lrint(chroma_den * ni_q2d(p_src->white_point[0]));
1051  p_mdcv->white_point_x = htons(wpx);
1052  wpy = (uint16_t)lrint(chroma_den * ni_q2d(p_src->white_point[1]));
1053  p_mdcv->white_point_y = htons(wpy);
1054 
1055  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1056  "mastering display color volume, primaries "
1057  "%u/%u/%u/%u/%u/%u white_point_x/y %u/%u max/min_lumi %u/%u\n",
1058  (uint16_t)dp00, (uint16_t)dp01, (uint16_t)dp10, (uint16_t)dp11,
1059  (uint16_t)dp20, (uint16_t)dp21, (uint16_t)wpx, (uint16_t)wpy,
1060  (uint32_t)(luma_den * ni_q2d(p_src->max_luminance)),
1061  (uint32_t)(luma_den * ni_q2d(p_src->min_luminance)));
1062 
1063  dst += 6 * 2 + 2 * 2;
1064  memcpy(dst, p_enc_ctx->ui8_mdcv_max_min_lum_data,
1065  p_enc_ctx->mdcv_max_min_lum_data_len);
1066 
1067  dst += p_enc_ctx->mdcv_max_min_lum_data_len;
1068  *dst = 0x80;
1069 
1072 
1073  p_enc_frame->sei_total_len +=
1075  }
1076 
1077  // prep SEI for HDR (content light level info)
1078  aux_data = ni_frame_get_aux_data(p_dec_frame,
1080  if (aux_data)
1081  {
1082  // size of: start code + NAL unit header + payload type byte +
1083  // payload size byte + payload + rbsp trailing bits, default HEVC
1084  p_enc_ctx->light_level_data_len = 4;
1085  p_enc_ctx->sei_hdr_content_light_level_info_len = 8 + 2 * 2 + 1;
1086  if (NI_CODEC_FORMAT_H264 == codec_format)
1087  {
1089  }
1090 
1091  uint16_t max_content_light_level =
1092  htons(((ni_content_light_level_t *)aux_data->data)->max_cll);
1093  uint16_t max_pic_average_light_level =
1094  htons(((ni_content_light_level_t *)aux_data->data)->max_fall);
1095 
1096  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "content light level info, MaxCLL %u MaxFALL %u\n",
1097  ((ni_content_light_level_t *)aux_data->data)->max_cll,
1098  ((ni_content_light_level_t *)aux_data->data)->max_fall);
1099 
1100  memcpy(p_enc_ctx->ui8_light_level_data, &max_content_light_level,
1101  sizeof(uint16_t));
1102  memcpy(&(p_enc_ctx->ui8_light_level_data[2]),
1103  &max_pic_average_light_level, sizeof(uint16_t));
1104 
1105  // emulation prevention checking
1106  int emu_bytes_inserted = ni_insert_emulation_prevent_bytes(
1107  p_enc_ctx->ui8_light_level_data, p_enc_ctx->light_level_data_len);
1108 
1109  p_enc_ctx->light_level_data_len += emu_bytes_inserted;
1110  p_enc_ctx->sei_hdr_content_light_level_info_len += emu_bytes_inserted;
1111  }
1112 
1113  if (p_enc_ctx->sei_hdr_content_light_level_info_len &&
1114  should_send_sei_with_frame)
1115  {
1116  dst = cll_data;
1117  dst[0] = dst[1] = dst[2] = 0;
1118  dst[3] = 1;
1119 
1120  if (NI_CODEC_FORMAT_H264 == codec_format)
1121  {
1122  dst[4] = 0x6;
1123  dst[5] = 0x90; // payload type=144
1124  dst[6] = 4; // payload size=4
1125  dst += 7;
1126  } else
1127  {
1128  dst[4] = 0x4e;
1129  dst[5] = 1;
1130  dst[6] = 0x90; // payload type=144
1131  dst[7] = 4; // payload size=4
1132  dst += 8;
1133  }
1134 
1135  memcpy(dst, p_enc_ctx->ui8_light_level_data,
1136  p_enc_ctx->light_level_data_len);
1137  dst += p_enc_ctx->light_level_data_len;
1138  *dst = 0x80;
1139 
1142 
1143  p_enc_frame->sei_total_len +=
1145  }
1146 
1147  // prep SEI for close caption
1148  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_A53_CC);
1149  if (aux_data)
1150  {
1151  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data sei_cc_len %d\n", aux_data->size);
1152 
1153  uint8_t cc_data_emu_prevent[NI_MAX_SEI_DATA];
1154  int cc_size = aux_data->size;
1155  if (cc_size > NI_MAX_SEI_DATA)
1156  {
1157  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data sei_cc_len %d > MAX %d !\n",
1158  aux_data->size, (int)NI_MAX_SEI_DATA);
1159  cc_size = NI_MAX_SEI_DATA;
1160  }
1161  memcpy(cc_data_emu_prevent, aux_data->data, cc_size);
1162  int cc_size_emu_prevent = cc_size +
1163  ni_insert_emulation_prevent_bytes(cc_data_emu_prevent, cc_size);
1164  if (cc_size_emu_prevent != cc_size)
1165  {
1166  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data: close caption "
1167  "emulation prevention bytes added: %d\n",
1168  cc_size_emu_prevent - cc_size);
1169  }
1170 
1171  dst = cc_data;
1172  // set header info fields and extra size based on codec
1173  if (NI_CODEC_FORMAT_H265 == codec_format)
1174  {
1175  p_enc_frame->sei_cc_len = NI_CC_SEI_HDR_HEVC_LEN +
1176  cc_size_emu_prevent + NI_CC_SEI_TRAILER_LEN;
1177  p_enc_frame->sei_total_len += p_enc_frame->sei_cc_len;
1178 
1179  p_enc_ctx->itu_t_t35_cc_sei_hdr_hevc[7] = cc_size + 11;
1180  p_enc_ctx->itu_t_t35_cc_sei_hdr_hevc[16] = (cc_size / 3) | 0xc0;
1181 
1182  memcpy(dst, p_enc_ctx->itu_t_t35_cc_sei_hdr_hevc,
1184  dst += NI_CC_SEI_HDR_HEVC_LEN;
1185  memcpy(dst, cc_data_emu_prevent, cc_size_emu_prevent);
1186  dst += cc_size_emu_prevent;
1187  memcpy(dst, p_enc_ctx->sei_trailer, NI_CC_SEI_TRAILER_LEN);
1188  } else // H.264
1189  {
1190  p_enc_frame->sei_cc_len = NI_CC_SEI_HDR_H264_LEN +
1191  cc_size_emu_prevent + NI_CC_SEI_TRAILER_LEN;
1192  p_enc_frame->sei_total_len += p_enc_frame->sei_cc_len;
1193 
1194  p_enc_ctx->itu_t_t35_cc_sei_hdr_h264[6] = cc_size + 11;
1195  p_enc_ctx->itu_t_t35_cc_sei_hdr_h264[15] = (cc_size / 3) | 0xc0;
1196 
1197  memcpy(dst, p_enc_ctx->itu_t_t35_cc_sei_hdr_h264,
1199  dst += NI_CC_SEI_HDR_H264_LEN;
1200  memcpy(dst, cc_data_emu_prevent, cc_size_emu_prevent);
1201  dst += cc_size_emu_prevent;
1202  memcpy(dst, p_enc_ctx->sei_trailer, NI_CC_SEI_TRAILER_LEN);
1203  }
1204  }
1205 
1206  // prep SEI for HDR+
1207  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_HDR_PLUS);
1208  if (aux_data)
1209  {
1210  ni_dynamic_hdr_plus_t *hdrp = (ni_dynamic_hdr_plus_t *)aux_data->data;
1211  int w, i, j;
1213  uint32_t ui_tmp;
1214 
1216 
1217  // HDR10+ SEI header bytes
1218 
1219  // itu_t_t35_provider_code and itu_t_t35_provider_oriented_code are
1220  // contained in the first 4 bytes of payload; pb has all the data until
1221  // start of trailer
1222  ni_bs_writer_put(&pb, 0, 8);
1223  ni_bs_writer_put(&pb, 0x3c,
1224  8); // u16 itu_t_t35_provider_code = 0x003c
1225  ni_bs_writer_put(&pb, 0, 8);
1226  // u16 itu_t_t35_provider_oriented_code = 0x0001
1227  ni_bs_writer_put(&pb, 0x01, 8);
1228  ni_bs_writer_put(&pb, 4, 8); // u8 application_identifier = 0x04
1229  ni_bs_writer_put(&pb, hdrp->application_version, 8);
1230  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ application_version %u\n", hdrp->application_version);
1231 
1232  ni_bs_writer_put(&pb, hdrp->num_windows, 2);
1233  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ num_windows %u\n", hdrp->num_windows);
1234  for (w = 1; w < hdrp->num_windows; w++)
1235  {
1237  &pb, hdrp->params[w - 1].window_upper_left_corner_x.num, 16);
1239  &pb, hdrp->params[w - 1].window_upper_left_corner_y.num, 16);
1241  &pb, hdrp->params[w - 1].window_lower_right_corner_x.num, 16);
1243  &pb, hdrp->params[w - 1].window_lower_right_corner_y.num, 16);
1244  ni_bs_writer_put(&pb, hdrp->params[w - 1].center_of_ellipse_x, 16);
1245  ni_bs_writer_put(&pb, hdrp->params[w - 1].center_of_ellipse_y, 16);
1246  ni_bs_writer_put(&pb, hdrp->params[w - 1].rotation_angle, 8);
1248  &pb, hdrp->params[w - 1].semimajor_axis_internal_ellipse, 16);
1250  &pb, hdrp->params[w - 1].semimajor_axis_external_ellipse, 16);
1252  &pb, hdrp->params[w - 1].semiminor_axis_external_ellipse, 16);
1254  1);
1255  }
1256 
1257  // values are scaled up according to standard spec
1258  ui_tmp = lrint(10000 *
1260  ni_bs_writer_put(&pb, ui_tmp, 27);
1263  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ targeted_system_display_maximum_luminance "
1264  "%u\n",
1265  ui_tmp);
1266  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1267  "hdr10+ targeted_system_display_actual_peak_luminance_"
1268  "flag %u\n",
1270 
1272  {
1274  &pb,
1276  5);
1278  &pb,
1280  5);
1281  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1282  "hdr10+ num_rows_targeted_system_display_actual_peak_luminance "
1283  "x num_cols_targeted_system_display_actual_peak_luminance %u x "
1284  "%u\n",
1287 
1288  for (i = 0; i <
1290  i++)
1291  for (
1292  j = 0; j <
1294  j++)
1295  {
1296  ui_tmp = lrint(
1297  15 *
1298  ni_q2d(
1300  [i][j]));
1301  ni_bs_writer_put(&pb, ui_tmp, 4);
1302  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ targeted_system_display_actual_peak_"
1303  "luminance[%d][%d] %u\n",
1304  i, j, ui_tmp);
1305  }
1306  }
1307 
1308  for (w = 0; w < hdrp->num_windows; w++)
1309  {
1310  for (i = 0; i < 3; i++)
1311  {
1312  ui_tmp = lrint(100000 * ni_q2d(hdrp->params[w].maxscl[i]));
1313  ni_bs_writer_put(&pb, ui_tmp, 17);
1314  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ maxscl[%d][%d] %u\n", w, i, ui_tmp);
1315  }
1316  ui_tmp = lrint(100000 * ni_q2d(hdrp->params[w].average_maxrgb));
1317  ni_bs_writer_put(&pb, ui_tmp, 17);
1318  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ average_maxrgb[%d] %u\n", w, ui_tmp);
1319 
1321  &pb, hdrp->params[w].num_distribution_maxrgb_percentiles, 4);
1322  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1323  "hdr10+ num_distribution_maxrgb_percentiles[%d] %d\n", w,
1325 
1326  for (i = 0; i < hdrp->params[w].num_distribution_maxrgb_percentiles;
1327  i++)
1328  {
1330  &pb, hdrp->params[w].distribution_maxrgb[i].percentage, 7);
1331  ui_tmp = lrint(
1332  100000 *
1333  ni_q2d(hdrp->params[w].distribution_maxrgb[i].percentile));
1334  ni_bs_writer_put(&pb, ui_tmp, 17);
1335  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1336  "hdr10+ distribution_maxrgb_percentage[%d][%d] %u\n", w, i,
1337  hdrp->params[w].distribution_maxrgb[i].percentage);
1338  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1339  "hdr10+ distribution_maxrgb_percentile[%d][%d] %u\n", w, i,
1340  ui_tmp);
1341  }
1342 
1343  ui_tmp =
1344  lrint(1000 * ni_q2d(hdrp->params[w].fraction_bright_pixels));
1345  ni_bs_writer_put(&pb, ui_tmp, 10);
1346  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ fraction_bright_pixels[%d] %u\n", w, ui_tmp);
1347  }
1348 
1349  ni_bs_writer_put(&pb,
1351  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1352  "hdr10+ mastering_display_actual_peak_luminance_flag %u\n",
1355  {
1360  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1361  "hdr10+ num_rows_mastering_display_actual_peak_luminance x "
1362  "num_cols_mastering_display_actual_peak_luminance %u x %u\n",
1365 
1366  for (i = 0;
1368  i++)
1369  for (j = 0;
1371  j++)
1372  {
1373  ui_tmp = lrint(
1374  15 *
1375  ni_q2d(
1377  [j]));
1378  ni_bs_writer_put(&pb, ui_tmp, 4);
1379  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1380  "hdr10+ "
1381  "mastering_display_actual_peak_luminance[%d][%d] %u\n",
1382  i, j, ui_tmp);
1383  }
1384  }
1385 
1386  for (w = 0; w < hdrp->num_windows; w++)
1387  {
1388  ni_bs_writer_put(&pb, hdrp->params[w].tone_mapping_flag, 1);
1389  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ tone_mapping_flag[%d] %u\n", w,
1390  hdrp->params[w].tone_mapping_flag);
1391 
1392  if (hdrp->params[w].tone_mapping_flag)
1393  {
1394  ui_tmp = lrint(4095 * ni_q2d(hdrp->params[w].knee_point_x));
1395  ni_bs_writer_put(&pb, ui_tmp, 12);
1396  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ knee_point_x[%d] %u\n", w, ui_tmp);
1397 
1398  ui_tmp = lrint(4095 * ni_q2d(hdrp->params[w].knee_point_y));
1399  ni_bs_writer_put(&pb, ui_tmp, 12);
1400  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ knee_point_y[%d] %u\n", w, ui_tmp);
1401 
1403  4);
1404  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ num_bezier_curve_anchors[%d] %u\n", w,
1405  hdrp->params[w].num_bezier_curve_anchors);
1406  for (i = 0; i < hdrp->params[w].num_bezier_curve_anchors; i++)
1407  {
1408  ui_tmp = lrint(
1409  1023 * ni_q2d(hdrp->params[w].bezier_curve_anchors[i]));
1410  ni_bs_writer_put(&pb, ui_tmp, 10);
1411  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ bezier_curve_anchors[%d][%d] %u\n",
1412  w, i, ui_tmp);
1413  }
1414  }
1415 
1417  1);
1418  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ color_saturation_mapping_flag[%d] %u\n", w,
1421  {
1422  ui_tmp =
1423  lrint(8 * ni_q2d(hdrp->params[w].color_saturation_weight));
1424  ni_bs_writer_put(&pb, 6, ui_tmp);
1425  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ color_saturation_weight[%d] %u\n", w,
1426  ui_tmp);
1427  }
1428  } // num_windows
1429 
1430  uint64_t hdr10p_num_bytes = (ni_bs_writer_tell(&pb) + 7) / 8;
1431  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "hdr10+ total bits: %d -> bytes %" PRIu64 "\n",
1432  (int)ni_bs_writer_tell(&pb), hdr10p_num_bytes);
1434 
1435  dst = hdrp_data;
1436 
1437  // emulation prevention checking of payload
1438  int emu_bytes_inserted;
1439 
1440  // set header info fields and extra size based on codec
1441  if (NI_CODEC_FORMAT_H265 == codec_format)
1442  {
1443  p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_hevc[7] =
1444  (uint8_t)hdr10p_num_bytes + NI_RBSP_TRAILING_BITS_LEN;
1445 
1446  memcpy(dst, p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_hevc,
1449  ni_bs_writer_copy(dst, &pb);
1450 
1451  emu_bytes_inserted =
1452  ni_insert_emulation_prevent_bytes(dst, (int)hdr10p_num_bytes);
1453  dst += hdr10p_num_bytes + emu_bytes_inserted;
1454  *dst = p_enc_ctx->sei_trailer[1];
1455  //dst += NI_RBSP_TRAILING_BITS_LEN;
1456 
1458  (uint32_t)hdr10p_num_bytes + emu_bytes_inserted +
1460  p_enc_frame->sei_total_len += p_enc_frame->sei_hdr_plus_len;
1461  } else if (NI_CODEC_FORMAT_H264 == codec_format)
1462  {
1463  p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_h264[6] =
1464  (uint8_t)hdr10p_num_bytes + NI_RBSP_TRAILING_BITS_LEN;
1465 
1466  memcpy(dst, p_enc_ctx->itu_t_t35_hdr10p_sei_hdr_h264,
1469  ni_bs_writer_copy(dst, &pb);
1470 
1471  emu_bytes_inserted =
1472  ni_insert_emulation_prevent_bytes(dst, (int)hdr10p_num_bytes);
1473  dst += hdr10p_num_bytes + emu_bytes_inserted;
1474  *dst = p_enc_ctx->sei_trailer[1];
1475  //dst += NI_RBSP_TRAILING_BITS_LEN;
1476 
1478  (uint8_t)hdr10p_num_bytes + emu_bytes_inserted +
1480  p_enc_frame->sei_total_len += p_enc_frame->sei_hdr_plus_len;
1481  } else
1482  {
1483  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1484  "ni_enc_prep_aux_data: codec %d not supported for HDR10+ "
1485  "SEI !\n",
1486  codec_format);
1487  p_enc_frame->sei_hdr_plus_len = 0;
1488  }
1489 
1490  ni_bs_writer_clear(&pb);
1491  } // hdr10+
1492 
1493  // prep SEI for User Data Unregistered
1494  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_UDU_SEI);
1495  if (aux_data)
1496  {
1497  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data sei_user_data_unreg_len %d\n",
1498  aux_data->size);
1499 
1500  // emulation prevention checking: a working buffer of size in worst case
1501  // that each two bytes comes with 1B emulation prevention byte
1502  int udu_sei_size = aux_data->size;
1503  int ext_udu_sei_size, sei_len;
1504 
1505  uint8_t *sei_data = malloc(udu_sei_size * 3 / 2);
1506  if (sei_data)
1507  {
1508  memcpy(sei_data, (uint8_t *)aux_data->data, udu_sei_size);
1509  int emu_bytes_inserted =
1510  ni_insert_emulation_prevent_bytes(sei_data, udu_sei_size);
1511 
1512  ext_udu_sei_size = udu_sei_size + emu_bytes_inserted;
1513 
1514  if (NI_CODEC_FORMAT_H264 == codec_format)
1515  {
1516  /* 4B long start code + 1B nal header + 1B SEI type + Bytes of
1517  payload length + Bytes of SEI payload + 1B trailing */
1518  sei_len =
1519  6 + ((udu_sei_size + 0xFE) / 0xFF) + ext_udu_sei_size + 1;
1520  } else
1521  {
1522  /* 4B long start code + 2B nal header + 1B SEI type + Bytes of
1523  payload length + Bytes of SEI payload + 1B trailing */
1524  sei_len =
1525  7 + ((udu_sei_size + 0xFE) / 0xFF) + ext_udu_sei_size + 1;
1526  }
1527 
1528  // discard this UDU SEI if the total SEI size exceeds the max size
1529  if (p_enc_frame->sei_total_len + sei_len > NI_ENC_MAX_SEI_BUF_SIZE)
1530  {
1531  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1532  "ni_enc_prep_aux_data sei total length %u + sei_len %d "
1533  "exceeds maximum sei size %u, discarding it !\n",
1534  p_enc_frame->sei_total_len, sei_len,
1536  } else
1537  {
1538  int payload_size = udu_sei_size;
1539 
1540  dst = udu_data;
1541  *dst++ = 0x00; // long start code
1542  *dst++ = 0x00;
1543  *dst++ = 0x00;
1544  *dst++ = 0x01;
1545 
1546  if (NI_CODEC_FORMAT_H264 == codec_format)
1547  {
1548  *dst++ = 0x06; // nal type: SEI
1549  } else
1550  {
1551  *dst++ = 0x4e; // nal type: SEI
1552  *dst++ = 0x01;
1553  }
1554  *dst++ = 0x05; // SEI type: user data unregistered
1555 
1556  // original payload size
1557  while (payload_size > 0)
1558  {
1559  *dst++ =
1560  (payload_size > 0xFF ? 0xFF : (uint8_t)payload_size);
1561  payload_size -= 0xFF;
1562  }
1563 
1564  // payload data after emulation prevention checking
1565  memcpy(dst, sei_data, ext_udu_sei_size);
1566  dst += ext_udu_sei_size;
1567 
1568  // trailing byte
1569  *dst = 0x80;
1570  dst++;
1571 
1572  // save UDU data length
1573  p_enc_frame->sei_user_data_unreg_len = sei_len;
1574  p_enc_frame->sei_total_len += sei_len;
1575  }
1576 
1577  free(sei_data);
1578  sei_data = NULL;
1579  }
1580  }
1581 
1582  // supply QP map if ROI enabled and if ROIs passed in as aux data
1583  aux_data = ni_frame_get_aux_data(p_dec_frame,
1585  if (api_params->cfg_enc_params.roi_enable && aux_data)
1586  {
1587  int is_new_rois = 1;
1588  const ni_region_of_interest_t *roi = NULL;
1589  uint32_t self_size = 0;
1590 
1591  roi = (const ni_region_of_interest_t *)aux_data->data;
1592  self_size = roi->self_size;
1593  if (!self_size || aux_data->size % self_size)
1594  {
1595  ni_log2(p_enc_ctx, NI_LOG_ERROR, "Invalid ni_region_of_interest_t.self_size, "
1596  "aux_data size %d self_size %u\n",
1597  aux_data->size, self_size);
1598  } else
1599  {
1600  int nb_roi = aux_data->size / (int)self_size;
1601 
1602  // update ROI(s) if new/different from last one
1603  if (0 == p_enc_ctx->nb_rois || 0 == p_enc_ctx->roi_side_data_size ||
1604  !p_enc_ctx->av_rois || p_enc_ctx->nb_rois != nb_roi ||
1605  p_enc_ctx->roi_side_data_size != aux_data->size ||
1606  memcmp(p_enc_ctx->av_rois, aux_data->data, aux_data->size) != 0)
1607  {
1608  p_enc_ctx->roi_side_data_size = aux_data->size;
1609  p_enc_ctx->nb_rois = nb_roi;
1610 
1611  free(p_enc_ctx->av_rois);
1612  p_enc_ctx->av_rois = malloc(aux_data->size);
1613  if (!p_enc_ctx->av_rois)
1614  {
1615  ni_log2(p_enc_ctx, NI_LOG_ERROR, "malloc ROI aux_data failed.\n");
1616  is_new_rois = 0;
1617  } else
1618  {
1619  memcpy(p_enc_ctx->av_rois, aux_data->data, aux_data->size);
1620  }
1621  } else
1622  {
1623  is_new_rois = 0;
1624  }
1625 
1626  if (is_new_rois)
1627  {
1628  if (set_roi_map(p_enc_ctx, codec_format, aux_data, nb_roi,
1629  api_params->source_width,
1630  api_params->source_height,
1631  api_params->cfg_enc_params.rc.intra_qp))
1632  {
1633  ni_log2(p_enc_ctx, NI_LOG_ERROR, "set_roi_map failed\n");
1634  }
1635  }
1636  }
1637 
1638  // ROI data in the frame
1639  p_enc_frame->roi_len = p_enc_ctx->roi_len;
1640  }
1641 
1642  // when ROI is enabled, a QP map is always supplied with each frame, and
1643  // we use frame->roi_len value to: when 0, supply a zeroed map; when non-0,
1644  // supply the map stored in p_enc_ctx->roi_map.
1645  // - if ROI aux data is present, use it, otherwise:
1646  // - if cacheRoi, use map if exists, use 0 map otherwise
1647  // - if !cacheRoi, use 0 map
1648  // Note: the above excludes the demo modes which is handled separately in
1649  // application (e.g. nienc, xcoder)
1650  if (api_params->cfg_enc_params.roi_enable && !api_params->roi_demo_mode)
1651  {
1652  if (aux_data && p_enc_ctx->roi_map)
1653  {
1654  p_enc_frame->roi_len = p_enc_ctx->roi_len;
1655  } else
1656  {
1657  if (api_params->cacheRoi)
1658  {
1659  p_enc_frame->roi_len =
1660  (p_enc_ctx->roi_map ? p_enc_ctx->roi_len : 0);
1661  } else
1662  {
1663  p_enc_frame->roi_len = 0;
1664  }
1665  }
1666 
1667  p_enc_frame->extra_data_len += p_enc_ctx->roi_len;
1668 
1669  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_prep_aux_data: supply QP map, cacheRoi %d "
1670  "aux_data %d ctx->roi_map %d frame->roi_len %u ctx->roi_len %u\n",
1671  api_params->cacheRoi, aux_data != NULL,
1672  p_enc_ctx->roi_map != NULL, p_enc_frame->roi_len, p_enc_ctx->roi_len);
1673  }
1674 
1675  // prep for NetInt long term reference frame support setting: when this has
1676  // been requested by both frame and API, API takes priority
1677  ni_long_term_ref_t ltr = {0};
1678  aux_data =
1680  if (aux_data)
1681  {
1682  ltr = *((ni_long_term_ref_t *)aux_data->data);
1683  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1684  "%s(): frame aux data LTR use_cur_src_as_ltr %u "
1685  "use_ltr %u\n",
1686  __func__, ltr.use_cur_src_as_long_term_pic,
1687  ltr.use_long_term_ref);
1688  }
1689 
1690  if (p_enc_ctx->ltr_to_set.use_cur_src_as_long_term_pic > 0)
1691  {
1692  ltr = p_enc_ctx->ltr_to_set;
1694  p_enc_ctx->ltr_to_set.use_long_term_ref = 0;
1695 
1696  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1697  "%s(): frame API set LTR use_cur_src_as_ltr %u "
1698  "use_ltr %u\n",
1699  __func__, ltr.use_cur_src_as_long_term_pic,
1700  ltr.use_long_term_ref);
1701  }
1702 
1703  if (ltr.use_cur_src_as_long_term_pic > 0)
1704  {
1705  p_enc_frame->use_cur_src_as_long_term_pic =
1707  p_enc_frame->use_long_term_ref = ltr.use_long_term_ref;
1708  }
1709 
1710  // prep for NetInt target max/min QP reconfiguration support: when max/min QP
1711  // setting has been requested by both frame and API, API takes priority
1712  ni_rc_min_max_qp qp_info = {0};
1713  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_MAX_MIN_QP);
1714  if (aux_data)
1715  {
1716  qp_info = *(ni_rc_min_max_qp *)aux_data->data;
1717  ni_log2(p_enc_ctx, NI_LOG_DEBUG,
1718  "%s(): frame aux data qp info max/min I qp <%d %d> maxDeltaQp <%d> max/min PB qp <%d %d>",
1719  __func__, qp_info.maxQpI, qp_info.minQpI, qp_info.maxDeltaQp, qp_info.maxQpPB, qp_info.minQpPB);
1720  }
1721  if (qp_info.maxQpI > 0)
1722  {
1723  p_enc_ctx->enc_change_params->minQpI = qp_info.minQpI;
1724  p_enc_ctx->enc_change_params->maxQpI = qp_info.maxQpI;
1725  p_enc_ctx->enc_change_params->maxDeltaQp = qp_info.maxDeltaQp;
1726  p_enc_ctx->enc_change_params->minQpPB = qp_info.minQpPB;
1727  p_enc_ctx->enc_change_params->maxQpPB = qp_info.maxQpPB;
1728  p_enc_ctx->enc_change_params->enable_option |=
1730  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1731  }
1732 
1733  // prep for NetInt target bitrate reconfiguration support: when bitrate
1734  // setting has been requested by both frame and API, API takes priority
1735  int32_t bitrate = -1;
1736  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_BITRATE);
1737  if (aux_data)
1738  {
1739  bitrate = *((int32_t *)aux_data->data);
1740  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data bitrate %d\n", __func__,
1741  bitrate);
1742  }
1743 
1744  if (p_enc_ctx->target_bitrate > 0)
1745  {
1746  bitrate = p_enc_ctx->target_bitrate;
1747  p_enc_ctx->target_bitrate = -1;
1748  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set bitrate %d\n", __func__, bitrate);
1749  }
1750 
1751  if (bitrate > 0)
1752  {
1753  p_enc_ctx->enc_change_params->enable_option |=
1755 
1756  p_enc_ctx->enc_change_params->bitRate = bitrate;
1757  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1758 
1759  // update last bitrate with reconfigured bitrate
1760  p_enc_ctx->last_bitrate = bitrate;
1761  ni_log2(p_enc_ctx, NI_LOG_INFO, "%s: bitrate %d updated for reconfig\n", __func__, bitrate);
1762  }
1763 
1764  // prep for NetInt API force frame type
1765  if (p_enc_ctx->force_idr_frame)
1766  {
1767  p_enc_frame->force_key_frame = 1;
1768  p_enc_frame->ni_pict_type = PIC_TYPE_IDR;
1769 
1770  p_enc_ctx->force_idr_frame = 0;
1771  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API force IDR frame\n", __func__);
1772  }
1773 
1774  // prep for NetInt VUI reconfiguration support: when VUI HRD
1775  // setting has been requested by both frame and API, API takes priority
1776  ni_vui_hrd_t vui = {0};
1777  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_VUI);
1778  if (aux_data)
1779  {
1780  ni_vui_hrd_t *aux_vui_ptr = (ni_vui_hrd_t *)aux_data->data;
1781 
1782  if (aux_vui_ptr->colorDescPresent < 0 || aux_vui_ptr->colorDescPresent > 1)
1783  {
1784  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid colorDescPresent in aux data %d\n",
1785  __func__, aux_vui_ptr->colorDescPresent);
1786  }
1787  else
1788  {
1789  vui.colorDescPresent = aux_vui_ptr->colorDescPresent;
1790  }
1791 
1792  if((aux_vui_ptr->aspectRatioWidth > NI_MAX_ASPECTRATIO) || (aux_vui_ptr->aspectRatioHeight > NI_MAX_ASPECTRATIO))
1793  {
1794  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid aspect ratio in aux data %dx%d\n",
1795  __func__, aux_vui_ptr->aspectRatioWidth, aux_vui_ptr->aspectRatioHeight);
1796  }
1797  else
1798  {
1799  vui.colorDescPresent = aux_vui_ptr->colorDescPresent;
1800  vui.colorPrimaries = aux_vui_ptr->colorPrimaries;
1801  vui.colorTrc = aux_vui_ptr->colorTrc;
1802  vui.colorSpace = aux_vui_ptr->colorSpace;
1803  vui.aspectRatioWidth = aux_vui_ptr->aspectRatioWidth;
1804  vui.aspectRatioHeight = aux_vui_ptr->aspectRatioHeight;
1805  }
1806 
1807  if (aux_vui_ptr->videoFullRange < 0 || aux_vui_ptr->videoFullRange > 1)
1808  {
1809  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid videoFullRange in aux data %d\n",
1810  __func__, aux_vui_ptr->videoFullRange);
1811  }
1812  else
1813  {
1814  vui.videoFullRange = aux_vui_ptr->videoFullRange;
1815  }
1816  }
1817 
1818  if (p_enc_ctx->vui.aspectRatioWidth > 0)
1819  {
1820  vui = p_enc_ctx->vui;
1821  p_enc_ctx->vui.colorDescPresent =
1822  p_enc_ctx->vui.colorPrimaries =
1823  p_enc_ctx->vui.colorTrc =
1824  p_enc_ctx->vui.colorSpace =
1825  p_enc_ctx->vui.aspectRatioWidth =
1826  p_enc_ctx->vui.aspectRatioHeight =
1827  p_enc_ctx->vui.videoFullRange = 0;
1828  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set VUI "
1829  "colorDescPresent %d colorPrimaries %d "
1830  "colorTrc %d colorSpace %d aspectRatioWidth %d "
1831  "aspectRatioHeight %d videoFullRange %d\n",
1832  __func__, vui.colorDescPresent,
1833  vui.colorPrimaries, vui.colorTrc,
1834  vui.colorSpace, vui.aspectRatioWidth,
1836  }
1837 
1838  if (vui.aspectRatioWidth > 0)
1839  {
1840  p_enc_ctx->enc_change_params->enable_option |=
1842 
1845  p_enc_ctx->enc_change_params->colorTrc = vui.colorTrc;
1846  p_enc_ctx->enc_change_params->colorSpace = vui.colorSpace;
1850  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1851  }
1852 
1853  // prep for NetInt long term reference interval reconfiguration support:
1854  // when LTR has been requested by both frame and API, API takes priority
1855  int32_t ltr_interval = -1;
1856  aux_data =
1858  if (aux_data)
1859  {
1860  ltr_interval = *((int32_t *)aux_data->data);
1861  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data LTR interval %d\n", __func__,
1862  ltr_interval);
1863  }
1864 
1865  if (p_enc_ctx->ltr_interval > 0)
1866  {
1867  ltr_interval = p_enc_ctx->ltr_interval;
1868  p_enc_ctx->ltr_interval = -1;
1869  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set LTR interval %d\n", __func__,
1870  ltr_interval);
1871  }
1872 
1873  if (ltr_interval > 0)
1874  {
1875  p_enc_ctx->enc_change_params->enable_option |=
1877 
1878  p_enc_ctx->enc_change_params->ltrInterval = ltr_interval;
1879  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1880  }
1881 
1882  // prep for NetInt target framerate reconfiguration support: when framerate
1883  // setting has been requested by both frame aux data and API, API takes priority
1884  ni_framerate_t framerate = {0};
1885  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_FRAMERATE);
1886  if (aux_data)
1887  {
1888  ni_framerate_t *aux_framerate_ptr = (ni_framerate_t *)aux_data->data;
1889  int32_t framerate_num = aux_framerate_ptr->framerate_num;
1890  int32_t framerate_denom = aux_framerate_ptr->framerate_denom;
1891  if ((framerate_num <= 0) || (framerate_denom <= 0))
1892  {
1893  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1894  "ERROR: %s(): invalid framerate in aux data (%d/%d)\n",
1895  __func__, framerate_num, framerate_denom);
1896  } else
1897  {
1898  if ((framerate_num % framerate_denom) != 0)
1899  {
1900  uint32_t numUnitsInTick = 1000;
1901  framerate_num = framerate_num / framerate_denom;
1902  framerate_denom = numUnitsInTick + 1;
1903  framerate_num += 1;
1904  framerate_num *= numUnitsInTick;
1905  } else
1906  {
1907  framerate_num = framerate_num / framerate_denom;
1908  framerate_denom = 1;
1909  }
1910  if (((framerate_num + framerate_denom - 1) / framerate_denom) >
1912  {
1913  ni_log2(p_enc_ctx, NI_LOG_ERROR,
1914  "ERROR: %s(): invalid framerate in aux data (%d/%d)\n",
1915  __func__, aux_framerate_ptr->framerate_num,
1916  aux_framerate_ptr->framerate_denom);
1917  } else
1918  {
1919  framerate.framerate_num = framerate_num;
1920  framerate.framerate_denom = framerate_denom;
1921  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data framerate (%d/%d)\n",
1922  __func__, framerate_num, framerate_denom);
1923  }
1924  }
1925  }
1926 
1927  if (p_enc_ctx->framerate.framerate_num > 0)
1928  {
1929  framerate = p_enc_ctx->framerate;
1930  p_enc_ctx->framerate.framerate_num =
1931  p_enc_ctx->framerate.framerate_denom = 0;
1932  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set framerate (%d/%d)\n", __func__,
1933  framerate.framerate_num, framerate.framerate_denom);
1934  }
1935 
1936  if (framerate.framerate_num > 0)
1937  {
1938  p_enc_ctx->enc_change_params->enable_option |=
1940 
1941  p_enc_ctx->enc_change_params->frameRateNum = framerate.framerate_num;
1942  p_enc_ctx->enc_change_params->frameRateDenom =
1943  framerate.framerate_denom;
1944  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1945 
1946  // update last framerate with reconfigured framerate
1947  p_enc_ctx->last_framerate.framerate_num = framerate.framerate_num;
1948  p_enc_ctx->last_framerate.framerate_denom = framerate.framerate_denom;
1949  ni_log2(p_enc_ctx, NI_LOG_INFO, "%s: framerate num %d denom %d updated for reconfig\n",
1950  __func__, framerate.framerate_num, framerate.framerate_denom);
1951  }
1952 
1953  // prep for NetInt frame reference invalidation support: when this setting
1954  // has been requested by both frame and API, API takes priority
1955  int32_t frame_num = -1;
1956  aux_data =
1958  if (aux_data)
1959  {
1960  frame_num = *((int32_t *)aux_data->data);
1961  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data frame ref invalid %d\n",
1962  __func__, frame_num);
1963  }
1964 
1965  if (p_enc_ctx->ltr_frame_ref_invalid > 0)
1966  {
1967  frame_num = p_enc_ctx->ltr_frame_ref_invalid;
1968  p_enc_ctx->ltr_frame_ref_invalid = -1;
1969  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s(): API set frame ref invalid %d\n", __func__,
1970  frame_num);
1971  }
1972 
1973  if (frame_num >= 0)
1974  {
1975  p_enc_ctx->enc_change_params->enable_option |=
1977 
1978  p_enc_ctx->enc_change_params->invalidFrameNum = frame_num;
1979  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
1980  }
1981 
1982  // prep for alternative preferred transfer characteristics SEI
1983  if (api_params->cfg_enc_params.preferred_transfer_characteristics >= 0 &&
1984  should_send_sei_with_frame)
1985  {
1986  if (NI_CODEC_FORMAT_H264 == codec_format)
1987  {
1988  p_enc_frame->preferred_characteristics_data_len = 9;
1989  } else
1990  {
1991  p_enc_frame->preferred_characteristics_data_len = 10;
1992  }
1993 
1994  p_enc_ctx->preferred_characteristics_data =
1995  (uint8_t)
1997  p_enc_frame->sei_total_len +=
1999  }
2000 
2001  // prep for NetInt maxFrameSize reconfiguration support: when maxFrameSize
2002  // setting has been requested by both frame aux data and API, API takes priority
2003  int32_t max_frame_size = 0;
2005  if (aux_data)
2006  {
2007  max_frame_size = *((int32_t *)aux_data->data);
2008  uint32_t maxFrameSize = (uint32_t)max_frame_size / 2000;
2009  uint32_t min_maxFrameSize;
2010  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data max_frame_size %d\n", __func__,
2011  max_frame_size);
2012 
2013  if (!api_params->low_delay_mode)
2014  {
2015  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is valid only when lowDelay mode is enabled\n",
2016  __func__, max_frame_size);
2017  max_frame_size = 0;
2018  }
2019  else
2020  {
2021  int32_t tmp_bitrate, tmp_framerate_num, tmp_framerate_denom;
2022  tmp_bitrate = (p_enc_ctx->enc_change_params->bitRate > 0) ? p_enc_ctx->enc_change_params->bitRate : api_params->bitrate;
2023 
2024  if ((p_enc_ctx->enc_change_params->frameRateNum > 0) && (p_enc_ctx->enc_change_params->frameRateDenom > 0))
2025  {
2026  tmp_framerate_num = p_enc_ctx->enc_change_params->frameRateNum;
2027  tmp_framerate_denom = p_enc_ctx->enc_change_params->frameRateDenom;
2028  }
2029  else
2030  {
2031  tmp_framerate_num = (int32_t)api_params->fps_number;
2032  tmp_framerate_denom = (int32_t)api_params->fps_denominator;
2033  }
2034 
2035  min_maxFrameSize = (((uint32_t)tmp_bitrate / tmp_framerate_num * tmp_framerate_denom) / 8) / 2000;
2036 
2037  if (maxFrameSize < min_maxFrameSize)
2038  {
2039  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is too small (invalid)\n",
2040  __func__, max_frame_size);
2041  max_frame_size = 0;
2042  }
2043 
2044  if (max_frame_size > NI_MAX_FRAME_SIZE) {
2045  max_frame_size = NI_MAX_FRAME_SIZE;
2046  }
2047  }
2048  }
2049 
2050  if (p_enc_ctx->max_frame_size > 0)
2051  {
2052  max_frame_size = p_enc_ctx->max_frame_size;
2053  p_enc_ctx->max_frame_size = 0;
2054  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set max_frame_size %d\n", __func__, max_frame_size);
2055  }
2056 
2057  if (max_frame_size > 0)
2058  {
2059  p_enc_ctx->enc_change_params->enable_option |=
2061 
2062  p_enc_ctx->enc_change_params->maxFrameSize = (uint16_t)(max_frame_size / 2000);
2063  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2064  }
2065 
2066  // prep for NetInt crf reconfiguration support: when crf
2067  // setting has been requested by both frame aux data and API, API takes priority
2068  float crf = -1.0f;
2069  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_CRF);
2070  if (aux_data)
2071  {
2072  crf = (float)(*((int32_t *)aux_data->data));
2073  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data crf %d\n", __func__,
2074  crf);
2075 
2076  if (api_params->cfg_enc_params.crf < 0)
2077  {
2078  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %d is valid only in CRF mode\n",
2079  __func__, crf);
2080  crf = -1;
2081  }
2082  else
2083  {
2084  if (crf < 0 || crf > 51)
2085  {
2086  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %d is invalid (valid range in [0..51])\n",
2087  __func__, crf);
2088  crf = -1;
2089  }
2090  }
2091  }
2092  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_CRF_FLOAT);
2093  if (aux_data)
2094  {
2095  crf = *((float *)aux_data->data);
2096  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data crf %f\n", __func__,
2097  crf);
2098 
2099  if (api_params->cfg_enc_params.crfFloat < 0)
2100  {
2101  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %f is valid only in CRF mode\n",
2102  __func__, crf);
2103  crf = -1;
2104  }
2105  else
2106  {
2107  if (crf < 0 || crf > 51)
2108  {
2109  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %f is invalid (valid range in [0..51])\n",
2110  __func__, crf);
2111  crf = -1;
2112  }
2113  }
2114  }
2115 
2116  if (p_enc_ctx->reconfig_crf >= 0 || p_enc_ctx->reconfig_crf_decimal > 0)
2117  {
2118  crf = (float)(p_enc_ctx->reconfig_crf +
2119  (float)p_enc_ctx->reconfig_crf_decimal / 100.0);
2120  p_enc_ctx->reconfig_crf = -1;
2121  p_enc_ctx->reconfig_crf_decimal = 0;
2122  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_crf %f\n", __func__, crf);
2123  }
2124 
2125  if (crf >= 0)
2126  {
2127  p_enc_ctx->enc_change_params->enable_option |=
2129 
2130  p_enc_ctx->enc_change_params->crf = (uint8_t)crf;
2131  p_enc_ctx->enc_change_params->crfDecimal =
2132  (float)((crf - (float)p_enc_ctx->enc_change_params->crf) * 100);
2133  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2134  }
2135 
2136  int32_t vbvMaxRate = 0;
2137  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_VBV_MAX_RATE);
2138  if (aux_data)
2139  {
2140  vbvMaxRate = *((int32_t *)aux_data->data);
2141  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data vbvMaxRate %d\n", __func__,
2142  vbvMaxRate);
2143  }
2144 
2145  if (p_enc_ctx->reconfig_vbv_max_rate > 0)
2146  {
2147  vbvMaxRate = p_enc_ctx->reconfig_vbv_max_rate;
2148  p_enc_ctx->reconfig_vbv_max_rate = 0;
2149  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_vbv_max_rate %d\n", __func__, vbvMaxRate);
2150  }
2151 
2152  if (vbvMaxRate)
2153  {
2154  p_enc_ctx->enc_change_params->enable_option |=
2156 
2157  p_enc_ctx->enc_change_params->vbvMaxRate = vbvMaxRate;
2158  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2159  }
2160 
2161  int32_t vbvBufferSize = 0;
2163  if (aux_data)
2164  {
2165  vbvBufferSize = *((int32_t *)aux_data->data);
2166  if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
2167  {
2168  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s(): invalid frame aux data vbvBufferSize %d\n", __func__,
2169  vbvBufferSize);
2170  vbvBufferSize = 0;
2171  }
2172  else
2173  {
2174  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data vbvBufferSize %d\n", __func__,
2175  vbvBufferSize);
2176  }
2177  }
2178 
2179  if (p_enc_ctx->reconfig_vbv_buffer_size > 0)
2180  {
2181  vbvBufferSize = p_enc_ctx->reconfig_vbv_buffer_size;
2182  p_enc_ctx->reconfig_vbv_buffer_size = 0;
2183  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_vbv_max_rate %d\n", __func__, vbvBufferSize);
2184  }
2185 
2186  if (vbvBufferSize)
2187  {
2188  p_enc_ctx->enc_change_params->enable_option |=
2190 
2191  p_enc_ctx->enc_change_params->vbvBufferSize = vbvBufferSize;
2192  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2193  }
2194 
2195  int16_t sliceArg = 0;
2196  aux_data = ni_frame_get_aux_data(p_dec_frame, NI_FRAME_AUX_DATA_SLICE_ARG);
2197  if (aux_data)
2198  {
2199  sliceArg = *((int16_t *)aux_data->data);
2200  ni_encoder_cfg_params_t *p_enc = &api_params->cfg_enc_params;
2201  if (p_enc->slice_mode == 0)
2202  {
2203  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s():not support to reconfig slice_arg when slice_mode disable.\n",
2204  __func__);
2205  sliceArg = 0;
2206  }
2207  if (NI_CODEC_FORMAT_JPEG == p_enc_ctx->codec_format || NI_CODEC_FORMAT_AV1 == p_enc_ctx->codec_format)
2208  {
2209  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s():sliceArg is only supported for H.264 or H.265.\n",
2210  __func__);
2211  sliceArg = 0;
2212  }
2213  int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_enc_ctx->codec_format) ? 16 : 64;
2214  int max_num_ctu_mb_row = (api_params->source_height + ctu_mb_size - 1) / ctu_mb_size;
2215  if (sliceArg < 1 || sliceArg > max_num_ctu_mb_row)
2216  {
2217  ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s(): invalid frame aux data sliceArg %d\n", __func__,
2218  sliceArg);
2219  sliceArg = 0;
2220  }
2221  else
2222  {
2223  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): frame aux data sliceArg %d\n", __func__,
2224  sliceArg);
2225  }
2226  }
2227 
2228  if (p_enc_ctx->reconfig_slice_arg > 0)
2229  {
2230  sliceArg = p_enc_ctx->reconfig_slice_arg;
2231  p_enc_ctx->reconfig_slice_arg = 0;
2232  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s(): API set reconfig_slice_arg %d\n", __func__, sliceArg);
2233  }
2234 
2235  if (sliceArg)
2236  {
2237  if (sliceArg > NI_MAX_SLICE_SIZE) {
2238  ni_log2(p_enc_ctx, NI_LOG_INFO, "%s(): slice arg > NI_MAX_SLICE_SIZE, change from %d to %d\n",
2239  __func__, sliceArg, NI_MAX_SLICE_SIZE);
2240  sliceArg = NI_MAX_SLICE_SIZE;
2241  }
2242  p_enc_ctx->enc_change_params->enable_option |=
2244 
2245  p_enc_ctx->enc_change_params->sliceArg = sliceArg;
2246  p_enc_frame->reconf_len = sizeof(ni_encoder_change_params_t);
2247  }
2248 }
2249 
2250 /*!*****************************************************************************
2251  * \brief Copy auxiliary data that should be sent together with this frame
2252  * to encoder.
2253  *
2254  * \param[in] p_enc_ctx encoder session context
2255  * \param[out] p_enc_frame frame to be sent to encoder
2256  * \param[in] p_dec_frame frame returned by decoder
2257  * \param[in] mdcv_data SEI for HDR mastering display color volume info
2258  * \param[in] cll_data SEI for HDR content light level info
2259  * \param[in] cc_data SEI for close caption
2260  * \param[in] udu_data SEI for User data unregistered
2261  * \param[in] hdrp_data SEI for HDR10+
2262  * \param[in] is_hwframe, must be 0 (sw frame) or 1 (hw frame)
2263  * \param[in] is_semiplanar, must be 1 (semiplanar frame) or 0 (not)
2264  *
2265  * \return NONE
2266  ******************************************************************************/
2268  ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame,
2269  ni_codec_format_t codec_format,
2270  const uint8_t *mdcv_data, const uint8_t *cll_data,
2271  const uint8_t *cc_data, const uint8_t *udu_data,
2272  const uint8_t *hdrp_data, int is_hwframe,
2273  int is_semiplanar)
2274 {
2275  ni_xcoder_params_t *api_params =
2276  (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
2277 
2278  // fill in extra data (skipping meta data header)
2279  if (is_hwframe != 0 && is_hwframe != 1 && is_semiplanar != 0 &&
2280  is_semiplanar != 1)
2281  {
2282  ni_log2(p_enc_ctx, NI_LOG_ERROR,
2283  "ni_enc_copy_aux_data: error, illegal hwframe or nv12frame\n");
2284  return;
2285  }
2286 
2287  uint32_t frame_metadata_size = NI_APP_ENC_FRAME_META_DATA_SIZE;
2289  "6Q") < 0)
2290  {
2292  }
2293  else if (ni_cmp_fw_api_ver((char*) &p_enc_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
2294  "6rc") < 0)
2295  {
2297  }
2298 
2299 
2300  uint8_t *dst = (uint8_t *)p_enc_frame->p_data[2 + is_hwframe] +
2301  p_enc_frame->data_len[2 + is_hwframe] + frame_metadata_size;
2302 
2303  if (!is_hwframe)
2304  {
2305  dst = (uint8_t *)p_enc_frame->p_data[2 - is_semiplanar] +
2306  p_enc_frame->data_len[2 - is_semiplanar] +
2307  frame_metadata_size;
2308  }
2309 
2310  // Separate metadata buffer (not contiguous with YUV buffer)
2311  if (p_enc_frame->separate_metadata)
2312  {
2313  dst = p_enc_frame->p_metadata_buffer + frame_metadata_size;
2314  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: p_metadata_buffer %p frame_metadata_size %u dst %p\n",
2315  p_enc_frame->p_metadata_buffer, frame_metadata_size, dst);
2316  }
2317 
2318  // fill in reconfig data if enabled; even if it's disabled, keep the space
2319  // for it if SEI or ROI is present;
2320  if (p_enc_frame->reconf_len || api_params->cfg_enc_params.roi_enable ||
2321  p_enc_frame->sei_total_len)
2322  {
2323  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: keep reconfig space: %"
2324  PRId64 " to %p\n", sizeof(ni_encoder_change_params_t), dst);
2325 
2326  memset(dst, 0, sizeof(ni_encoder_change_params_t));
2327 
2328  if (p_enc_frame->reconf_len && p_enc_ctx->enc_change_params)
2329  {
2330  memcpy(dst, p_enc_ctx->enc_change_params, p_enc_frame->reconf_len);
2331  }
2332 
2333  dst += sizeof(ni_encoder_change_params_t);
2334  }
2335 
2336  // fill in ROI map, if ROI is enabled; the ROI map could be:
2337  // - a zeroed one, e.g. in the case of no any ROI specified yet at session
2338  // start, or
2339  // - one generated by ROI auxiliary data coming with the frame, or
2340  // - a hardcoded one created in nienc/xcoder by ROI demo modes
2341  if (api_params->cfg_enc_params.roi_enable)
2342  {
2343  if (p_enc_frame->roi_len && p_enc_ctx->roi_map)
2344  {
2345  memcpy(dst, p_enc_ctx->roi_map, p_enc_frame->roi_len);
2346  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: ROI size: %u to %p\n",
2347  p_enc_frame->roi_len, dst);
2348 
2349  } else
2350  {
2351  memset(dst, 0, p_enc_ctx->roi_len);
2352  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: zeroed ROI size: %u to %p\n",
2353  p_enc_ctx->roi_len, dst);
2354  }
2355  // for QUADRA, when ROI enabled, requires ROI map included in input buffer and data transferred for every frame
2356  dst += p_enc_ctx->roi_len;
2357  // reset frame ROI len to the actual map size
2358  p_enc_frame->roi_len = p_enc_ctx->roi_len;
2359  }
2360 
2361  // HDR SEI: mastering display color volume
2362  if (p_enc_frame->sei_hdr_mastering_display_color_vol_len)
2363  {
2364  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: HDR SEI mdcv size: %u to %p\n",
2365  p_enc_frame->sei_hdr_mastering_display_color_vol_len, dst);
2366  memcpy(dst, mdcv_data,
2368  dst += p_enc_frame->sei_hdr_mastering_display_color_vol_len;
2369  }
2370 
2371  // HDR SEI: content light level info
2372  if (p_enc_frame->sei_hdr_content_light_level_info_len)
2373  {
2374  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: HDR SEI cll size: %u to %p\n",
2375  p_enc_frame->sei_hdr_content_light_level_info_len, dst);
2376 
2377  memcpy(dst, cll_data,
2379  dst += p_enc_frame->sei_hdr_content_light_level_info_len;
2380  }
2381 
2382  // HLG SEI: preferred characteristics
2383  if (p_enc_frame->preferred_characteristics_data_len)
2384  {
2385  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: preferred characteristics size: %u to %p\n",
2386  p_enc_frame->preferred_characteristics_data_len, dst);
2387 
2388  dst[0] = dst[1] = dst[2] = 0;
2389  dst[3] = 1;
2390  if (NI_CODEC_FORMAT_H265 == codec_format)
2391  {
2392  dst[4] = 0x4e;
2393  dst[5] = 1;
2394  dst[6] = 0x93; // payload type=147
2395  dst[7] = 1; // payload size=1
2396  dst += 8;
2397  } else
2398  {
2399  dst[4] = 0x6;
2400  dst[5] = 0x93; // payload type=147
2401  dst[6] = 1; // payload size=1
2402  dst += 7;
2403  }
2404  *dst = p_enc_ctx->preferred_characteristics_data;
2405  dst++;
2406  *dst = 0x80;
2407  dst++;
2408  }
2409 
2410  // close caption
2411  if (p_enc_frame->sei_cc_len)
2412  {
2413  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: close caption size: %u to %p\n",
2414  p_enc_frame->sei_cc_len, dst);
2415 
2416  memcpy(dst, cc_data, p_enc_frame->sei_cc_len);
2417  dst += p_enc_frame->sei_cc_len;
2418  }
2419 
2420  // HDR10+
2421  if (p_enc_frame->sei_hdr_plus_len)
2422  {
2423  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: HDR10+ size: %u to %p\n",
2424  p_enc_frame->sei_hdr_plus_len, dst);
2425 
2426  memcpy(dst, hdrp_data, p_enc_frame->sei_hdr_plus_len);
2427  dst += p_enc_frame->sei_hdr_plus_len;
2428  }
2429 
2430  // User data unregistered SEI
2431  if (p_enc_frame->sei_user_data_unreg_len)
2432  {
2433  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "ni_enc_copy_aux_data: UDU size: %u to %p\n",
2434  p_enc_frame->sei_user_data_unreg_len, dst);
2435  memcpy(dst, udu_data, p_enc_frame->sei_user_data_unreg_len);
2436  //dst += p_enc_frame->sei_user_data_unreg_len;
2437  }
2438 }
2439 
2440 /*!*****************************************************************************
2441  * \brief Insert timecode data into picture timing SEI (H264) or time code SEI (H265)
2442  *
2443  * \note This function must be callled after all other aux data has been processed by
2444  * ni_enc_prep_aux_data and ni_enc_copy_aux_data. Otherwise the timecode SEI data
2445  * might be overwritten
2446  *
2447  * \param[in] p_enc_ctx encoder session context
2448  * \param[out] p_enc_frame frame to be sent to encoder
2449  * \param[in] p_timecode the timecode data to be written along with the frame
2450  *
2451  * \return NI_RETCODE_SUCCESS on success, NI_RETCODE_FAILURE on failure
2452  ******************************************************************************/
2454  ni_timecode_t *p_timecode)
2455 {
2456  uint8_t timecode_data[NI_MAX_SEI_DATA];
2457  uint8_t *dst = timecode_data;
2459  uint32_t header_len, payload_len, total_len;
2460  int emu_bytes_inserted, is_hwframe, is_semiplanar;
2461 
2462  if (!p_enc_ctx || !p_enc_frame || !p_timecode) {
2463  ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s received NULL parameter\n", __func__);
2464  return NI_RETCODE_FAILURE;
2465  }
2466 
2467  if (p_enc_ctx->codec_format != NI_CODEC_FORMAT_H264 && p_enc_ctx->codec_format != NI_CODEC_FORMAT_H265) {
2468  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__);
2469  return NI_RETCODE_FAILURE;
2470  }
2471 
2473 
2474  // NAL start code
2475  ni_bs_writer_put(&pb, 0x00, 8);
2476  ni_bs_writer_put(&pb, 0x00, 8);
2477  ni_bs_writer_put(&pb, 0x00, 8);
2478  ni_bs_writer_put(&pb, 0x01, 8);
2479 
2480  // NAL type: SEI
2481  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2482  ni_bs_writer_put(&pb, 0x06, 8);
2483  } else {
2484  ni_bs_writer_put(&pb, 0x4e, 8);
2485  ni_bs_writer_put(&pb, 0x01, 8);
2486  }
2487 
2488  // SEI type: picture timing (1) for H264, time code (136) for H265
2489  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2490  ni_bs_writer_put(&pb, 0x01, 8);
2491  header_len = 7;
2492  } else {
2493  ni_bs_writer_put(&pb, 0x88, 8);
2494  header_len = 8;
2495  }
2496 
2497  // SEI payload size, to be set later
2498  ni_bs_writer_put(&pb, 0x00, 8);
2499 
2500  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2501  ni_bs_writer_put(&pb, 0x0, 4); // pic_struct, always 0 (progressive)
2502  } else {
2503  ni_bs_writer_put(&pb, 0x1, 2); // num_clock_ts, only support inserting 1
2504  }
2505 
2506  // actual timestamp data below, retrieve the values from ni_timecode_t passed in
2507  ni_bs_writer_put(&pb, 0x1, 1); // clock_timestamp_flag = 1
2508  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2509  ni_bs_writer_put(&pb, 0x0, 2); // ct_type, always 0 (progressive)
2510  }
2511  ni_bs_writer_put(&pb, p_timecode->nuit_field_based_flag, 1);
2512  ni_bs_writer_put(&pb, p_timecode->counting_type, 5);
2513  ni_bs_writer_put(&pb, p_timecode->full_timestamp_flag, 1);
2514  ni_bs_writer_put(&pb, p_timecode->discontinuity_flag, 1);
2515  ni_bs_writer_put(&pb, p_timecode->cnt_dropped_flag, 1);
2516  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2517  ni_bs_writer_put(&pb, p_timecode->n_frames, 8);
2518  } else {
2519  ni_bs_writer_put(&pb, p_timecode->n_frames, 9);
2520  }
2521  if (p_timecode->full_timestamp_flag) {
2522  ni_bs_writer_put(&pb, p_timecode->seconds_value, 6);
2523  ni_bs_writer_put(&pb, p_timecode->minutes_value, 6);
2524  ni_bs_writer_put(&pb, p_timecode->hours_value, 5);
2525  } else {
2526  ni_bs_writer_put(&pb, p_timecode->seconds_flag, 1);
2527  if (p_timecode->seconds_flag) {
2528  ni_bs_writer_put(&pb, p_timecode->seconds_value, 6);
2529  ni_bs_writer_put(&pb, p_timecode->minutes_flag, 1);
2530  if (p_timecode->minutes_flag) {
2531  ni_bs_writer_put(&pb, p_timecode->minutes_value, 6);
2532  ni_bs_writer_put(&pb, p_timecode->hours_flag, 1);
2533  if (p_timecode->hours_flag) {
2534  ni_bs_writer_put(&pb, p_timecode->hours_value, 5);
2535  }
2536  }
2537  }
2538  }
2539  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265) {
2540  ni_bs_writer_put(&pb, p_timecode->time_offset_length, 5);
2541  if (p_timecode->time_offset_length) {
2542  ni_bs_writer_put(&pb, p_timecode->time_offset_value, p_timecode->time_offset_length);
2543  }
2544  } else {
2545  // for H264, time_offset_length is stored in HRD parameters in VUI, which can only be set
2546  // in the FW when HRD is enabled, so we assume that it is not present, in which case it
2547  // should be intepreted as 24 by default
2548  ni_bs_writer_put(&pb, p_timecode->time_offset_value, 24);
2549  }
2550 
2551  ni_bs_writer_put(&pb, 1, 1);
2553  payload_len = ((ni_bs_writer_tell(&pb) + 7) / 8) - header_len;
2554  ni_bs_writer_copy(dst, &pb);
2555  ni_bs_writer_clear(&pb);
2556 
2557  // set the SEI payload size
2558  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) {
2559  dst[6] = payload_len;
2560  } else {
2561  dst[7] = payload_len;
2562  }
2563  dst += header_len;
2564 
2565  // insert emulation prevention bytes to the SEI payload data and write trailing bits
2566  emu_bytes_inserted = ni_insert_emulation_prevent_bytes(dst, (int)payload_len);
2567  dst += payload_len + emu_bytes_inserted;
2568  *dst = 0x80;
2569 
2570  // total size of the timecode_data buffer to be copied
2571  total_len = header_len + payload_len + emu_bytes_inserted + 1;
2572 
2573  is_hwframe = p_enc_ctx->hw_action != NI_CODEC_HW_NONE;
2574  is_semiplanar = p_enc_ctx->pixel_format == NI_PIX_FMT_NV12 ||
2575  p_enc_ctx->pixel_format == NI_PIX_FMT_P010LE;
2576  dst = (uint8_t *)p_enc_frame->p_data[2 + is_hwframe] +
2577  p_enc_frame->data_len[2 + is_hwframe] + p_enc_frame->extra_data_len;
2578  if (!is_hwframe)
2579  {
2580  dst = (uint8_t *)p_enc_frame->p_data[2 - is_semiplanar] +
2581  p_enc_frame->data_len[2 - is_semiplanar] + p_enc_frame->extra_data_len;
2582  }
2583 
2584  // separate metadata buffer (not contiguous with YUV buffer)
2585  if (p_enc_frame->separate_metadata)
2586  {
2587  dst = p_enc_frame->p_metadata_buffer + p_enc_frame->extra_data_len;
2588  }
2589 
2590  // copy formatted SEI NAL unit data to the proper buffer
2591  memcpy(dst, timecode_data, total_len);
2592 
2593  // finally, update the relevant data size counters in ni_frame_t
2594  p_enc_frame->sei_total_len += total_len;
2595  p_enc_frame->extra_data_len += total_len;
2596 
2597  return NI_RETCODE_SUCCESS;
2598 }
2599 
2600 /*!*****************************************************************************
2601  * \brief Send an input data frame to the encoder with YUV data given in
2602  * the inputs.
2603  *
2604  * For ideal performance memory should be 4k aligned. If it is not 4K aligned
2605  * then a temporary 4k aligned memory will be used to copy data to and from
2606  * when writing and reading. This will negatively impact performance.
2607  *
2608  * Any metadata to be sent with the frame should be attached to p_enc_frame
2609  * as aux data (e.g. using ni_frame_new_aux_data()).
2610  *
2611  * \param[in] p_ctx Encoder session context
2612  * \param[in] p_enc_frame Struct holding information about the frame
2613  * to be sent to the encoder
2614  * \param[in] p_yuv_buffer Caller allocated buffer holding YUV data
2615  * for the frame
2616  *
2617  * \return On success
2618  * Total number of bytes written
2619  * On failure
2620  * NI_RETCODE_INVALID_PARAM
2621  * NI_RETCODE_ERROR_MEM_ALOC
2622  * NI_RETCODE_ERROR_NVME_CMD_FAILED
2623  * NI_RETCODE_ERROR_INVALID_SESSION
2624  *****************************************************************************/
2626  ni_frame_t *p_enc_frame, uint8_t *p_yuv_buffer)
2627 {
2628  int frame_width;
2629  int frame_height;
2630  bool need_copy = true;
2631  ni_xcoder_params_t *p_param;
2633  bool alignment_2pass_wa = false;
2634  int is_hwframe;
2635 
2636  if (!p_ctx || !p_enc_frame)
2637  {
2638  ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2639  __func__);
2640  return NI_RETCODE_INVALID_PARAM;
2641  }
2642 
2643  if (!p_yuv_buffer)
2644  {
2645  // send EOS
2646  p_enc_frame->end_of_stream = 1;
2647  goto send_frame;
2648  }
2649 
2650  if (((uintptr_t)p_yuv_buffer) % NI_MEM_PAGE_ALIGNMENT)
2651  {
2652  ni_log2(p_ctx, NI_LOG_INFO, "WARNING: %s passed buffer ptr %p is not 4k aligned\n",
2653  __func__, p_yuv_buffer);
2654 
2655  }
2656 
2657  is_hwframe = p_ctx->hw_action != NI_CODEC_HW_NONE;
2658  frame_width = p_enc_frame->video_width;
2659  frame_height = p_enc_frame->video_height;
2660  p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2661 
2662  // extra data starts with metadata header
2664 
2665  if (!p_enc_frame->start_of_stream &&
2666  (p_enc_frame->video_width != p_ctx->actual_video_width ||
2667  p_enc_frame->video_height != p_ctx->active_video_height ||
2668  p_enc_frame->pixel_format != p_ctx->pixel_format))
2669  {
2670  ni_log2(p_ctx, NI_LOG_INFO,
2671  "%s: resolution change %dx%d -> %dx%d "
2672  "or pixel format change %d -> %d\n",
2673  __func__, p_ctx->actual_video_width, p_ctx->active_video_height,
2674  p_enc_frame->video_width, p_enc_frame->video_height,
2675  p_ctx->pixel_format, p_enc_frame->pixel_format);
2676 
2677  // change run state
2679 
2680  ni_log2(p_ctx, NI_LOG_DEBUG, "%s: session_run_state change to %d \n", __func__,
2681  p_ctx->session_run_state);
2682 
2683  // send EOS
2684  p_enc_frame->end_of_stream = 1;
2685  goto send_frame;
2686  }
2687 
2688  // ROI demo mode takes higher priority over aux data
2689  // Note: when ROI demo modes enabled, supply ROI map for the specified range
2690  // frames, and 0 map for others
2691  if (p_param->roi_demo_mode && p_param->cfg_enc_params.roi_enable)
2692  {
2693  if (p_ctx->frame_num > 90 && p_ctx->frame_num < 300)
2694  {
2695  p_enc_frame->roi_len = p_ctx->roi_len;
2696  } else
2697  {
2698  p_enc_frame->roi_len = 0;
2699  }
2700  // when ROI enabled, always have a data buffer for ROI
2701  // Note: this is handled separately from ROI through side/aux data
2702  p_enc_frame->extra_data_len += p_ctx->roi_len;
2703  }
2704 
2705  int should_send_sei_with_frame =
2706  ni_should_send_sei_with_frame(p_ctx, PIC_TYPE_P, p_param);
2707 
2708  uint8_t mdcv_data[NI_MAX_SEI_DATA];
2709  uint8_t cll_data[NI_MAX_SEI_DATA];
2710  uint8_t cc_data[NI_MAX_SEI_DATA];
2711  uint8_t udu_data[NI_MAX_SEI_DATA];
2712  uint8_t hdrp_data[NI_MAX_SEI_DATA];
2713 
2714  // Convert aux data attached to input frame into required format,
2715  // and store in local arrays
2716  ni_enc_prep_aux_data(p_ctx, p_enc_frame, p_enc_frame, p_ctx->codec_format,
2717  should_send_sei_with_frame, mdcv_data, cll_data,
2719 
2720  p_enc_frame->extra_data_len += p_enc_frame->sei_total_len;
2721 
2722  // data layout requirement: leave space for reconfig data if at least one of
2723  // reconfig, SEI or ROI is present
2724  // Note: ROI is present when enabled, so use encode config flag instead of
2725  // frame's roi_len as it can be 0 indicating a 0'd ROI map setting !
2726  if (p_enc_frame->reconf_len || p_enc_frame->sei_total_len ||
2727  (p_param->roi_demo_mode && p_param->cfg_enc_params.roi_enable))
2728  {
2729  p_enc_frame->extra_data_len += sizeof(ni_encoder_change_params_t);
2730  }
2731 
2732  // Check whether line-by-line copy is needed
2733  int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0};
2734  int dst_height_aligned[NI_MAX_NUM_DATA_POINTERS] = {0};
2735  int is_semiplanar = !ni_get_planar_from_pixfmt(p_ctx->pixel_format);
2736  ni_get_hw_yuv420p_dim(frame_width, frame_height, p_ctx->bit_depth_factor,
2737  is_semiplanar, dst_stride, dst_height_aligned);
2738 
2739  int src_stride[NI_MAX_NUM_DATA_POINTERS];
2740  int src_height[NI_MAX_NUM_DATA_POINTERS];
2741  uint8_t *p_src[NI_MAX_NUM_DATA_POINTERS];
2742 
2743  bool isrgba = (p_ctx->pixel_format == NI_PIX_FMT_ABGR || p_ctx->pixel_format == NI_PIX_FMT_ARGB
2744  || p_ctx->pixel_format == NI_PIX_FMT_RGBA || p_ctx->pixel_format == NI_PIX_FMT_BGRA);
2745 
2746  // NOTE - FFmpeg / Gstreamer users should use linesize array in frame structure instead of src_stride in the following sample code
2747  src_stride[0] = frame_width * p_ctx->bit_depth_factor;
2748  src_height[0] = frame_height;
2749  p_src[0] = p_yuv_buffer;
2750 
2751  if (isrgba)
2752  {
2753  src_stride[1] = 0;
2754  src_stride[2] = 0;
2755 
2756  src_height[1] = 0;
2757  src_height[2] = 0;
2758 
2759  p_src[1] = NULL;
2760  p_src[2] = NULL;
2761  }
2762  else
2763  {
2764  src_stride[1] = is_semiplanar ? src_stride[0] : src_stride[0] / 2;
2765  src_stride[2] = is_semiplanar ? 0 : src_stride[0] / 2;
2766 
2767  src_height[1] = src_height[0] / 2;
2768  src_height[2] = is_semiplanar ? 0 : src_height[1];
2769 
2770  p_src[1] = p_src[0] + src_stride[0] * src_height[0];
2771  p_src[2] = p_src[1] + src_stride[1] * src_height[1];
2772  }
2773 
2774  alignment_2pass_wa = (
2775  (p_param->cfg_enc_params.lookAheadDepth ||
2776  p_param->cfg_enc_params.crf >= 0 ||
2777  p_param->cfg_enc_params.crfFloat >= 0) &&
2778  (p_ctx->codec_format == NI_CODEC_FORMAT_H265 ||
2779  p_ctx->codec_format == NI_CODEC_FORMAT_AV1));
2780 
2781  if (alignment_2pass_wa && !is_hwframe) {
2782  if (is_semiplanar) {
2783  // for 2-pass encode output mismatch WA, need to extend (and
2784  // pad) CbCr plane height, because 1st pass assume input 32
2785  // align
2786  dst_height_aligned[1] = (((dst_height_aligned[0] + 31) / 32) * 32) / 2;
2787  } else {
2788  // for 2-pass encode output mismatch WA, need to extend (and
2789  // pad) Cr plane height, because 1st pass assume input 32 align
2790  dst_height_aligned[2] = (((dst_height_aligned[0] + 31) / 32) * 32) / 2;
2791  }
2792  }
2793 
2794  // check input resolution zero copy compatible or not
2796  p_param, frame_width, frame_height,
2797  (const int *)src_stride, false) == NI_RETCODE_SUCCESS)
2798  {
2799  need_copy = false;
2800  //alloc metadata buffer etc. (if needed)
2802  p_enc_frame, frame_width,
2803  frame_height, (const int *)src_stride, (const uint8_t **)p_src,
2804  (int)(p_enc_frame->extra_data_len));
2805  if (retval != NI_RETCODE_SUCCESS)
2806  goto end;
2807  }
2808  else
2809  {
2810  // if linesize changes (while resolution remains the same), copy to previously configured linesizes
2811  if (p_param->luma_linesize && p_param->chroma_linesize)
2812  {
2813  dst_stride[0] = p_param->luma_linesize;
2814  dst_stride[1] = p_param->chroma_linesize;
2815  dst_stride[2] = is_semiplanar ? 0 : p_param->chroma_linesize;
2816  }
2818  p_param->cfg_enc_params.planar, p_enc_frame, frame_width,
2819  dst_height_aligned[0], dst_stride,
2821  (int)(p_enc_frame->extra_data_len), alignment_2pass_wa);
2822  if (retval != NI_RETCODE_SUCCESS)
2823  {
2824  return retval;
2825  }
2826  }
2827 
2828  ni_log2(p_ctx, NI_LOG_TRACE,
2829  "%s: src_stride %d dst_stride "
2830  "%d dst_height_aligned %d src_height %d need_copy %d\n",
2831  __func__, src_stride[0],
2832  dst_stride[0], dst_height_aligned[0],
2833  src_height[0], need_copy);
2834 
2835  if (need_copy)
2836  {
2837  ni_copy_hw_yuv420p((uint8_t **)(p_enc_frame->p_data), p_src,
2838  frame_width, frame_height, p_ctx->bit_depth_factor,
2839  is_semiplanar,
2840  p_param->cfg_enc_params.conf_win_right, dst_stride,
2841  dst_height_aligned, src_stride, src_height);
2842  p_enc_frame->separate_metadata = 0;
2843  }
2844 
2845  ni_log2(p_ctx, NI_LOG_DEBUG,
2846  "p_dst alloc linesize = %d/%d/%d src height=%d "
2847  "dst height aligned = %d/%d/%d force_key_frame=%d, "
2848  "extra_data_len=%u"
2849  " sei_size=%u (hdr_content_light_level %u hdr_mastering_display_"
2850  "color_vol %u hdr10+ %u hrd %d) reconf_size=%u roi_size=%u "
2851  "force_pic_qp=%u udu_sei_size=%u "
2852  "use_cur_src_as_long_term_pic %u use_long_term_ref %u\n",
2853  dst_stride[0], dst_stride[1], dst_stride[2], frame_height,
2854  dst_height_aligned[0], dst_height_aligned[1], dst_height_aligned[2],
2855  p_enc_frame->force_key_frame, p_enc_frame->extra_data_len,
2856  p_enc_frame->sei_total_len,
2859  p_enc_frame->sei_hdr_plus_len, 0, /* hrd is 0 size for now */
2860  p_enc_frame->reconf_len, p_enc_frame->roi_len,
2861  p_enc_frame->force_pic_qp, p_enc_frame->sei_user_data_unreg_len,
2862  p_enc_frame->use_cur_src_as_long_term_pic,
2863  p_enc_frame->use_long_term_ref);
2864 
2865  ni_enc_copy_aux_data(p_ctx, p_enc_frame, p_enc_frame, p_ctx->codec_format,
2867  0 /*swframe*/, is_semiplanar);
2868 
2869 send_frame:
2870  retval = ni_device_session_write(p_ctx, (ni_session_data_io_t *)p_enc_frame,
2872 end:
2873  if (!need_copy)
2874  {
2875  // Don't want to accidentally free or reuse user-allocated YUV buffer, so remove from frame
2876  p_enc_frame->p_buffer = NULL;
2877  p_enc_frame->buffer_size = 0;
2878  for (int i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
2879  {
2880  p_enc_frame->data_len[i] = 0;
2881  p_enc_frame->p_data[i] = NULL;
2882  }
2883  }
2884 
2885  return retval;
2886 }
2887 
2888 /*!*****************************************************************************
2889  * \brief Find the next start code
2890  *
2891  * \param[in] p pointer to buffer start address.
2892  * \param[in] end pointer to buffer end address.
2893  * \param[state] state pointer to nalu type address
2894  *
2895  * \return search end address
2896  ******************************************************************************/
2897 const uint8_t *ni_find_start_code (const uint8_t *p, const uint8_t *end, uint32_t *state)
2898 {
2899  int i;
2900 
2901  if (p >= end)
2902  return end;
2903 
2904  for (i = 0; i < 3; i++) {
2905  uint32_t tmp = *state << 8;
2906  *state = tmp + *(p++);
2907  if (tmp == 0x100 || p == end)
2908  return p;
2909  }
2910 
2911  while (p < end) {
2912  if (p[-1] > 1)
2913  p += 3;
2914  else if (p[-2])
2915  p += 2;
2916  else if (p[-3] | (p[-1] - 1))
2917  p++;
2918  else {
2919  p++;
2920  break;
2921  }
2922  }
2923 
2924  p = ((p) < (end) ? (p - 4) : (end - 4)); // min
2925  *state =
2926  (((uint32_t) (p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | (p)[3]);
2927 
2928  return p + 4;
2929 }
2930 
2931 /*!******************************************************************************
2932  * \brief Extract custom sei payload data from pkt_data,
2933  * and save it to ni_packet_t
2934  *
2935  * \param uint8_t *pkt_data - FFmpeg AVPacket data
2936  * \param int pkt_size - packet size
2937  * \param long index - pkt data index of custom sei first byte after SEI type
2938  * \param ni_packet_t *p_packet - libxcoder internal packet
2939  * \param uint8_t sei_type - type of SEI
2940  * \param int vcl_found - whether got vcl in the pkt data, 1 means got
2941  *
2942  * \return - 0 on success, non-0 on failure
2943  ********************************************************************************/
2944 int ni_extract_custom_sei(uint8_t *pkt_data, int pkt_size, long index,
2945  ni_packet_t *p_packet, uint8_t sei_type, int vcl_found)
2946 {
2947  int i, len;
2948  uint8_t *udata;
2949  uint8_t *sei_data;
2950  int sei_size;
2951  int sei_index;
2952  ni_custom_sei_t *p_custom_sei;
2953 
2954  ni_log(NI_LOG_TRACE, "%s() enter\n", __FUNCTION__);
2955 
2956  if (p_packet->p_custom_sei_set == NULL)
2957  {
2958  /* max size */
2959  p_packet->p_custom_sei_set = (ni_custom_sei_set_t *)malloc(sizeof(ni_custom_sei_set_t));
2960  if (p_packet->p_custom_sei_set == NULL)
2961  {
2962  ni_log(NI_LOG_ERROR, "failed to allocate all custom sei buffer.\n");
2964  }
2965  memset(p_packet->p_custom_sei_set, 0, sizeof(ni_custom_sei_set_t));
2966  }
2967 
2968  sei_index = p_packet->p_custom_sei_set->count;
2969  p_custom_sei = &p_packet->p_custom_sei_set->custom_sei[sei_index];
2970  if (sei_index >= NI_MAX_CUSTOM_SEI_CNT)
2971  {
2972  ni_log(NI_LOG_INFO, "number of custom sei in current frame is out of limit(%d).\n",
2974  return 0;
2975  }
2976  sei_data = &p_custom_sei->data[0];
2977 
2985  sei_size = 0;
2986  while (index < pkt_size && pkt_data[index] == 0xff)
2987  {
2988  sei_size += pkt_data[index++];
2989  }
2990 
2991  if (index >= pkt_size)
2992  {
2993  ni_log(NI_LOG_INFO, "custom sei corrupted: length truncated.\n");
2994  return NI_RETCODE_FAILURE;
2995  }
2996  sei_size += pkt_data[index++];
2997 
2998  if (sei_size > NI_MAX_CUSTOM_SEI_DATA)
2999  {
3000  ni_log(NI_LOG_INFO, "custom sei corrupted: size(%d) out of limit(%d).\n",
3001  sei_size, NI_MAX_CUSTOM_SEI_DATA);
3002  return 0;
3003  }
3004 
3005  udata = &pkt_data[index];
3006 
3007  /* set SEI payload type at the first byte */
3008  sei_data[0] = sei_type;
3009 
3010  /* extract SEI payload data
3011  * SEI payload data in NAL is EBSP(Encapsulated Byte Sequence Payload),
3012  * need change EBSP to RBSP(Raw Byte Sequence Payload) for exact size
3013  */
3014  for (i = 0, len = 0; (i < pkt_size - index) && len < sei_size; i++, len++)
3015  {
3016  /* if the latest 3-byte data pattern matchs '00 00 03' which means udata[i] is an escaping byte,
3017  * discard udata[i]. */
3018  if (i >= 2 && udata[i - 2] == 0 && udata[i - 1] == 0 && udata[i] == 3)
3019  {
3020  len--;
3021  continue;
3022  }
3023  sei_data[len] = udata[i];
3024  }
3025 
3026  if (len != sei_size)
3027  {
3028  ni_log(NI_LOG_INFO, "custom sei corrupted: data truncated, "
3029  "required size:%d, actual size:%d.\n", sei_size, len);
3030  return NI_RETCODE_FAILURE;
3031  }
3032 
3033  p_custom_sei->type = sei_type;
3034  p_custom_sei->size = sei_size;
3036 
3037  p_packet->p_custom_sei_set->count++;
3038 
3039  ni_log(NI_LOG_TRACE, "%s() exit, custom sei size=%d type=%d\n",
3040  __FUNCTION__, sei_size, sei_type);
3041 
3042  return 0;
3043 }
3044 
3045 /*!******************************************************************************
3046  * \brief Decode parse packet
3047  *
3048  * \param[in] p_session_ctx Pointer to a caller allocated
3049  * ni_session_context_t struct
3050  * \param[in] p_param Pointer to a caller allocated
3051  * ni_xcoder_params_t struct
3052  * \param[in] *data FFmpeg AVPacket data
3053  * \param[in] size packet size
3054  * \param[in] p_packet Pointer to a caller allocated
3055  * ni_packet_t struct
3056  * \param[in] low_delay FFmpeg lowdelay
3057  * \param[in] codec_format enum ni_codec_format_t
3058  * \param[in] pkt_nal_bitmap pkt_nal_bitmap
3059  * \param[in] custom_sei_type custom_sei_type
3060  * \param[in] *svct_skip_next_packet svct_skip_next_packet int*
3061  * \param[in] *is_lone_sei_pkt is_lone_sei_pkt int*
3062  *
3063  * \return - 0 on success, non-0 on failure
3064  ********************************************************************************/
3066  uint8_t *data, int size, ni_packet_t *p_packet, int low_delay,
3067  int codec_format, int pkt_nal_bitmap, int custom_sei_type,
3068  int *svct_skip_next_packet, int *is_lone_sei_pkt)
3069 {
3070  int pkt_sei_alone = 1;
3071  int vcl_found = 0;
3072  int tmp_low_delay =
3073  (p_session_ctx->decoder_low_delay == -1) ? 0 : low_delay;
3074  int svct_layer = (codec_format == NI_CODEC_FORMAT_H264) ?
3077  // int pkt_nal_bitmap = ni_dec_ctx->pkt_nal_bitmap;
3078  const uint8_t *ptr = data;
3079  const uint8_t *end = data + size;
3080  uint32_t stc;
3081  int nalu_type;
3082  uint8_t sei_type = 0;
3083  int ret = 0;
3084  int nalu_count = 0;
3086  uint32_t temporal_id;
3087 
3088  if (pkt_nal_bitmap & NI_GENERATE_ALL_NAL_HEADER_BIT)
3089  {
3090  ni_log2(p_session_ctx, NI_LOG_TRACE,
3091  "ni_dec_packet_parse(): already find the header of streams.\n");
3092  low_delay = 0;
3093  }
3094 
3095  while (
3096  (custom_sei_type != NI_INVALID_SEI_TYPE ||
3098  svct_layer != NI_INVALID_SVCT_DECODING_LAYER || tmp_low_delay ||
3100  ptr < end)
3101  {
3102  stc = -1;
3103  ptr = ni_find_start_code(ptr, end, &stc);
3104  if (ptr == end)
3105  {
3106  if (0 == nalu_count)
3107  {
3108  pkt_sei_alone = 0;
3109  ni_log2(p_session_ctx, NI_LOG_TRACE, "%s(): no NAL found in pkt.\n",
3110  __FUNCTION__);
3111  }
3112  break;
3113  }
3114  nalu_count++;
3115 
3116  if (NI_CODEC_FORMAT_H264 == codec_format)
3117  {
3118  nalu_type = (int)stc & 0x1f;
3119 
3120  //check whether the packet is sei alone
3121  pkt_sei_alone = (pkt_sei_alone && 6 /*H264_NAL_SEI */ == nalu_type);
3122 
3123  // Enable decoder low delay mode on sequence change
3124  if (low_delay)
3125  {
3126  switch (nalu_type)
3127  {
3128  case 7 /*H264_NAL_SPS */:
3129  pkt_nal_bitmap |= NI_NAL_SPS_BIT;
3130  break;
3131  case 8 /*H264_NAL_PPS */:
3132  pkt_nal_bitmap |= NI_NAL_PPS_BIT;
3133  break;
3134  default:
3135  break;
3136  }
3137 
3138  if (pkt_nal_bitmap == (NI_NAL_SPS_BIT | NI_NAL_PPS_BIT))
3139  {
3140  ni_log2(p_session_ctx, NI_LOG_TRACE,
3141  "ni_dec_packet_parse(): Detect SPS, PPS and IDR, "
3142  "enable decoder low delay mode.\n");
3143  p_session_ctx->decoder_low_delay = low_delay;
3144  pkt_nal_bitmap |= NI_GENERATE_ALL_NAL_HEADER_BIT;
3145  low_delay = 0;
3146  }
3147  }
3148  // check whether the packet contains SEI NAL after VCL units
3149  if (6 /*H264_NAL_SEI */ == nalu_type)
3150  {
3151  sei_type = *ptr;
3152  if (vcl_found ||
3153  custom_sei_type == sei_type ||
3154  p_param->dec_input_params.custom_sei_passthru == sei_type ||
3156  {
3157  // SEI after VCL found or SEI type indicated then extract
3158  // the SEI unit;
3159  // ret = ni_quadra_extract_custom_sei(ni_dec_ctx, data, size,
3160  // ptr + 1 - data, p_packet,
3161  // sei_type, vcl_found);
3162  ret = ni_extract_custom_sei(data, size,
3163  ptr + 1 - data, p_packet,
3164  sei_type, vcl_found);
3165  if (ret != 0)
3166  {
3167  return ret;
3168  }
3169  }
3170  } else if (nalu_type >= 1 /* H264_NAL_SLICE */ &&
3171  nalu_type <= 5 /* H264_NAL_IDR_SLICE */)
3172  {
3173  vcl_found = 1;
3174  } else if (14 /*H264_NAL_PREFIX */ == nalu_type)
3175  {
3176  ni_bitstream_reader_init(&br, ptr,
3177  48); // 3 * 2 bytes * 8 = 48 bits
3178  // skip some header
3179  ni_bs_reader_skip_bits(&br, 16);
3180  temporal_id = ni_bs_reader_get_bits(&br, 3);
3181  if (temporal_id > svct_layer)
3182  {
3183  // H264_NAL_PREFIX UNIT will be sent with the last packet.
3184  // So, the H264_NAL_PREFIX here is used for the next packet.
3185  *svct_skip_next_packet = 1;
3186  ni_log2(p_session_ctx, NI_LOG_TRACE,
3187  "ni_dec_packet_parse(): temporal_id %d"
3188  " is bigger than decoded layer %d, skip the next "
3189  "packet\n",
3190  temporal_id, svct_layer);
3191  }
3192  }
3193  } else if (NI_CODEC_FORMAT_H265 == codec_format)
3194  {
3195  nalu_type = (int)(stc >> 1) & 0x3F;
3196 
3197  //check whether the packet is sei alone
3198  pkt_sei_alone = (pkt_sei_alone &&
3199  (39 /* HEVC_NAL_SEI_PREFIX */ == nalu_type ||
3200  40 /* HEVC_NAL_SEI_SUFFIX */ == nalu_type));
3201 
3202  // Enable decoder low delay mode on sequence change
3203  if (low_delay)
3204  {
3205  switch (nalu_type)
3206  {
3207  case 32 /* HEVC_NAL_VPS */:
3208  pkt_nal_bitmap |= NI_NAL_VPS_BIT;
3209  break;
3210  case 33 /* HEVC_NAL_SPS */:
3211  pkt_nal_bitmap |= NI_NAL_SPS_BIT;
3212  break;
3213  case 34 /* HEVC_NAL_PPS */:
3214  pkt_nal_bitmap |= NI_NAL_PPS_BIT;
3215  break;
3216  default:
3217  break;
3218  }
3219 
3220  if (pkt_nal_bitmap ==
3222  {
3223  // Packets before the header is sent cannot be decoded.
3224  // So set packet num to zero here.
3225  ni_log2(p_session_ctx, NI_LOG_TRACE,
3226  "ni_dec_packet_parse(): Detect VPS, SPS, PPS and "
3227  "IDR enable decoder low delay mode.\n");
3228  p_session_ctx->decoder_low_delay = low_delay;
3229  pkt_nal_bitmap |= NI_GENERATE_ALL_NAL_HEADER_BIT;
3230  low_delay = 0;
3231  }
3232  }
3233  // check whether the packet contains SEI NAL after VCL units
3234  if (39 /* HEVC_NAL_SEI_PREFIX */ == nalu_type ||
3235  40 /* HEVC_NAL_SEI_SUFFIX */ == nalu_type)
3236  {
3237  sei_type = *(ptr + 1);
3238  if (vcl_found ||
3239  custom_sei_type == sei_type ||
3240  p_param->dec_input_params.custom_sei_passthru == sei_type ||
3242  {
3243  // SEI after VCL found or SEI type indicated then extract
3244  // the SEI unit;
3245  // ret = ni_quadra_extract_custom_sei(ni_dec_ctx, data, size,
3246  // ptr + 2 - data, p_packet,
3247  // sei_type, vcl_found);
3248  ret = ni_extract_custom_sei(data, size, ptr + 2 - data, p_packet,
3249  sei_type, vcl_found);
3250  if (ret != 0)
3251  {
3252  return ret;
3253  }
3254  }
3255  } else if (nalu_type >= 0 /* HEVC_NAL_TRAIL_N */ &&
3256  nalu_type <= 31 /* HEVC_NAL_RSV_VCL31 */)
3257  {
3258  vcl_found = 1;
3259  }
3260  } else
3261  {
3262  ni_log2(p_session_ctx,NI_LOG_DEBUG, "%s() wrong codec %d !\n", __FUNCTION__, codec_format);
3263  pkt_sei_alone = 0;
3264  break;
3265  }
3266  }
3267 
3268  if (nalu_count > 0)
3269  {
3270  *is_lone_sei_pkt = pkt_sei_alone;
3271  }
3272 
3273  return 0;
3274 }
3275 
3276 /*!******************************************************************************
3277  * \brief Expand frame form src frame
3278  *
3279  * \param[in] dst Pointer to a caller allocated ni_frame_t struct
3280  * \param[in] src Pointer to a caller allocated ni_frame_t struct
3281  * \param[in] dst_stride int dst_stride[]
3282  * \param[in] raw_width frame width
3283  * \param[in] raw_height frame height
3284  * \param[in] ni_fmt ni_pix_fmt_t type for ni pix_fmt
3285  * \param[in] nb_planes int nb_planes
3286  *
3287  * \return - 0 on success, NI_RETCODE_FAILURE on failure
3288  ********************************************************************************/
3289 int ni_expand_frame(ni_frame_t *dst, ni_frame_t *src, int dst_stride[],
3290  int raw_width, int raw_height, int ni_fmt, int nb_planes)
3291 {
3292  int i, j, h, tenBit = 0;
3293  int vpad[3], hpad[3], src_height[3], src_width[3], src_stride[3];
3294  uint8_t *src_line, *dst_line, *sample, *dest, YUVsample;
3295  uint16_t lastidx;
3296 
3297  switch (ni_fmt)
3298  {
3299  case NI_PIX_FMT_YUV420P:
3300  /* width of source frame for each plane in pixels */
3301  src_width[0] = NIALIGN(raw_width, 2);
3302  src_width[1] = NIALIGN(raw_width, 2) / 2;
3303  src_width[2] = NIALIGN(raw_width, 2) / 2;
3304 
3305  /* height of source frame for each plane in pixels */
3306  src_height[0] = NIALIGN(raw_height, 2);
3307  src_height[1] = NIALIGN(raw_height, 2) / 2;
3308  src_height[2] = NIALIGN(raw_height, 2) / 2;
3309 
3310  /* stride of source frame for each plane in bytes */
3311  src_stride[0] = NIALIGN(src_width[0], 128);
3312  src_stride[1] = NIALIGN(src_width[1], 128);
3313  src_stride[2] = NIALIGN(src_width[2], 128);
3314 
3315  tenBit = 0;
3316 
3317  /* horizontal padding needed for each plane in bytes */
3318  hpad[0] = dst_stride[0] - src_width[0];
3319  hpad[1] = dst_stride[1] - src_width[1];
3320  hpad[2] = dst_stride[2] - src_width[2];
3321 
3322  /* vertical padding needed for each plane in pixels */
3323  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3324  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3325  vpad[2] = NI_MIN_HEIGHT / 2 - src_height[2];
3326 
3327  break;
3328 
3330  /* width of source frame for each plane in pixels */
3331  src_width[0] = NIALIGN(raw_width, 2);
3332  src_width[1] = NIALIGN(raw_width, 2) / 2;
3333  src_width[2] = NIALIGN(raw_width, 2) / 2;
3334 
3335  /* height of source frame for each plane in pixels */
3336  src_height[0] = NIALIGN(raw_height, 2);
3337  src_height[1] = NIALIGN(raw_height, 2) / 2;
3338  src_height[2] = NIALIGN(raw_height, 2) / 2;
3339 
3340  /* stride of source frame for each plane in bytes */
3341  src_stride[0] = NIALIGN(src_width[0] * 2, 128);
3342  src_stride[1] = NIALIGN(src_width[1] * 2, 128);
3343  src_stride[2] = NIALIGN(src_width[2] * 2, 128);
3344 
3345  tenBit = 1;
3346 
3347  /* horizontal padding needed for each plane in bytes */
3348  hpad[0] = dst_stride[0] - src_width[0] * 2;
3349  hpad[1] = dst_stride[1] - src_width[1] * 2;
3350  hpad[2] = dst_stride[2] - src_width[2] * 2;
3351 
3352  /* vertical padding needed for each plane in pixels */
3353  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3354  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3355  vpad[2] = NI_MIN_HEIGHT / 2 - src_height[2];
3356 
3357  break;
3358 
3359  case NI_PIX_FMT_NV12:
3360  /* width of source frame for each plane in pixels */
3361  src_width[0] = NIALIGN(raw_width, 2);
3362  src_width[1] = NIALIGN(raw_width, 2);
3363  src_width[2] = 0;
3364 
3365  /* height of source frame for each plane in pixels */
3366  src_height[0] = NIALIGN(raw_height, 2);
3367  src_height[1] = NIALIGN(raw_height, 2) / 2;
3368  src_height[2] = 0;
3369 
3370  /* stride of source frame for each plane in bytes */
3371  src_stride[0] = NIALIGN(src_width[0], 128);
3372  src_stride[1] = NIALIGN(src_width[1], 128);
3373  src_stride[2] = 0;
3374 
3375  tenBit = 0;
3376 
3377  /* horizontal padding needed for each plane in bytes */
3378  hpad[0] = dst_stride[0] - src_width[0];
3379  hpad[1] = dst_stride[1] - src_width[1];
3380  hpad[2] = 0;
3381 
3382  /* vertical padding for each plane in pixels */
3383  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3384  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3385  vpad[2] = 0;
3386 
3387  break;
3388 
3389  case NI_PIX_FMT_P010LE:
3390  /* width of source frame for each plane in pixels */
3391  src_width[0] = NIALIGN(raw_width, 2);
3392  src_width[1] = NIALIGN(raw_width, 2);
3393  src_width[2] = 0;
3394 
3395  /* height of source frame for each plane in pixels */
3396  src_height[0] = NIALIGN(raw_height, 2);
3397  src_height[1] = NIALIGN(raw_height, 2) / 2;
3398  src_height[2] = 0;
3399 
3400  /* stride of source frame for each plane in bytes */
3401  src_stride[0] = NIALIGN(src_width[0] * 2, 128);
3402  src_stride[1] = NIALIGN(src_width[1] * 2, 128);
3403  src_stride[2] = 0;
3404 
3405  tenBit = 1;
3406 
3407  /* horizontal padding needed for each plane in bytes */
3408  hpad[0] = dst_stride[0] - src_width[0] * 2;
3409  hpad[1] = dst_stride[1] - src_width[1] * 2;
3410  hpad[2] = 0;
3411 
3412  /* vertical padding for each plane in pixels */
3413  vpad[0] = NI_MIN_HEIGHT - src_height[0];
3414  vpad[1] = NI_MIN_HEIGHT / 2 - src_height[1];
3415  vpad[2] = 0;
3416 
3417  break;
3418 
3419  default:
3420  ni_log(NI_LOG_ERROR, "Invalid pixel format %d\n",ni_fmt);
3421  return NI_RETCODE_FAILURE;
3422  }
3423 
3424  for (i = 0; i < nb_planes && nb_planes < NI_MAX_NUM_DATA_POINTERS; i++)
3425  {
3426  dst_line = dst->p_data[i];
3427  src_line = src->p_data[i];
3428 
3429  for (h = 0; i < 3 && h < src_height[i]; h++)
3430  {
3431  memcpy(dst_line, src_line, src_width[i] * (tenBit + 1));
3432 
3433  /* Add horizontal padding */
3434  if (hpad[i])
3435  {
3436  lastidx = src_width[i];
3437 
3438  if (tenBit)
3439  {
3440  sample = &src_line[(lastidx - 1) * 2];
3441  dest = &dst_line[lastidx * 2];
3442 
3443  /* two bytes per sample */
3444  for (j = 0; j < hpad[i] / 2; j++)
3445  {
3446  memcpy(dest, sample, 2);
3447  dest += 2;
3448  }
3449  } else
3450  {
3451  YUVsample = dst_line[lastidx - 1];
3452  memset(&dst_line[lastidx], YUVsample, hpad[i]);
3453  }
3454  }
3455 
3456  src_line += src_stride[i];
3457  dst_line += dst_stride[i];
3458  }
3459 
3460  /* Pad the height by duplicating the last line */
3461  src_line = dst_line - dst_stride[i];
3462 
3463  for (h = 0; h < vpad[i]; h++)
3464  {
3465  memcpy(dst_line, src_line, dst_stride[i]);
3466  dst_line += dst_stride[i];
3467  }
3468  }
3469 
3470  return 0;
3471 }
3472 
3473 /*!******************************************************************************
3474  * \brief Reset decoder ppu resolution
3475  *
3476  * \param[in] p_session_ctx Pointer to a caller allocated
3477  * ni_session_context_t struct
3478  * \param[in] p_param Pointer to a caller allocated
3479  * ni_xcoder_params_t struct
3480  * \param[in] ppu_config Pointer to a caller allocated
3481  * ni_ppu_config_t struct
3482  *
3483  * \return - 0 on success, NI_RETCODE_FAILURE on failure
3484  ********************************************************************************/
3486  ni_xcoder_params_t *p_param, ni_ppu_config_t *ppu_config)
3487 {
3488  int sei_size, size, len;
3489  int ret = 0, i = 0, j = 0;
3490  uint8_t *p_src_sei_data, *p_dst_sei_data;
3491  ni_custom_sei_t *p_dst_custom_sei;
3492 
3493  if (!p_session_ctx || !p_param || !ppu_config)
3494  {
3496  return ret;
3497  }
3498 
3499  // check fw revision
3500  if (ni_cmp_fw_api_ver(
3501  (char*) &p_session_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
3502  "6rx") < 0)
3503  {
3504  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: not supported on device with FW API version < 6rx\n", __func__);
3506  }
3507 
3508  if (NI_CODEC_FORMAT_H264 != p_session_ctx->codec_format &&
3509  NI_CODEC_FORMAT_H265 != p_session_ctx->codec_format)
3510  {
3511  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Ppu reconfig only support "
3512  "h264 and h265 decoder\n", __func__);
3514  }
3515 
3516  ni_decoder_input_params_t *p_dec_input_param = &(p_param->dec_input_params);
3517  if (p_dec_input_param->hwframes != 1)
3518  {
3519  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Not hw mode, "
3520  "So can't reconfig ppu\n", __func__);
3522  }
3523  if (p_dec_input_param->enable_out1 == 0 &&
3524  ppu_config->ppu_set_enable & (0x01 << 1))
3525  {
3526  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Warning Not enable ppu1, "
3527  "So can't reconfig ppu1\n", __func__);
3529  }
3530  if (p_dec_input_param->enable_out2 == 0 &&
3531  ppu_config->ppu_set_enable & (0x01 << 2))
3532  {
3533  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Warning Not enable ppu2, "
3534  "So can't reconfig ppu2\n", __func__);
3536  }
3537  for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
3538  {
3539  if (ppu_config->ppu_set_enable & (0x01 << i))
3540  {
3541  if (ppu_config->ppu_w[i] > NI_MAX_RESOLUTION_WIDTH ||
3542  ppu_config->ppu_h[i] > NI_MAX_RESOLUTION_HEIGHT ||
3543  ppu_config->ppu_w[i] < NI_MIN_RESOLUTION_WIDTH_SCALER ||
3544  ppu_config->ppu_h[i] < NI_MIN_RESOLUTION_WIDTH_SCALER)
3545  {
3546  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu width x height %dx%d "
3547  "out of range\n", __func__, ppu_config->ppu_w[i], ppu_config->ppu_h[i]);
3549  return ret;
3550  }
3551  if ((ppu_config->ppu_w[i] & 1) || (ppu_config->ppu_h[i] & 1))
3552  {
3553  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu wxh %dx%d not align to 2!\n",
3554  __func__, ppu_config->ppu_w[i], ppu_config->ppu_h[i]);
3556  return ret;
3557  }
3558  }
3559  }
3560  p_dst_custom_sei = malloc(sizeof(ni_custom_sei_t));
3561  if (p_dst_custom_sei == NULL)
3562  {
3563  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): failed "
3564  "to allocate memory for custom sei data\n", __func__);
3566  return ret;
3567  }
3568  memset(p_dst_custom_sei, 0, sizeof(ni_custom_sei_t));
3569 
3570 
3571  sei_size = sizeof(ni_ppu_config_t);
3572 
3573  p_src_sei_data = (uint8_t *)ppu_config;
3574  p_dst_sei_data = &p_dst_custom_sei->data[0];
3575  size = 0;
3576 
3577  // long start code
3578  p_dst_sei_data[size++] = 0x00;
3579  p_dst_sei_data[size++] = 0x00;
3580  p_dst_sei_data[size++] = 0x00;
3581  p_dst_sei_data[size++] = 0x01;
3582 
3583  if (NI_CODEC_FORMAT_H264 == p_session_ctx->codec_format)
3584  {
3585  p_dst_sei_data[size++] = 0x06; //nal type: SEI
3586  }
3587  else
3588  {
3589  p_dst_sei_data[size++] = 0x4e; //nal type: SEI
3590  p_dst_sei_data[size++] = 0x01;
3591  }
3592 
3593  // SEI type
3594  p_dst_sei_data[size++] = NI_SEI_TYPE_PPU_RECONFIG;
3595 
3596  // original payload size
3597  len = sei_size;
3598  while (len >= 0)
3599  {
3600  p_dst_sei_data[size++] = len > 0xff ? 0xff : len;
3601  len -= 0xff;
3602  }
3603 
3604  // payload data
3605  for (j = 0; j < sei_size && size < NI_MAX_CUSTOM_SEI_DATA - 1; j++)
3606  {
3607  if (j >= 2 && !p_dst_sei_data[size - 2] && !p_dst_sei_data[size - 1] && p_src_sei_data[j] <= 0x03)
3608  {
3609  /* insert 0x3 as emulation_prevention_three_byte */
3610  p_dst_sei_data[size++] = 0x03;
3611  }
3612  p_dst_sei_data[size++] = p_src_sei_data[j];
3613  }
3614 
3615  if (j != sei_size)
3616  {
3617  ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): sei RBSP size out of limit(%d), "
3618  "idx=%u, size=%d\n", __func__,
3619  NI_MAX_CUSTOM_SEI_DATA, i, sei_size);
3620  free(p_dst_custom_sei);
3621  return NI_RETCODE_FAILURE;
3622  }
3623 
3624  // trailing byte
3625  p_dst_sei_data[size++] = 0x80;
3626 
3627  memcpy(p_session_ctx->p_leftover + p_session_ctx->prev_size,
3628  p_dst_sei_data, size);
3629  p_session_ctx->prev_size += size;
3630  free(p_dst_custom_sei);
3631 
3632  return ret;
3633 }
_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:691
_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:2719
_ni_region_of_interest::left
int left
Definition: ni_device_api.h:636
_ni_xcoder_params::luma_linesize
int luma_linesize
Definition: ni_device_api.h:2784
NI_PIX_FMT_BGRA
@ NI_PIX_FMT_BGRA
Definition: ni_device_api.h:267
_ni_session_context::force_idr_frame
int force_idr_frame
Definition: ni_device_api.h:1600
NI_CODEC_FORMAT_JPEG
@ NI_CODEC_FORMAT_JPEG
Definition: ni_device_api.h:914
NI_FRAME_AUX_DATA_MAX_FRAME_SIZE
@ NI_FRAME_AUX_DATA_MAX_FRAME_SIZE
Definition: ni_device_api.h:566
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:4066
_ni_session_context::sei_hdr_mastering_display_color_vol_len
int sei_hdr_mastering_display_color_vol_len
Definition: ni_device_api.h:1429
_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:955
NI_MAX_RESOLUTION_HEIGHT
#define NI_MAX_RESOLUTION_HEIGHT
Definition: ni_device_api.h:101
NI_UNUSED
#define NI_UNUSED
Definition: ni_defs.h:64
NI_DEVICE_TYPE_ENCODER
@ NI_DEVICE_TYPE_ENCODER
Definition: ni_defs.h:347
_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:2853
_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:1602
_ni_session_context::decoder_low_delay
int decoder_low_delay
Definition: ni_device_api.h:1594
_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:1074
NI_SET_CHANGE_PARAM_CRF
@ NI_SET_CHANGE_PARAM_CRF
Definition: ni_device_api.h:973
_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:2650
_ni_frame::sei_hdr_content_light_level_info_offset
unsigned int sei_hdr_content_light_level_info_offset
Definition: ni_device_api.h:2637
_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:2500
_ni_session_context::nb_rois
int nb_rois
Definition: ni_device_api.h:1581
_ni_frame::sar_width
uint16_t sar_width
Definition: ni_device_api.h:2687
_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:1418
_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:1430
SLICE_TYPE_P
@ SLICE_TYPE_P
Definition: ni_av_codec.c:46
_ni_custom_sei::size
uint32_t size
Definition: ni_device_api.h:1121
_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:1433
_ni_frame::aspect_ratio_idc
uint8_t aspect_ratio_idc
Definition: ni_device_api.h:2686
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:399
_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:974
_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:1420
_ni_dec_mastering_display_colour_volume_bytes
decoded payload format of HDR SEI mastering display colour volume
Definition: ni_device_api.h:1061
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:2267
_ni_vui_hrd
Definition: ni_device_api.h:654
_ni_session_context::ui8_mdcv_max_min_lum_data
uint8_t ui8_mdcv_max_min_lum_data[9]
Definition: ni_device_api.h:1431
_ni_rc_min_max_qp::minQpI
int32_t minQpI
Definition: ni_device_api.h:706
_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:1578
_ni_extended_dec_metadata
Definition: ni_device_api.h:721
_ni_xcoder_params::source_width
int source_width
Definition: ni_device_api.h:2723
_ni_frame::reconf_len
unsigned int reconf_len
Definition: ni_device_api.h:2655
cll_data
uint8_t cll_data[NI_MAX_SEI_DATA]
Definition: ni_quadra_enc_api.c:1546
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:2453
_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:1599
_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:1120
NI_HDR10P_SEI_HDR_H264_LEN
#define NI_HDR10P_SEI_HDR_H264_LEN
Definition: ni_device_api.h:463
_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:385
NI_CODEC_HW_NONE
@ NI_CODEC_HW_NONE
Definition: ni_device_api.h:939
NI_PIX_FMT_YUV420P
@ NI_PIX_FMT_YUV420P
Definition: ni_device_api.h:262
_ni_rc_min_max_qp
Definition: ni_device_api.h:704
_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:1506
_ni_session_context::ltr_to_set
ni_long_term_ref_t ltr_to_set
Definition: ni_device_api.h:1601
_ni_encoder_change_params_t::frameRateDenom
int32_t frameRateDenom
Definition: ni_device_api.h:1051
GOP_PRESET_BBBBBBBSP_8
@ GOP_PRESET_BBBBBBBSP_8
Definition: ni_av_codec.c:72
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:427
_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:701
ni_bs_writer_clear
void ni_bs_writer_clear(ni_bitstream_writer_t *stream)
clear and reset bitstream
Definition: ni_bitstream.c:300
_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:3531
_ni_session_context::av_rois
ni_region_of_interest_t * av_rois
Definition: ni_device_api.h:1580
_ni_frame::color_trc
uint8_t color_trc
Definition: ni_device_api.h:2683
NI_FRAME_AUX_DATA_CRF
@ NI_FRAME_AUX_DATA_CRF
Definition: ni_device_api.h:574
_ni_region_of_interest
Definition: ni_device_api.h:626
_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:1674
_ni_session_context::actual_video_width
uint32_t actual_video_width
Definition: ni_device_api.h:1553
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:2625
_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:987
_ni_custom_sei::data
uint8_t data[NI_MAX_CUSTOM_SEI_DATA]
Definition: ni_device_api.h:1122
_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:2689
_ni_region_of_interest::right
int right
Definition: ni_device_api.h:637
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:462
_ni_encoder_cfg_params::roi_enable
int roi_enable
Definition: ni_device_api.h:2257
_ni_encoder_cfg_params::intra_period
int intra_period
Definition: ni_device_api.h:2260
_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:2698
_ni_session_context::reconfig_slice_arg
int16_t reconfig_slice_arg
Definition: ni_device_api.h:1706
_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:1427
NI_INVALID_SEI_TYPE
#define NI_INVALID_SEI_TYPE
Definition: ni_defs.h:300
_ni_encoder_change_params_t::minQpPB
int32_t minQpPB
Definition: ni_device_api.h:1003
NI_FRAME_AUX_DATA_SLICE_ARG
@ NI_FRAME_AUX_DATA_SLICE_ARG
Definition: ni_device_api.h:590
_ni_encoder_cfg_params::gop_preset_index
int gop_preset_index
Definition: ni_device_api.h:2251
_ni_frame::sei_user_data_unreg_len
unsigned int sei_user_data_unreg_len
Definition: ni_device_api.h:2644
ni_pic_type_t
ni_pic_type_t
Definition: ni_device_api.h:382
_ni_xcoder_params::roi_demo_mode
int roi_demo_mode
Definition: ni_device_api.h:2730
_ni_encoder_cfg_params::intra_mb_refresh_mode
int intra_mb_refresh_mode
Definition: ni_device_api.h:2261
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:2629
_ni_encoder_change_params_t::aspectRatioHeight
uint16_t aspectRatioHeight
Definition: ni_device_api.h:1024
_ni_encoder_change_params_t::enable_option
uint32_t enable_option
Definition: ni_device_api.h:984
NI_RETCODE_INVALID_PARAM
@ NI_RETCODE_INVALID_PARAM
Definition: ni_defs.h:429
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:2671
_ni_session_context::bit_depth_factor
int bit_depth_factor
Definition: ni_device_api.h:1494
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:1686
_ni_encoder_change_params_t
This is a data structure for encoding parameters that have changed.
Definition: ni_device_api.h:982
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:471
_ni_frame::force_pic_qp
uint16_t force_pic_qp
Definition: ni_device_api.h:2659
NI_FRAME_AUX_DATA_HDR_PLUS
@ NI_FRAME_AUX_DATA_HDR_PLUS
Definition: ni_device_api.h:514
_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:622
_ni_encoder_cfg_params::crf
int crf
Definition: ni_device_api.h:2269
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:629
NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE
@ NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE
Definition: ni_device_api.h:586
_ni_xcoder_params::fps_number
uint32_t fps_number
Definition: ni_device_api.h:2718
NI_FRAME_AUX_DATA_VBV_MAX_RATE
@ NI_FRAME_AUX_DATA_VBV_MAX_RATE
Definition: ni_device_api.h:582
_ni_enc_quad_roi_custom_map::roiAbsQp_flag
uint8_t roiAbsQp_flag
Definition: ni_device_api.h:887
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:968
_ni_session_context::reconfig_intra_period
int reconfig_intra_period
Definition: ni_device_api.h:1704
NI_RETCODE_ERROR_MEM_ALOC
@ NI_RETCODE_ERROR_MEM_ALOC
Definition: ni_defs.h:431
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:425
NI_FRAME_AUX_DATA_MAX_MIN_QP
@ NI_FRAME_AUX_DATA_MAX_MIN_QP
Definition: ni_device_api.h:570
_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:661
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:1178
NI_FRAME_AUX_DATA_UDU_SEI
@ NI_FRAME_AUX_DATA_UDU_SEI
Definition: ni_device_api.h:525
NI_CC_SEI_HDR_H264_LEN
#define NI_CC_SEI_HDR_H264_LEN
Definition: ni_device_api.h:464
_ni_enc_mastering_display_colour_volume::white_point_y
uint16_t white_point_y
Definition: ni_device_api.h:1088
_ni_session_context::fw_rev
uint8_t fw_rev[8]
Definition: ni_device_api.h:1625
_ni_enc_mastering_display_colour_volume::display_primaries
uint16_t display_primaries[3][2]
Definition: ni_device_api.h:1086
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:858
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:4005
NI_RETCODE_PARAM_INVALID_VALUE
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition: ni_defs.h:437
_ni_encoder_change_params_t::colorPrimaries
uint8_t colorPrimaries
Definition: ni_device_api.h:1020
_ni_frame::sei_hdr_mastering_display_color_vol_offset
unsigned int sei_hdr_mastering_display_color_vol_offset
Definition: ni_device_api.h:2635
_ni_frame::sei_cc_offset
unsigned int sei_cc_offset
Definition: ni_device_api.h:2632
_ni_session_context::reconfig_vbv_buffer_size
int reconfig_vbv_buffer_size
Definition: ni_device_api.h:1688
_ni_session_context::framerate
ni_framerate_t framerate
Definition: ni_device_api.h:1604
_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:1038
GOP_PRESET_BSP_2
@ GOP_PRESET_BSP_2
Definition: ni_av_codec.c:64
udu_data
uint8_t udu_data[NI_MAX_SEI_DATA]
Definition: ni_quadra_enc_api.c:1548
_ni_rational
Definition: ni_device_api.h:598
_ni_long_term_ref
Definition: ni_device_api.h:683
NI_LOG_INFO
@ NI_LOG_INFO
Definition: ni_log.h:61
_ni_vui_hrd::colorDescPresent
int32_t colorDescPresent
Definition: ni_device_api.h:657
_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:1689
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:282
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:2728
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:308
_ni_encoder_change_params_t::colorSpace
uint8_t colorSpace
Definition: ni_device_api.h:1022
_ni_encoder_change_params_t::maxDeltaQp
int32_t maxDeltaQp
Definition: ni_device_api.h:1001
NI_MAX_CUSTOM_SEI_CNT
#define NI_MAX_CUSTOM_SEI_CNT
Definition: ni_defs.h:303
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:2627
_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:543
_ni_vui_hrd::colorTrc
int32_t colorTrc
Definition: ni_device_api.h:665
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:698
NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
@ NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
Definition: ni_defs.h:521
_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:2765
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:264
NI_SET_CHANGE_PARAM_SLICE_ARG
@ NI_SET_CHANGE_PARAM_SLICE_ARG
Definition: ni_device_api.h:959
_ni_frame::data_len
uint32_t data_len[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2664
NI_MAX_SLICE_SIZE
#define NI_MAX_SLICE_SIZE
Definition: ni_device_api.h:219
_ni_frame::extra_data_len
unsigned int extra_data_len
Definition: ni_device_api.h:2657
_ni_encoder_change_params_t::maxFrameSize
uint16_t maxFrameSize
Definition: ni_device_api.h:1041
_ni_encoder_cfg_params::intra_qp
int intra_qp
Definition: ni_device_api.h:2368
_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:1037
_ni_decoder_input_params_t::hwframes
int hwframes
Definition: ni_device_api.h:2499
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:1019
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:4045
NI_FRAME_AUX_DATA_FRAMERATE
@ NI_FRAME_AUX_DATA_FRAMERATE
Definition: ni_device_api.h:562
GOP_PRESET_B_1
@ GOP_PRESET_B_1
Definition: ni_av_codec.c:56
_ni_decoder_input_params_t
Definition: ni_device_api.h:2445
NI_RBSP_TRAILING_BITS_LEN
#define NI_RBSP_TRAILING_BITS_LEN
Definition: ni_device_api.h:466
NI_MEM_PAGE_ALIGNMENT
#define NI_MEM_PAGE_ALIGNMENT
Definition: ni_defs.h:251
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:502
_ni_frame::end_of_stream
uint32_t end_of_stream
Definition: ni_device_api.h:2608
_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:389
_ni_session_context::prev_size
int prev_size
Definition: ni_device_api.h:1507
_ni_session_context::enc_change_params
ni_encoder_change_params_t * enc_change_params
Definition: ni_device_api.h:1592
_ni_session_context::p_session_config
void * p_session_config
Definition: ni_device_api.h:1473
NI_CODEC_FORMAT_AV1
@ NI_CODEC_FORMAT_AV1
Definition: ni_device_api.h:915
_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:2641
_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:1014
_ni_custom_sei_set
Definition: ni_device_api.h:1125
cc_data
uint8_t cc_data[NI_MAX_SEI_DATA]
Definition: ni_quadra_enc_api.c:1547
_ni_region_of_interest::top
int top
Definition: ni_device_api.h:634
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:3065
_ni_session_data_io
Definition: ni_device_api.h:2866
_ni_enc_quad_roi_custom_map::ipcm_flag
uint8_t ipcm_flag
Definition: ni_device_api.h:891
_ni_decoder_input_params_t::svct_decoding_layer
int svct_decoding_layer
Definition: ni_device_api.h:2522
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:2897
_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:600
NI_PIX_FMT_YUV420P10LE
@ NI_PIX_FMT_YUV420P10LE
Definition: ni_device_api.h:263
_ni_enc_mastering_display_colour_volume
encoded payload format of HDR SEI mastering display colour volume
Definition: ni_device_api.h:1084
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:96
_ni_frame::vui_time_scale
uint32_t vui_time_scale
Definition: ni_device_api.h:2690
NI_FRAME_AUX_DATA_REGIONS_OF_INTEREST
@ NI_FRAME_AUX_DATA_REGIONS_OF_INTEREST
Definition: ni_device_api.h:519
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:310
_ni_encoder_change_params_t::frameRateNum
int32_t frameRateNum
Definition: ni_device_api.h:1050
_ni_encoder_cfg_params
Definition: ni_device_api.h:2060
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:1428
_ni_frame::force_key_frame
int force_key_frame
Definition: ni_device_api.h:2624
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:2879
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:3289
_ni_aux_data::data
void * data
Definition: ni_device_api.h:621
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:2785
_ni_packet
Definition: ni_device_api.h:2825
_ni_session_context::frame_num
uint64_t frame_num
Definition: ni_device_api.h:1531
_ni_frame::sei_cc_len
unsigned int sei_cc_len
Definition: ni_device_api.h:2633
_ni_session_context::roi_map
ni_enc_quad_roi_custom_map * roi_map
Definition: ni_device_api.h:1582
NI_MAX_CUSTOM_SEI_DATA
#define NI_MAX_CUSTOM_SEI_DATA
Definition: ni_device_api.h:428
_ni_custom_sei::type
uint8_t type
Definition: ni_device_api.h:1119
NIALIGN
#define NIALIGN(x, a)
Definition: ni_quadra_enc_api.h:54
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:2649
_ni_session_context::force_idr_intra_offset
uint32_t force_idr_intra_offset
Definition: ni_device_api.h:1648
_ni_frame::p_data
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2663
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:2653
_ni_decoder_input_params_t::enable_all_sei_passthru
bool enable_all_sei_passthru
Definition: ni_device_api.h:2530
_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:1605
_ni_frame::sei_hdr_plus_offset
unsigned int sei_hdr_plus_offset
Definition: ni_device_api.h:2640
_ni_session_context::hw_action
int hw_action
Definition: ni_device_api.h:1609
_ni_session_context
Definition: ni_device_api.h:1408
_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:1417
_ni_rc_min_max_qp::minQpPB
int32_t minQpPB
Definition: ni_device_api.h:709
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:15702
NI_PIX_FMT_P010LE
@ NI_PIX_FMT_P010LE
Definition: ni_device_api.h:265
_ni_region_of_interest::qoffset
ni_rational_t qoffset
Definition: ni_device_api.h:642
NI_MAX_NUM_DATA_POINTERS
#define NI_MAX_NUM_DATA_POINTERS
Definition: ni_defs.h:232
_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:2601
_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:266
_ni_encoder_change_params_t::maxQpPB
int32_t maxQpPB
Definition: ni_device_api.h:1004
_ni_frame::color_space
uint8_t color_space
Definition: ni_device_api.h:2684
_ni_session_context::roi_len
uint32_t roi_len
Definition: ni_device_api.h:1496
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:3485
NI_SET_CHANGE_PARAM_MAX_FRAME_SIZE
@ NI_SET_CHANGE_PARAM_MAX_FRAME_SIZE
Definition: ni_device_api.h:972
NI_PIX_FMT_ABGR
@ NI_PIX_FMT_ABGR
Definition: ni_device_api.h:269
_ni_frame::color_primaries
uint8_t color_primaries
Definition: ni_device_api.h:2682
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:268
_ni_xcoder_params
Definition: ni_device_api.h:2713
_ni_frame::sei_hdr_content_light_level_info_len
unsigned int sei_hdr_content_light_level_info_len
Definition: ni_device_api.h:2638
_ni_enc_mastering_display_colour_volume::white_point_x
uint16_t white_point_x
Definition: ni_device_api.h:1087
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:2636
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:2685
_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:1044
_ni_encoder_cfg_params::slice_mode
int slice_mode
Definition: ni_device_api.h:2357
_ni_session_context::codec_format
uint32_t codec_format
Definition: ni_device_api.h:1486
_ni_session_context::max_frame_size
int32_t max_frame_size
Definition: ni_device_api.h:1655
NI_MAX_NUM_OF_DECODER_OUTPUTS
#define NI_MAX_NUM_OF_DECODER_OUTPUTS
Definition: ni_defs.h:243
_ni_rc_min_max_qp::maxQpPB
int32_t maxQpPB
Definition: ni_device_api.h:710
_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:1419
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:266
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:311
_ni_encoder_cfg_params::crfFloat
float crfFloat
Definition: ni_device_api.h:2410
mdcv_data
uint8_t mdcv_data[NI_MAX_SEI_DATA]
Definition: ni_quadra_enc_api.c:1545
NI_CC_SEI_HDR_HEVC_LEN
#define NI_CC_SEI_HDR_HEVC_LEN
Definition: ni_device_api.h:461
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:975
_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:2688
_ni_frame::sei_alt_transfer_characteristics_offset
unsigned int sei_alt_transfer_characteristics_offset
Definition: ni_device_api.h:2646
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:2944
_ni_decoder_input_params_t::enable_out2
int enable_out2
Definition: ni_device_api.h:2501
NI_FRAME_AUX_DATA_LTR_INTERVAL
@ NI_FRAME_AUX_DATA_LTR_INTERVAL
Definition: ni_device_api.h:553
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:317
_ni_encoder_change_params_t::ltrInterval
int32_t ltrInterval
Definition: ni_device_api.h:1047
_ni_session_context::reconfig_crf
int reconfig_crf
Definition: ni_device_api.h:1685
NI_SET_CHANGE_PARAM_LTR_INTERVAL
@ NI_SET_CHANGE_PARAM_LTR_INTERVAL
Definition: ni_device_api.h:970
_ni_encoder_change_params_t::minQpI
int32_t minQpI
Definition: ni_device_api.h:998
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:2643
_ni_timecode
Definition: ni_av_codec.h:448
_ni_frame::video_height
uint32_t video_height
Definition: ni_device_api.h:2611
_ni_vui_hrd::colorSpace
int32_t colorSpace
Definition: ni_device_api.h:668
_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:479
_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:2521
_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:1551
_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:548
NI_MAX_SEI_DATA
#define NI_MAX_SEI_DATA
Definition: ni_device_api.h:426
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:1117
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:2300
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:317
_ni_session_context::session_run_state
ni_session_run_state_t session_run_state
Definition: ni_device_api.h:1547
_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:687
_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:465
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:883
NI_SET_CHANGE_PARAM_RC_FRAMERATE
@ NI_SET_CHANGE_PARAM_RC_FRAMERATE
Definition: ni_device_api.h:971
_ni_xcoder_params::cacheRoi
int cacheRoi
Definition: ni_device_api.h:2747
_ni_encoder_change_params_t::maxQpI
int32_t maxQpI
Definition: ni_device_api.h:999
_ni_region_of_interest::bottom
int bottom
Definition: ni_device_api.h:635
_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:505
NI_MIN_HEIGHT
#define NI_MIN_HEIGHT
Definition: ni_device_api.h:126
NI_RETCODE_FAILURE
@ NI_RETCODE_FAILURE
Definition: ni_defs.h:428
_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:1033
NI_CUSTOM_SEI_LOC_BEFORE_VCL
@ NI_CUSTOM_SEI_LOC_BEFORE_VCL
Definition: ni_device_api.h:1110
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:2242
_ni_rational::den
int den
Definition: ni_device_api.h:601
_ni_frame::start_of_stream
uint32_t start_of_stream
Definition: ni_device_api.h:2609
_ni_encoder_change_params_t::colorTrc
uint8_t colorTrc
Definition: ni_device_api.h:1021
NI_SET_CHANGE_PARAM_RC_MIN_MAX_QP
@ NI_SET_CHANGE_PARAM_RC_MIN_MAX_QP
Definition: ni_device_api.h:957
_ni_vui_hrd::videoFullRange
int32_t videoFullRange
Definition: ni_device_api.h:679
_ni_vui_hrd::aspectRatioHeight
int32_t aspectRatioHeight
Definition: ni_device_api.h:675
NI_SET_CHANGE_PARAM_INVALID_REF_FRAME
@ NI_SET_CHANGE_PARAM_INVALID_REF_FRAME
Definition: ni_device_api.h:969
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:1111
_ni_session_context::last_framerate
ni_framerate_t last_framerate
Definition: ni_device_api.h:1675
_ni_session_context::ltr_frame_ref_invalid
int32_t ltr_frame_ref_invalid
Definition: ni_device_api.h:1603
_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:2672
_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:1031
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:1128
_ni_frame::p_metadata_buffer
uint8_t * p_metadata_buffer
Definition: ni_device_api.h:2695
_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:707
_ni_custom_sei_set::custom_sei
ni_custom_sei_t custom_sei[NI_MAX_CUSTOM_SEI_CNT]
Definition: ni_device_api.h:1127
_ni_encoder_cfg_params::lookAheadDepth
int lookAheadDepth
Definition: ni_device_api.h:2267
GOP_PRESET_I_1
@ GOP_PRESET_I_1
Definition: ni_av_codec.c:54
_ni_encoder_change_params_t::vbvBufferSize
int32_t vbvBufferSize
Definition: ni_device_api.h:994
_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:578
_ni_frame::sei_alt_transfer_characteristics_len
unsigned int sei_alt_transfer_characteristics_len
Definition: ni_device_api.h:2647
NI_FRAME_AUX_DATA_CONTENT_LIGHT_LEVEL
@ NI_FRAME_AUX_DATA_CONTENT_LIGHT_LEVEL
Definition: ni_device_api.h:509
_ni_xcoder_params::low_delay_mode
int low_delay_mode
Definition: ni_device_api.h:2733
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:361
_ni_bitstream_reader_t
Definition: ni_bitstream.h:119
NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_H264
Definition: ni_device_api.h:911
_ni_frame::use_cur_src_as_long_term_pic
uint8_t use_cur_src_as_long_term_pic
Definition: ni_device_api.h:2621
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:558
_ni_frame::video_width
uint32_t video_width
Definition: ni_device_api.h:2610
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:2729
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:1426
_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:2265
hdrp_data
uint8_t hdrp_data[NI_MAX_SEI_DATA]
Definition: ni_quadra_enc_api.c:1549
_ni_session_context::pixel_format
int pixel_format
Definition: ni_device_api.h:1616
_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:1422
_ni_aux_data
Definition: ni_device_api.h:618
NI_LOG_DEBUG
@ NI_LOG_DEBUG
Definition: ni_log.h:62
_ni_framerate
Definition: ni_device_api.h:695
_ni_vui_hrd::aspectRatioWidth
int32_t aspectRatioWidth
Definition: ni_device_api.h:672
_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:1023
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:539
_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:2766
_ni_enc_quad_roi_custom_map::qp_info
uint8_t qp_info
Definition: ni_device_api.h:889
_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:708
_ni_session_context::roi_avg_qp
uint32_t roi_avg_qp
Definition: ni_device_api.h:1497
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:1432
_ni_encoder_cfg_params::forced_header_enable
int forced_header_enable
Definition: ni_device_api.h:2258
NI_FRAME_AUX_DATA_BITRATE
@ NI_FRAME_AUX_DATA_BITRATE
Definition: ni_device_api.h:535
_ni_encoder_change_params_t::videoFullRange
uint8_t videoFullRange
Definition: ni_device_api.h:1025
NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_H265
Definition: ni_device_api.h:912
_ni_frame::use_long_term_ref
uint8_t use_long_term_ref
Definition: ni_device_api.h:2622