libxcoder  5.3.1
ni_encode_utils.c
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * Copyright (C) 2022 NETINT Technologies
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18  * SOFTWARE.
19  *
20  ******************************************************************************/
21 
22 /*!*****************************************************************************
23  * \file encode_utils.c
24  *
25  * \brief Video encoding utility functions shared by Libxcoder API examples
26  ******************************************************************************/
27 
28 #include "ni_generic_utils.h"
29 #include "ni_encode_utils.h"
30 #include "ni_log.h"
31 #include "ni_av_codec.h"
32 #include "ni_util.h"
33 
34 /*!*****************************************************************************
35  * \brief Set up hard coded demo ROI map
36  *
37  * \param
38  *
39  * \return none
40  ******************************************************************************/
42 {
43  ni_xcoder_params_t *p_param =
44  (ni_xcoder_params_t *)(p_enc_ctx->p_session_config);
45  uint32_t i, j, sumQp = 0;
46  uint32_t mbWidth, mbHeight, numMbs;
47  // mode 1: Set QP for center 1/3 of picture to highest - lowest quality
48  // the rest to lowest - highest quality;
49  // mode non-1: reverse of mode 1
50  int importanceLevelCentre = p_param->roi_demo_mode == 1 ? 40 : 10;
51  int importanceLevelRest = p_param->roi_demo_mode == 1 ? 10 : 40;
52  int32_t width, height;
53 
54  if (!p_enc_ctx->roi_map)
55  {
56  p_enc_ctx->roi_map =
57  (ni_enc_quad_roi_custom_map *)calloc(1, p_enc_ctx->roi_len);
58  }
59  if (!p_enc_ctx->roi_map)
60  {
61  return;
62  }
63  uint32_t roiMapBlockUnitSize = 64; // HEVC
64  uint32_t max_cu_size = 64; // HEVC
65  if (NI_CODEC_FORMAT_H264 == p_enc_ctx->codec_format)
66  {
67  max_cu_size = 16;
68  roiMapBlockUnitSize = 16;
69  }
70 
71  width = p_param->source_width;
72  height = p_param->source_height;
73  // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
74  if (NI_CODEC_FORMAT_AV1 == p_enc_ctx->codec_format)
75  {
76  width = (width / 8) * 8;
77  height = (height / 8) * 8;
78  }
79 
80  mbWidth =
81  ((width + max_cu_size - 1) & (~(max_cu_size - 1))) /
82  roiMapBlockUnitSize;
83  mbHeight =
84  ((height + max_cu_size - 1) & (~(max_cu_size - 1))) /
85  roiMapBlockUnitSize;
86  numMbs = mbWidth * mbHeight;
87 
88  // copy roi MBs QPs into custom map
89  bool bIsCenter;
90  // number of qp info (8x8) per mb or ctb
91  uint32_t entryPerMb = (roiMapBlockUnitSize / 8) * (roiMapBlockUnitSize / 8);
92 
93  for (i = 0; i < numMbs; i++)
94  {
95  if ((i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3))
96  bIsCenter = 1;
97  else
98  bIsCenter = 0;
99 
100  for (j = 0; j < entryPerMb; j++)
101  {
102  /*
103  g_quad_roi_map[i*4+j].field.skip_flag = 0; // don't force
104  skip mode g_quad_roi_map[i*4+j].field.roiAbsQp_flag = 1; //
105  absolute QP g_quad_roi_map[i*4+j].field.qp_info = bIsCenter
106  ? importanceLevelCentre : importanceLevelRest;
107  */
108  p_enc_ctx->roi_map[i * entryPerMb + j].field.ipcm_flag =
109  0; // don't force skip mode
110  p_enc_ctx->roi_map[i * entryPerMb + j].field.roiAbsQp_flag =
111  1; // absolute QP
112  p_enc_ctx->roi_map[i * entryPerMb + j].field.qp_info =
113  bIsCenter ? importanceLevelCentre : importanceLevelRest;
114  }
115  sumQp += p_enc_ctx->roi_map[i * entryPerMb].field.qp_info;
116  }
117  p_enc_ctx->roi_avg_qp =
118  // NOLINTNEXTLINE(clang-analyzer-core.DivideZero)
119  (sumQp + (numMbs >> 1)) / numMbs; // round off
120 }
121 
122 // convert various reconfig and demo modes (stored in encoder configuration) to
123 // aux data and store them in frame
125 {
126  ni_xcoder_params_t *api_param =
127  (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
128  ni_aux_data_t *aux_data = NULL;
129 
130  switch (api_param->reconf_demo_mode)
131  {
133  if (p_enc_ctx->frame_num ==
134  api_param->reconf_hash[p_ctx->reconfig_count][0])
135  {
136  aux_data = ni_frame_new_aux_data(
137  frame, NI_FRAME_AUX_DATA_BITRATE, sizeof(int32_t));
138  if (!aux_data)
139  {
141  "Error %s(): no mem for reconf BR aux_data\n",
142  __func__);
143  return;
144  }
145  *((int32_t *)aux_data->data) =
146  api_param->reconf_hash[p_ctx->reconfig_count][1];
147  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu reconfig BR %d by frame aux data\n",
148  __func__, p_enc_ctx->frame_num,
149  api_param->reconf_hash[p_ctx->reconfig_count][1]);
150 
151  p_ctx->reconfig_count++;
152  }
153  break;
155  if (p_enc_ctx->frame_num ==
156  api_param->reconf_hash[p_ctx->reconfig_count][0])
157  {
158  aux_data = ni_frame_new_aux_data(
159  frame, NI_FRAME_AUX_DATA_INTRAPRD, sizeof(int32_t));
160  if (!aux_data)
161  {
162  return;
163  }
164  int32_t intraprd = *((int32_t *)aux_data->data) =
165  api_param->reconf_hash[p_ctx->reconfig_count][1];
167  "xcoder_send_frame: frame #%lu reconf "
168  "intraPeriod %d\n",
169  p_enc_ctx->frame_num,
170  intraprd);
171  p_ctx->reconfig_count++;
172  }
173  break;
175  if (p_enc_ctx->frame_num ==
176  api_param->reconf_hash[p_ctx->reconfig_count][0])
177  {
178  p_enc_ctx->enc_change_params->enable_option |=
180  p_enc_ctx->enc_change_params->colorDescPresent =
181  api_param->reconf_hash[p_ctx->reconfig_count][1];
182  p_enc_ctx->enc_change_params->colorPrimaries =
183  api_param->reconf_hash[p_ctx->reconfig_count][2];
184  p_enc_ctx->enc_change_params->colorTrc =
185  api_param->reconf_hash[p_ctx->reconfig_count][3];
186  p_enc_ctx->enc_change_params->colorSpace =
187  api_param->reconf_hash[p_ctx->reconfig_count][4];
188  p_enc_ctx->enc_change_params->aspectRatioWidth =
189  api_param->reconf_hash[p_ctx->reconfig_count][5];
191  api_param->reconf_hash[p_ctx->reconfig_count][6];
192  p_enc_ctx->enc_change_params->videoFullRange =
193  api_param->reconf_hash[p_ctx->reconfig_count][7];
194 
195  // frame reconf_len needs to be set here
196  frame->reconf_len = sizeof(ni_encoder_change_params_t);
197  p_ctx->reconfig_count++;
198  }
199  break;
201  // the reconf file data line format for this is:
202  // <frame-number>:useCurSrcAsLongtermPic,useLongtermRef where
203  // values will stay the same on every frame until changed.
204  if (p_enc_ctx->frame_num ==
205  api_param->reconf_hash[p_ctx->reconfig_count][0])
206  {
207  aux_data = ni_frame_new_aux_data(
209  sizeof(ni_long_term_ref_t));
210  if (!aux_data)
211  {
213  "Error %s(): no mem for reconf LTR aux_data\n",
214  __func__);
215  return;
216  }
217  ni_long_term_ref_t *ltr = (ni_long_term_ref_t *)aux_data->data;
219  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][1];
220  ltr->use_long_term_ref =
221  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][2];
222 
224  "%s(): frame #%lu reconf LTR "
225  "use_cur_src_as_long_term_pic %u use_long_term_ref "
226  "%u\n",
227  __func__, p_enc_ctx->frame_num,
229 
230  p_ctx->reconfig_count++;
231  }
232  break;
235  if (p_enc_ctx->frame_num ==
236  api_param->reconf_hash[p_ctx->reconfig_count][0])
237  {
238  aux_data = ni_frame_new_aux_data(
240  if (!aux_data) {
242  "Error %s(): no mem for reconf max&min QP aux_data\n",
243  __func__);
244  return;
245  }
246  ni_rc_min_max_qp *qp_info = (ni_rc_min_max_qp *)aux_data->data;
247  qp_info->minQpI = api_param->reconf_hash[p_ctx->reconfig_count][1];
248  qp_info->maxQpI = api_param->reconf_hash[p_ctx->reconfig_count][2];
249  qp_info->maxDeltaQp = api_param->reconf_hash[p_ctx->reconfig_count][3];
250  qp_info->minQpPB = api_param->reconf_hash[p_ctx->reconfig_count][4];
251  qp_info->maxQpPB = api_param->reconf_hash[p_ctx->reconfig_count][5];
252 
253  p_ctx->reconfig_count++;
254  }
255  break;
257  if (p_enc_ctx->frame_num ==
258  api_param->reconf_hash[p_ctx->reconfig_count][0])
259  {
260  aux_data = ni_frame_new_aux_data(
261  frame, NI_FRAME_AUX_DATA_LTR_INTERVAL, sizeof(int32_t));
262  if (!aux_data)
263  {
264  ni_log(NI_LOG_ERROR, "Error %s(): no mem for reconf LTR interval "
265  "aux_data\n",
266  __func__);
267  return;
268  }
269  *((int32_t *)aux_data->data) =
270  api_param->reconf_hash[p_ctx->reconfig_count][1];
271  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu reconf LTR interval %d\n",
272  __func__, p_enc_ctx->frame_num,
273  *((int32_t *)aux_data->data));
274 
275  p_ctx->reconfig_count++;
276  }
277  break;
279  if (p_enc_ctx->frame_num ==
280  api_param->reconf_hash[p_ctx->reconfig_count][0])
281  {
282  aux_data = ni_frame_new_aux_data(
284  sizeof(int32_t));
285  if (!aux_data)
286  {
287  ni_log(NI_LOG_ERROR, "Error %s(): no mem for reconf invalid ref "
288  "frame aux_data\n",
289  __func__);
290  return;
291  }
292  *((int32_t *)aux_data->data) =
293  api_param->reconf_hash[p_ctx->reconfig_count][1];
294  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu reconf invalid ref frame %d\n",
295  __func__, p_enc_ctx->frame_num,
296  *((int32_t *)aux_data->data));
297 
298  p_ctx->reconfig_count++;
299  }
300  break;
302  if (p_enc_ctx->frame_num ==
303  api_param->reconf_hash[p_ctx->reconfig_count][0])
304  {
305  aux_data = ni_frame_new_aux_data(
307  if (!aux_data)
308  {
310  "Error %s(): no mem for reconf framerate aux_data\n",
311  __func__);
312  return;
313  }
314  ni_framerate_t *framerate = (ni_framerate_t *)aux_data->data;
315  framerate->framerate_num =
316  (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][1];
317  framerate->framerate_denom =
318  (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][2];
319 
321  "%s(): frame #%lu reconfig framerate (%d/%d) by frame aux data\n",
322  __func__, p_enc_ctx->frame_num, framerate->framerate_num,
323  framerate->framerate_denom);
324 
325  p_ctx->reconfig_count++;
326  }
327  break;
329  if (p_enc_ctx->frame_num ==
330  api_param->reconf_hash[p_ctx->reconfig_count][0])
331  {
332  aux_data = ni_frame_new_aux_data(
333  frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
334  if (!aux_data)
335  {
337  "Error %s(): no mem for reconf maxFrameSize aux_data\n",
338  __func__);
339  return;
340  }
341  *((int32_t *)aux_data->data) =
342  api_param->reconf_hash[p_ctx->reconfig_count][1];
343  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu reconfig maxFrameSize %d by frame aux data\n",
344  __func__, p_enc_ctx->frame_num,
345  api_param->reconf_hash[p_ctx->reconfig_count][1]);
346 
347  p_ctx->reconfig_count++;
348  }
349  break;
351  if (p_enc_ctx->frame_num ==
352  api_param->reconf_hash[p_ctx->reconfig_count][0])
353  {
354  aux_data = ni_frame_new_aux_data(
355  frame, NI_FRAME_AUX_DATA_CRF, sizeof(int32_t));
356  if (!aux_data) {
358  "Error %s(): no mem for reconf crf aux_data\n",
359  __func__);
360  return;
361  }
362  *((int32_t *)aux_data->data) =
363  api_param->reconf_hash[p_ctx->reconfig_count][1];
364  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu reconfig crf %d by frame aux data\n",
365  __func__, p_enc_ctx->frame_num,
366  api_param->reconf_hash[p_ctx->reconfig_count][1]);
367 
368  p_ctx->reconfig_count++;
369  }
370  break;
372  if (p_enc_ctx->frame_num ==
373  api_param->reconf_hash[p_ctx->reconfig_count][0])
374  {
375  aux_data = ni_frame_new_aux_data(
376  frame, NI_FRAME_AUX_DATA_CRF_FLOAT, sizeof(float));
377  if (!aux_data) {
379  "Error %s(): no mem for reconf crf aux_data\n",
380  __func__);
381  return;
382  }
383  float crf = (float)(api_param->reconf_hash[p_ctx->reconfig_count][1] +
384  (float)api_param->reconf_hash[p_ctx->reconfig_count][2] / 100.0);
385  *((float *)aux_data->data) = crf;
387  "%s(): frame #%lu reconfig float type crf %f by frame "
388  "aux data\n", __func__, p_enc_ctx->frame_num, crf);
389  p_ctx->reconfig_count++;
390  }
391  break;
392 
394  if (p_enc_ctx->frame_num ==
395  api_param->reconf_hash[p_ctx->reconfig_count][0])
396  {
397  aux_data = ni_frame_new_aux_data(
398  frame, NI_FRAME_AUX_DATA_VBV_MAX_RATE, sizeof(int32_t));
399  if (!aux_data) {
401  "Error %s(): no mem for reconf vbfMaxRate aux_data\n",
402  __func__);
403  return;
404  }
405  *((int32_t *)aux_data->data) =
406  api_param->reconf_hash[p_ctx->reconfig_count][1];
407  aux_data = ni_frame_new_aux_data(
408  frame, NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE, sizeof(int32_t));
409  if (!aux_data) {
411  "Error %s(): no mem for reconf vbvBufferSize aux_data\n",
412  __func__);
413  return;
414  }
415  *((int32_t *)aux_data->data) =
416  api_param->reconf_hash[p_ctx->reconfig_count][2];
418  "%s(): frame #%lu reconfig vbfMaxRate %d vbvBufferSize "
419  "%d by frame aux data\n",
420  __func__, p_enc_ctx->frame_num,
421  api_param->reconf_hash[p_ctx->reconfig_count][1],
422  api_param->reconf_hash[p_ctx->reconfig_count][2]);
423 
424  p_ctx->reconfig_count++;
425  }
426  break;
428  if (p_enc_ctx->frame_num ==
429  api_param->reconf_hash[p_ctx->reconfig_count][0]) {
430  int maxFrameSizeRatio = api_param->reconf_hash[p_ctx->reconfig_count][1];
431  if (maxFrameSizeRatio < 1) {
432  ni_log(NI_LOG_ERROR, "maxFrameSizeRatio %d cannot < 1\n",
433  maxFrameSizeRatio);
434  return;
435  }
436  aux_data = ni_frame_new_aux_data(
437  frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
438  if (!aux_data) {
440  "Error %s(): no mem for reconf maxFrameSizeRatio aux_data\n",
441  __func__);
442  return;
443  }
444 
445  int32_t bitrate, framerate_num, framerate_denom;
446  uint32_t min_maxFrameSize, maxFrameSize;
447  bitrate = (p_enc_ctx->target_bitrate > 0) ? p_enc_ctx->target_bitrate : api_param->bitrate;
448 
449  if ((p_enc_ctx->framerate.framerate_num > 0) && (p_enc_ctx->framerate.framerate_denom > 0))
450  {
451  framerate_num = p_enc_ctx->framerate.framerate_num;
452  framerate_denom = p_enc_ctx->framerate.framerate_denom;
453  }
454  else
455  {
456  framerate_num = (int32_t) api_param->fps_number;
457  framerate_denom = (int32_t) api_param->fps_denominator;
458  }
459 
460  min_maxFrameSize = ((uint32_t)bitrate / framerate_num * framerate_denom) / 8;
461  maxFrameSize = min_maxFrameSize * maxFrameSizeRatio > NI_MAX_FRAME_SIZE ?
462  NI_MAX_FRAME_SIZE : min_maxFrameSize * maxFrameSizeRatio;
463  *((int32_t *)aux_data->data) = maxFrameSize;
465  "xcoder_send_frame: frame #%lu reconf "
466  "maxFrameSizeRatio %d maxFrameSize %d\n",
467  p_enc_ctx->frame_num, maxFrameSizeRatio, maxFrameSize);
468 
469  p_ctx->reconfig_count++;
470  }
471  break;
473  if (p_enc_ctx->frame_num ==
474  api_param->reconf_hash[p_ctx->reconfig_count][0]) {
475  aux_data = ni_frame_new_aux_data(
476  frame, NI_FRAME_AUX_DATA_SLICE_ARG, sizeof(int16_t));
477  if (!aux_data) {
479  "Error %s(): no mem for reconf sliceArg aux_data\n",
480  __func__);
481  return;
482  }
483  *((int16_t *)aux_data->data) =
484  api_param->reconf_hash[p_ctx->reconfig_count][1];
485  ni_log2(p_enc_ctx, NI_LOG_TRACE,
486  "xcoder_send_frame: frame #%lu reconf "
487  "sliceArg %d\n",
488  p_enc_ctx->frame_num,
489  api_param->reconf_hash[p_ctx->reconfig_count][1]);
490 
491  p_ctx->reconfig_count++;
492  }
493  break;
494 
496  if (p_enc_ctx->frame_num ==
497  api_param->reconf_hash[p_ctx->reconfig_count][0])
498  {
499  ni_force_idr_frame_type(p_enc_ctx);
500  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu force IDR frame\n", __func__,
501  p_enc_ctx->frame_num);
502  p_ctx->reconfig_count++;
503  }
504  break;
506  if (p_enc_ctx->frame_num ==
507  api_param->reconf_hash[p_ctx->reconfig_count][0])
508  {
509  ni_reconfig_bitrate(p_enc_ctx,
510  api_param->reconf_hash[p_ctx->reconfig_count][1]);
511  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API reconfig BR %d\n",
512  __func__, p_enc_ctx->frame_num,
513  api_param->reconf_hash[p_ctx->reconfig_count][1]);
514  p_ctx->reconfig_count++;
515  }
516  break;
518  if (p_enc_ctx->frame_num ==
519  api_param->reconf_hash[p_ctx->reconfig_count][0]) {
520  int32_t intraprd =
521  api_param->reconf_hash[p_ctx->reconfig_count][1];
522  ni_reconfig_intraprd(p_enc_ctx, intraprd);
524  "xcoder_send_frame: frame #%lu API reconfig intraPeriod %d\n",
525  p_enc_ctx->frame_num,
526  intraprd);
527 
528  p_ctx->reconfig_count++;
529  }
530  break;
532  if (p_enc_ctx->frame_num ==
533  api_param->reconf_hash[p_ctx->reconfig_count][0])
534  {
535  ni_vui_hrd_t vui;
536  vui.colorDescPresent =
537  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][1];
538  vui.colorPrimaries =
539  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][2];
540  vui.colorTrc =
541  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][3];
542  vui.colorSpace =
543  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][4];
544  vui.aspectRatioWidth =
545  (uint16_t)api_param->reconf_hash[p_ctx->reconfig_count][5];
546  vui.aspectRatioHeight =
547  (uint16_t)api_param->reconf_hash[p_ctx->reconfig_count][6];
548  vui.videoFullRange =
549  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][7];
550 
551  ni_reconfig_vui(p_enc_ctx, &vui);
552  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API reconfig VUI HRD "
553  "colorDescPresent %d colorPrimaries %d "
554  "colorTrc %d colorSpace %d aspectRatioWidth %d "
555  "aspectRatioHeight %d videoFullRange %d\n",
556  __func__, p_enc_ctx->frame_num,
557  api_param->reconf_hash[p_ctx->reconfig_count][1],
558  api_param->reconf_hash[p_ctx->reconfig_count][2],
559  api_param->reconf_hash[p_ctx->reconfig_count][3],
560  api_param->reconf_hash[p_ctx->reconfig_count][4],
561  api_param->reconf_hash[p_ctx->reconfig_count][5],
562  api_param->reconf_hash[p_ctx->reconfig_count][6],
563  api_param->reconf_hash[p_ctx->reconfig_count][7]);
564  p_ctx->reconfig_count++;
565  }
566  break;
568  if (p_enc_ctx->frame_num ==
569  api_param->reconf_hash[p_ctx->reconfig_count][0])
570  {
571  ni_long_term_ref_t ltr;
573  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][1];
574  ltr.use_long_term_ref =
575  (uint8_t)api_param->reconf_hash[p_ctx->reconfig_count][2];
576 
577  ni_set_ltr(p_enc_ctx, &ltr);
578  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API set LTR\n", __func__,
579  p_enc_ctx->frame_num);
580  p_ctx->reconfig_count++;
581  }
582  break;
585  if (p_enc_ctx->frame_num ==
586  api_param->reconf_hash[p_ctx->reconfig_count][0])
587  {
588  ni_rc_min_max_qp qp_info;
589  qp_info.minQpI = (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][1];
590  qp_info.maxQpI = (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][2];
591  qp_info.maxDeltaQp = (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][3];
592  qp_info.minQpPB = (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][4];
593  qp_info.maxQpPB = (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][5];
594  ni_reconfig_min_max_qp(p_enc_ctx, &qp_info);
596  "%s(): frame %llu minQpI %d maxQpI %d maxDeltaQp %d minQpPB %d maxQpPB %d\n",
597  __func__, p_enc_ctx->frame_num,
598  qp_info.minQpI, qp_info.maxQpI, qp_info.maxDeltaQp, qp_info.minQpPB, qp_info.maxQpPB);
599  p_ctx->reconfig_count++;
600  }
601  break;
603  if (p_enc_ctx->frame_num ==
604  api_param->reconf_hash[p_ctx->reconfig_count][0])
605  {
606  ni_set_ltr_interval(p_enc_ctx,
607  api_param->reconf_hash[p_ctx->reconfig_count][1]);
608  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API set LTR interval %d\n",
609  __func__, p_enc_ctx->frame_num,
610  api_param->reconf_hash[p_ctx->reconfig_count][1]);
611  p_ctx->reconfig_count++;
612  }
613  break;
615  if (p_enc_ctx->frame_num ==
616  api_param->reconf_hash[p_ctx->reconfig_count][0])
617  {
619  p_enc_ctx, api_param->reconf_hash[p_ctx->reconfig_count][1]);
620  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API set frame ref invalid "
621  "%d\n",
622  __func__, p_enc_ctx->frame_num,
623  api_param->reconf_hash[p_ctx->reconfig_count][1]);
624  p_ctx->reconfig_count++;
625  }
626  break;
628  if (p_enc_ctx->frame_num ==
629  api_param->reconf_hash[p_ctx->reconfig_count][0])
630  {
631  ni_framerate_t framerate;
632  framerate.framerate_num =
633  (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][1];
634  framerate.framerate_denom =
635  (int32_t)api_param->reconf_hash[p_ctx->reconfig_count][2];
636  ni_reconfig_framerate(p_enc_ctx, &framerate);
638  "%s(): frame #%lu API reconfig framerate (%d/%d)\n",
639  __func__, p_enc_ctx->frame_num,
640  api_param->reconf_hash[p_ctx->reconfig_count][1],
641  api_param->reconf_hash[p_ctx->reconfig_count][2]);
642  p_ctx->reconfig_count++;
643  }
644  break;
646  if (p_enc_ctx->frame_num ==
647  api_param->reconf_hash[p_ctx->reconfig_count][0])
648  {
649  ni_reconfig_max_frame_size(p_enc_ctx,
650  api_param->reconf_hash[p_ctx->reconfig_count][1]);
651  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API reconfig maxFrameSize %d\n",
652  __func__, p_enc_ctx->frame_num,
653  api_param->reconf_hash[p_ctx->reconfig_count][1]);
654  p_ctx->reconfig_count++;
655  }
656  break;
657  case XCODER_TEST_CRF_API:
658  if (p_enc_ctx->frame_num ==
659  api_param->reconf_hash[p_ctx->reconfig_count][0])
660  {
661  ni_reconfig_crf(p_enc_ctx,
662  api_param->reconf_hash[p_ctx->reconfig_count][1]);
663  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API reconfig crf %d\n",
664  __func__, p_enc_ctx->frame_num,
665  api_param->reconf_hash[p_ctx->reconfig_count][1]);
666  p_ctx->reconfig_count++;
667  }
668  break;
670  if (p_enc_ctx->frame_num ==
671  api_param->reconf_hash[p_ctx->reconfig_count][0])
672  {
673  float crf = (float)(api_param->reconf_hash[p_ctx->reconfig_count][1] +
674  (float)api_param->reconf_hash[p_ctx->reconfig_count][2] / 100.0);
675  ni_reconfig_crf2(p_enc_ctx, crf);
676  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API reconfig crf %f\n",
677  __func__, p_enc_ctx->frame_num, crf);
678  p_ctx->reconfig_count++;
679  }
680  break;
682  if (p_enc_ctx->frame_num ==
683  api_param->reconf_hash[p_ctx->reconfig_count][0])
684  {
686  p_enc_ctx, api_param->reconf_hash[p_ctx->reconfig_count][1],
687  api_param->reconf_hash[p_ctx->reconfig_count][2]);
688  ni_log(NI_LOG_DEBUG, "%s(): frame #%lu API reconfig vbvMaxRate %d vbvBufferSize %d\n",
689  __func__, p_enc_ctx->frame_num,
690  api_param->reconf_hash[p_ctx->reconfig_count][1],
691  api_param->reconf_hash[p_ctx->reconfig_count][2]);
692  p_ctx->reconfig_count++;
693  }
694  break;
696  if (p_enc_ctx->frame_num ==
697  api_param->reconf_hash[p_ctx->reconfig_count][0])
698  {
700  p_enc_ctx, api_param->reconf_hash[p_ctx->reconfig_count][1]);
702  "xcoder_send_frame: frame #%lu reconf maxFrameSizeRatio %d\n",
703  p_enc_ctx->frame_num, api_param->reconf_hash[p_ctx->reconfig_count][1]);
704 
705  p_ctx->reconfig_count++;
706  }
707  break;
709  if (p_enc_ctx->frame_num ==
710  api_param->reconf_hash[p_ctx->reconfig_count][0]) {
712  p_enc_ctx, api_param->reconf_hash[p_ctx->reconfig_count][1]);
714  "xcoder_send_frame: frame #%lu API reconfig sliceArg %d\n",
715  p_enc_ctx->frame_num,
716  api_param->reconf_hash[p_ctx->reconfig_count][1]);
717 
718  p_ctx->reconfig_count++;
719  }
720  break;
722  default:;
723  }
724 }
725 
726 /*!*****************************************************************************
727  * \brief Send encoder input data, read from input file
728  *
729  * Note: For optimal performance, yuv_buf should be 4k aligned
730  *
731  * \param
732  *
733  * \return
734  ******************************************************************************/
736  ni_session_data_io_t *p_in_data, void *yuv_buf,
737  int input_video_width, int input_video_height,
738  int is_last_input)
739 {
740  int oneSent;
741  ni_frame_t *p_in_frame = &p_in_data->data.frame;
742  uint8_t enc_id = p_ctx->curr_enc_index;
743 
744  ni_log(NI_LOG_DEBUG, "===> encoder_send_data <===\n");
745 
747  {
748  ni_log(NI_LOG_DEBUG, "encoder_send_data: Sequence Change - waiting "
749  "for previous session to end\n");
751  }
752 
753  if (p_ctx->enc_eos_sent[enc_id] == 1)
754  {
755  ni_log(NI_LOG_DEBUG, "encoder_send_data: ALL data (incl. eos) sent "
756  "already!\n");
758  }
759 
760  if (p_ctx->enc_resend[enc_id])
761  {
762  goto send_frame;
763  }
764 
765  p_in_frame->start_of_stream = 0;
766  if (!p_ctx->enc_sos_sent[enc_id] ||
768  {
769  p_ctx->enc_sos_sent[enc_id] = 1;
770  p_in_frame->start_of_stream = 1;
771  }
772  p_in_frame->end_of_stream = 0;
773  p_in_frame->force_key_frame = 0;
774 
775  p_in_frame->video_width = input_video_width;
776  p_in_frame->video_height = input_video_height;
777 
778  // reset encoder change data buffer
779  memset(p_enc_ctx->enc_change_params, 0, sizeof(ni_encoder_change_params_t));
780 
781  // reset various aux data size
782  p_in_frame->roi_len = 0;
783  p_in_frame->reconf_len = 0;
784  p_in_frame->sei_total_len = 0;
785  p_in_frame->pts = p_ctx->pts[enc_id];
786 
787  // collect encode reconfig and demo info and save them as aux data in
788  // the input frame struct.
789  prep_reconf_demo_data(p_ctx, p_enc_ctx, p_in_frame);
790 
791  if (yuv_buf == NULL)
792  {
793  if (is_last_input)
794  {
795  p_in_frame->end_of_stream = 1;
796  ni_log(NI_LOG_DEBUG, "encoder_send_data: read chunk size 0, eos!\n");
797  }
798  else
799  {
800  ni_log(NI_LOG_DEBUG, "encoder_send_data: exit to get next input\n");
802  }
803  }
804 
805 send_frame:
806  // simulate FFmpeg -re option, which controls process input rate to simualte real time environment
807  if (p_ctx->read_framerate > 0)
808  {
809  uint64_t abs_time_ns;
810  abs_time_ns = ni_gettime_ns();
811  if ((abs_time_ns - p_ctx->start_time) < (uint64_t)(1000000000LL / p_ctx->read_framerate * p_ctx->num_frames_sent[enc_id]))
812  {
813  if (!p_ctx->enc_resend[enc_id])
814  p_ctx->enc_resend[enc_id] = 2;
815  if (p_ctx->enc_resend[enc_id] == 2)
816  return NI_TEST_RETCODE_EAGAIN;
817  }
818  else
819  {
820  p_ctx->num_frames_sent[enc_id]++;
821  }
822  }
823 
824  oneSent = ni_enc_write_from_yuv_buffer(p_enc_ctx, p_in_frame, yuv_buf);
825  if (oneSent < 0)
826  {
828  "Error: failed ni_device_session_write() for encoder\n");
829  p_ctx->enc_resend[enc_id] = 1;
831  } else if (oneSent == 0 && !p_enc_ctx->ready_to_close)
832  {
833  p_ctx->enc_resend[enc_id] = 1;
834  return NI_TEST_RETCODE_EAGAIN;
835  } else
836  {
837  p_ctx->enc_resend[enc_id] = 0;
838 
839  p_ctx->enc_total_bytes_sent[enc_id] += p_in_frame->data_len[0] +
840  p_in_frame->data_len[1] + p_in_frame->data_len[2] + p_in_frame->data_len[3];
841  ni_log(NI_LOG_DEBUG, "encoder_send_data: total sent data size=%lu\n",
842  p_ctx->enc_total_bytes_sent[enc_id]);
843 
844  ni_log(NI_LOG_DEBUG, "encoder_send_data: success\n");
845 
846  if (p_enc_ctx->ready_to_close)
847  {
849  {
850  p_ctx->enc_eos_sent[enc_id] = 1;
851  }
852  }
853 
855  {
858  "encoder_send_data: session_run_state change to %d\n",
859  p_enc_ctx->session_run_state);
860  }
861 
862  ni_pts_enqueue(p_ctx->enc_pts_queue[enc_id], p_ctx->pts[enc_id]);
863  ++p_ctx->pts[enc_id];
864  }
865 
866  ni_frame_wipe_aux_data(p_in_frame);
868 }
869 
870 /*******************************************************************************
871  * @brief Send encoder input data, directly after receiving from decoder
872  *
873  * @param p_enc_ctx encoder context
874  * p_dec_ctx decoder context
875  * p_dec_out_data frame returned by decoder
876  * p_enc_in_data frame to be sent to encoder
877  *
878  * @return
879  ******************************************************************************/
881  ni_session_data_io_t *p_dec_out_data,
882  ni_session_data_io_t *p_enc_in_data,
883  int input_video_width, int input_video_height)
884 {
885  int oneSent;
886  int data_len_to_send;
887  // frame pointer to data frame struct to be sent
888  ni_frame_t *p_in_frame = &(p_enc_in_data->data.frame);
889  ni_xcoder_params_t *api_params =
890  (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
891  int is_semiplanar = get_pixel_planar(p_enc_ctx->pixel_format) == NI_PIXEL_PLANAR_FORMAT_SEMIPLANAR;
892  int is_hwframe = p_enc_ctx->hw_action != NI_CODEC_HW_NONE;
893  uint8_t enc_id = p_ctx->curr_enc_index;
894 
895  ni_log(NI_LOG_DEBUG, "===> encoder_send_data2 <===\n");
896 
897  if (p_ctx->enc_eos_sent[enc_id] == 1)
898  {
899  ni_log(NI_LOG_DEBUG, "encoder_send_data2: ALL data (incl. eos) sent "
900  "already!\n");
902  }
903 
904  // don't send new data before flushing completed
906  {
907  return NI_TEST_RETCODE_EAGAIN;
908  }
909 
910 //#define ENCODER_FLUSH_INJECT
911 // Note that this demo only supports in multi threads transcoding mode
912 // For examples: sudo ./xcoder -c 0 -i input.h265 -m h2h -b 8 -o output.h265 -t
913 #ifdef ENCODER_FLUSH_INJECT
914  if ((p_enc_ctx->frame_num > 0 && p_enc_ctx->frame_num % 30 == 0) &&
915  !p_dec_out_data->data.frame.end_of_stream)
916  {
917  // send the encoder flush command
919  {
920  // need to change the state
922  ni_log(NI_LOG_INFO, "encoder_send_data2 flush encoder successfully\n");
923  return NI_TEST_RETCODE_EAGAIN;
924  }
925  else
926  {
927  ni_log(NI_LOG_ERROR, "Error: encoder_send_data2 flush encoder\n");
928  return -1;
929  }
930  }
931 #endif
932 
933  // frame resend
934  if (p_ctx->enc_resend[enc_id])
935  {
936  goto send_frame;
937  }
938 
939  // copy input frame to a new frame struct and prep for the aux data
940  p_in_frame->end_of_stream = p_dec_out_data->data.frame.end_of_stream;
941  p_in_frame->ni_pict_type = 0;
942 
943  // reset encoder change data buffer
944  memset(p_enc_ctx->enc_change_params, 0,
946 
947  // extra data starts with metadata header, and reset various aux data
948  // size
950  p_in_frame->roi_len = 0;
951  p_in_frame->reconf_len = 0;
952  p_in_frame->sei_total_len = 0;
953  p_in_frame->force_pic_qp = 0;
954  p_in_frame->pts = p_ctx->pts[enc_id];
955 
956  // collect encode reconfig and demo info and save them in the decode out
957  // frame, to be used in the aux data prep and copy later
958  prep_reconf_demo_data(p_ctx, p_enc_ctx, &(p_dec_out_data->data.frame));
959 
960  int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0};
961  int dst_height_aligned[NI_MAX_NUM_DATA_POINTERS] = {0};
962  bool alignment_2pass_wa = (
963  (api_params->cfg_enc_params.lookAheadDepth ||
964  api_params->cfg_enc_params.crf >= 0 ||
965  api_params->cfg_enc_params.crfFloat >= 0) &&
966  (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265 ||
967  p_enc_ctx->codec_format == NI_CODEC_FORMAT_AV1));
968  ni_get_hw_yuv420p_dim(input_video_width, input_video_height,
969  p_enc_ctx->bit_depth_factor, is_semiplanar,
970  dst_stride, dst_height_aligned);
971 
972  if (alignment_2pass_wa && !is_hwframe) {
973  if (is_semiplanar) {
974  // for 2-pass encode output mismatch WA, need to extend (and
975  // pad) CbCr plane height, because 1st pass assume input 32
976  // align
977  dst_height_aligned[1] = (((dst_height_aligned[0] + 31) / 32) * 32) / 2;
978  } else {
979  // for 2-pass encode output mismatch WA, need to extend (and
980  // pad) Cr plane height, because 1st pass assume input 32 align
981  dst_height_aligned[2] = (((dst_height_aligned[0] + 31) / 32) * 32) / 2;
982  }
983  }
984 
985  // ROI demo mode takes higher priority over aux data
986  // Note: when ROI demo modes enabled, supply ROI map for the specified
987  // range frames, and 0 map for others
988  if (api_params->roi_demo_mode && api_params->cfg_enc_params.roi_enable)
989  {
990  if (p_enc_ctx->frame_num > 90 && p_enc_ctx->frame_num < 300)
991  {
992  p_in_frame->roi_len = p_enc_ctx->roi_len;
993  } else
994  {
995  p_in_frame->roi_len = 0;
996  }
997  // when ROI enabled, always have a data buffer for ROI
998  // Note: this is handled separately from ROI through side/aux data
999  p_in_frame->extra_data_len += p_enc_ctx->roi_len;
1000  }
1001 
1002  int should_send_sei_with_frame = ni_should_send_sei_with_frame(
1003  p_enc_ctx, p_in_frame->ni_pict_type, api_params);
1004 
1005  // data buffer for various SEI: HDR mastering display color volume, HDR
1006  // content light level, close caption, User data unregistered, HDR10+
1007  // etc.
1008  uint8_t mdcv_data[NI_MAX_SEI_DATA];
1009  uint8_t cll_data[NI_MAX_SEI_DATA];
1010  uint8_t cc_data[NI_MAX_SEI_DATA];
1011  uint8_t udu_data[NI_MAX_SEI_DATA];
1012  uint8_t hdrp_data[NI_MAX_SEI_DATA];
1013 
1014  // prep for auxiliary data (various SEI, ROI) in p_in_frame, based on
1015  // the data returned in decoded frame and also reconfig and demo modes
1016  // collected in prep_reconf_demo_data
1018  p_enc_ctx, p_in_frame, &(p_dec_out_data->data.frame),
1019  p_enc_ctx->codec_format, should_send_sei_with_frame, mdcv_data,
1020  cll_data, cc_data, udu_data, hdrp_data);
1021 
1022  p_in_frame->extra_data_len += p_in_frame->sei_total_len;
1023 
1024  // data layout requirement: leave space for reconfig data if at least
1025  // one of reconfig, SEI or ROI is present
1026  // Note: ROI is present when enabled, so use encode config flag instead
1027  // of frame's roi_len as it can be 0 indicating a 0'd ROI map
1028  // setting !
1029  if (p_in_frame->reconf_len || p_in_frame->sei_total_len ||
1030  (api_params->roi_demo_mode &&
1031  api_params->cfg_enc_params.roi_enable))
1032  {
1033  p_in_frame->extra_data_len += sizeof(ni_encoder_change_params_t);
1034  }
1035 
1036  if (!is_hwframe)
1037  {
1039  p_in_frame, input_video_width, input_video_height, dst_stride,
1040  p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264,
1041  (int)(p_in_frame->extra_data_len), alignment_2pass_wa);
1042  if (!p_in_frame->p_data[0])
1043  {
1044  ni_log(NI_LOG_ERROR, "Error: cannot allocate YUV frame buffer!");
1045  return NI_TEST_RETCODE_FAILURE;
1046  }
1047  } else
1048  {
1049  ni_frame_buffer_alloc_hwenc(p_in_frame, input_video_width,
1050  input_video_height,
1051  (int)(p_in_frame->extra_data_len));
1052  if (!p_in_frame->p_data[3])
1053  {
1054  ni_log(NI_LOG_ERROR, "Error: cannot allocate YUV frame buffer!");
1055  return NI_TEST_RETCODE_FAILURE;
1056  }
1057  }
1058 
1060  "p_dst alloc linesize = %d/%d/%d src height=%d "
1061  "dst height aligned = %d/%d/%d force_key_frame=%d, "
1062  "extra_data_len=%u"
1063  " sei_size=%u (hdr_content_light_level %u hdr_mastering_display_"
1064  "color_vol %u hdr10+ %u hrd %d) reconf_size=%u roi_size=%u "
1065  "force_pic_qp=%u udu_sei_size=%u "
1066  "use_cur_src_as_long_term_pic %u use_long_term_ref %u\n",
1067  dst_stride[0], dst_stride[1], dst_stride[2], input_video_height,
1068  dst_height_aligned[0], dst_height_aligned[1], dst_height_aligned[2],
1069  p_in_frame->force_key_frame, p_in_frame->extra_data_len,
1070  p_in_frame->sei_total_len,
1073  p_in_frame->sei_hdr_plus_len, 0, /* hrd is 0 size for now */
1074  p_in_frame->reconf_len, p_in_frame->roi_len,
1075  p_in_frame->force_pic_qp, p_in_frame->sei_user_data_unreg_len,
1076  p_in_frame->use_cur_src_as_long_term_pic,
1077  p_in_frame->use_long_term_ref);
1078 
1079  uint8_t *p_src[NI_MAX_NUM_DATA_POINTERS];
1080  int src_stride[NI_MAX_NUM_DATA_POINTERS];
1081  int src_height[NI_MAX_NUM_DATA_POINTERS];
1082 
1083  src_height[0] = p_dec_out_data->data.frame.video_height;
1084  src_height[1] = src_height[2] = src_height[0] / 2;
1085  src_height[3] = 0;
1086 
1087  src_stride[0] =
1088  (int)(p_dec_out_data->data.frame.data_len[0]) / src_height[0];
1089  src_stride[1] =
1090  (int)(p_dec_out_data->data.frame.data_len[1]) / src_height[1];
1091  src_stride[2] = src_stride[1];
1092  if (is_semiplanar)
1093  {
1094  src_height[2] = 0;
1095  src_stride[2] = 0;
1096  }
1097  src_stride[3] = 0;
1098 
1099  p_src[0] = p_dec_out_data->data.frame.p_data[0];
1100  p_src[1] = p_dec_out_data->data.frame.p_data[1];
1101  p_src[2] = p_dec_out_data->data.frame.p_data[2];
1102  p_src[3] = p_dec_out_data->data.frame.p_data[3];
1103 
1104  if (!is_hwframe)
1105  { // YUV part of the encoder input data layout
1107  (uint8_t **)(p_in_frame->p_data), p_src, input_video_width,
1108  input_video_height, p_enc_ctx->bit_depth_factor, is_semiplanar,
1109  ((ni_xcoder_params_t *)p_enc_ctx->p_session_config)
1110  ->cfg_enc_params.conf_win_right,
1111  dst_stride, dst_height_aligned, src_stride, src_height);
1112  } else
1113  {
1114  ni_copy_hw_descriptors((uint8_t **)(p_in_frame->p_data), p_src);
1115  }
1116  // auxiliary data part of the encoder input data layout
1117  ni_enc_copy_aux_data(p_enc_ctx, p_in_frame,
1118  &(p_dec_out_data->data.frame),
1119  p_enc_ctx->codec_format, mdcv_data, cll_data,
1120  cc_data, udu_data, hdrp_data, is_hwframe,
1121  is_semiplanar);
1122 
1123  p_in_frame->video_width = input_video_width;
1124  p_in_frame->video_height = input_video_height;
1125 
1126  p_in_frame->start_of_stream = 0;
1127  if (!p_ctx->enc_sos_sent[enc_id])
1128  {
1129  p_ctx->enc_sos_sent[enc_id] = 1;
1130  p_in_frame->start_of_stream = 1;
1131  }
1132 
1133 send_frame:
1134  data_len_to_send = (int)(p_in_frame->data_len[0] + p_in_frame->data_len[1] +
1135  p_in_frame->data_len[2] + p_in_frame->data_len[3]);
1136 
1137  if (data_len_to_send > 0 || p_in_frame->end_of_stream)
1138  {
1139  oneSent = ni_device_session_write(p_enc_ctx, p_enc_in_data,
1141  p_in_frame->end_of_stream = 0;
1142  } else
1143  {
1144  return NI_TEST_RETCODE_SUCCESS;
1145  }
1146 
1147  if (oneSent < 0)
1148  {
1149  ni_log(NI_LOG_ERROR, "Error: encoder_send_data2\n");
1150  p_ctx->enc_resend[enc_id] = 1;
1151  return NI_TEST_RETCODE_FAILURE;
1152  } else if (oneSent == 0)
1153  {
1154  if (p_ctx->enc_eos_sent[enc_id] == 0 && p_enc_ctx->ready_to_close)
1155  {
1156  p_ctx->enc_resend[enc_id] = 0;
1157  p_ctx->enc_eos_sent[enc_id] = 1;
1158  } else
1159  {
1160  p_ctx->enc_resend[enc_id] = 1;
1161  return NI_TEST_RETCODE_EAGAIN;
1162  }
1163  } else
1164  {
1165  p_ctx->enc_resend[enc_id] = 0;
1166 
1167  if (p_enc_ctx->ready_to_close)
1168  {
1169  p_ctx->enc_eos_sent[enc_id] = 1;
1170  }
1171 
1172  ni_pts_enqueue(p_ctx->enc_pts_queue[enc_id], p_ctx->pts[enc_id]);
1173  ++p_ctx->pts[enc_id];
1174 
1175  ni_log(NI_LOG_DEBUG, "encoder_send_data2: success\n");
1176  }
1177 
1178  return NI_TEST_RETCODE_SUCCESS;
1179 }
1180 
1181 /*!*****************************************************************************
1182  * \brief Send encoder input data, read from uploader instance hwframe
1183  *
1184  * \param
1185  *
1186  * \return
1187  ******************************************************************************/
1189  ni_session_data_io_t *p_in_data,
1190  int input_video_width, int input_video_height, int eos)
1191 {
1192  int oneSent;
1193  ni_frame_t *p_in_frame = &(p_in_data->data.frame);
1194  uint8_t enc_id = p_ctx->curr_enc_index;
1195 
1196  ni_log(NI_LOG_DEBUG, "===> encoder_send_data3 <===\n");
1197 
1198  if (p_ctx->enc_eos_sent[enc_id] == 1)
1199  {
1200  ni_log(NI_LOG_DEBUG, "encoder_send_data3: ALL data (incl. eos) sent "
1201  "already!\n");
1202  return 0;
1203  }
1204 
1205  if (p_ctx->enc_resend[enc_id])
1206  {
1207  goto send_frame;
1208  }
1209 
1210  p_in_frame->start_of_stream = 0;
1211  if (!p_ctx->enc_sos_sent[enc_id])
1212  {
1213  p_ctx->enc_sos_sent[enc_id] = 1;
1214  p_in_frame->start_of_stream = 1;
1215  }
1216  p_in_frame->end_of_stream = eos;
1217  p_in_frame->force_key_frame = 0;
1218  p_in_frame->video_width = input_video_width;
1219  p_in_frame->video_height = input_video_height;
1220  p_in_frame->pts = p_ctx->pts[enc_id];
1221  if (eos)
1222  {
1223  ni_log(NI_LOG_DEBUG, "encoder_send_data3: read chunk size 0, eos!\n");
1224  }
1225 
1226  // only metadata header for now
1228 
1229 send_frame:
1230  oneSent =
1231  ni_device_session_write(p_enc_ctx, p_in_data, NI_DEVICE_TYPE_ENCODER);
1232  if (oneSent < 0)
1233  {
1235  "Error: failed ni_device_session_write() for encoder\n");
1236  p_ctx->enc_resend[enc_id] = 1;
1237  return -1;
1238  } else if (oneSent == 0 && !p_enc_ctx->ready_to_close)
1239  {
1240  p_ctx->enc_resend[enc_id] = 1;
1241  ni_log(NI_LOG_DEBUG, "NEEDED TO RESEND");
1242  return NI_TEST_RETCODE_EAGAIN;
1243  } else
1244  {
1245  p_ctx->enc_resend[enc_id] = 0;
1246 
1247  ni_log(NI_LOG_DEBUG, "encoder_send_data3: total sent data size=%u\n",
1248  p_in_frame->data_len[3]);
1249 
1250  ni_log(NI_LOG_DEBUG, "encoder_send_data3: success\n");
1251 
1252  if (p_enc_ctx->ready_to_close)
1253  {
1254  p_ctx->enc_eos_sent[enc_id] = 1;
1255  }
1256 
1257  ni_pts_enqueue(p_ctx->enc_pts_queue[enc_id], p_ctx->pts[enc_id]);
1258  ++p_ctx->pts[enc_id];
1259  }
1260 
1261  return 0;
1262 }
1263 
1264 /*!*****************************************************************************
1265  * \brief Encoder session open
1266  *
1267  * \param
1268  *
1269  * \return 0 if successful, < 0 otherwise
1270  ******************************************************************************/
1271 int encoder_open_session(ni_session_context_t *p_enc_ctx, int dst_codec_format,
1272  int iXcoderGUID, ni_xcoder_params_t *p_enc_params,
1273  int width, int height, ni_pix_fmt_t pix_fmt,
1274  bool check_zerocopy)
1275 {
1276  int ret = 0;
1277  bool isrgba = false;
1278 
1279  p_enc_ctx->p_session_config = p_enc_params;
1280  p_enc_ctx->session_id = NI_INVALID_SESSION_ID;
1281  p_enc_ctx->codec_format = dst_codec_format;
1282 
1283  // assign the card GUID in the encoder context and let session open
1284  // take care of the rest
1285  p_enc_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
1286  p_enc_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
1287  p_enc_ctx->hw_id = iXcoderGUID;
1288 
1289  // default: little endian
1290  p_enc_ctx->src_endian = NI_FRAME_LITTLE_ENDIAN;
1291 
1292  switch (pix_fmt)
1293  {
1294  case NI_PIX_FMT_YUV420P:
1295  case NI_PIX_FMT_NV12:
1296  p_enc_ctx->src_bit_depth = 8;
1297  p_enc_ctx->bit_depth_factor = 1;
1298  break;
1300  case NI_PIX_FMT_P010LE:
1301  p_enc_ctx->src_bit_depth = 10;
1302  p_enc_ctx->bit_depth_factor = 2;
1303  break;
1304  case NI_PIX_FMT_ABGR:
1305  case NI_PIX_FMT_ARGB:
1306  case NI_PIX_FMT_RGBA:
1307  case NI_PIX_FMT_BGRA:
1308  p_enc_ctx->src_bit_depth = 8;
1309  p_enc_ctx->bit_depth_factor = 4;
1310  isrgba = true;
1311  break;
1312  default:
1313  p_enc_ctx->src_bit_depth = 8;
1314  p_enc_ctx->bit_depth_factor = 1;
1315  pix_fmt = NI_PIX_FMT_YUV420P;
1316  break;
1317  //ni_log(NI_LOG_ERROR, "%s: Invalid pixel format %s\n", __func__,
1318  // ni_pixel_format_name(pix_fmt));
1319  //return NI_RETCODE_INVALID_PARAM;
1320  }
1321 
1322  // original resolution this stream started with, this is used by encoder sequence change
1323  p_enc_ctx->ori_width = width;
1324  p_enc_ctx->ori_height = height;
1325  p_enc_ctx->ori_bit_depth_factor = p_enc_ctx->bit_depth_factor;
1326  p_enc_ctx->ori_pix_fmt = pix_fmt;
1327  p_enc_ctx->pixel_format = pix_fmt;
1328 
1329  int linesize_aligned = width;
1330  if (!isrgba)
1331  {
1332  if (linesize_aligned < NI_MIN_WIDTH)
1333  {
1334  p_enc_params->cfg_enc_params.conf_win_right +=
1335  (NI_MIN_WIDTH - width) / 2 * 2;
1336  linesize_aligned = NI_MIN_WIDTH;
1337  } else
1338  {
1339  linesize_aligned = ((width + 1) / 2) * 2;
1340  p_enc_params->cfg_enc_params.conf_win_right +=
1341  (linesize_aligned - width) / 2 * 2;
1342  }
1343  }
1344  p_enc_params->source_width = linesize_aligned;
1345 
1346  int height_aligned = height;
1347  if (!isrgba)
1348  {
1349  if (height_aligned < NI_MIN_HEIGHT)
1350  {
1351  p_enc_params->cfg_enc_params.conf_win_bottom +=
1352  (NI_MIN_HEIGHT - height) / 2 * 2;
1353  height_aligned = NI_MIN_HEIGHT;
1354  } else
1355  {
1356  height_aligned = ((height + 1) / 2) * 2;
1357  p_enc_params->cfg_enc_params.conf_win_bottom +=
1358  (height_aligned - height) / 2 * 2;
1359  }
1360  }
1361  p_enc_params->source_height = height_aligned;
1362 
1363  // default planar encoder input data
1364  p_enc_params->cfg_enc_params.planar = get_pixel_planar(pix_fmt);
1365 
1366  if (check_zerocopy)
1367  {
1368 
1369  // config linesize for zero copy (if input resolution is zero copy compatible)
1370  int src_stride[NI_MAX_NUM_DATA_POINTERS];
1371 
1372  // NOTE - FFmpeg / Gstreamer users should use linesize array in frame structure instead of src_stride in the following sample code
1373  src_stride[0] = width * p_enc_ctx->bit_depth_factor;
1374 
1375  if (isrgba)
1376  src_stride[1] = src_stride[2] = 0;
1377  else
1378  {
1379  bool isnv12frame = (p_enc_params->cfg_enc_params.planar == NI_PIXEL_PLANAR_FORMAT_SEMIPLANAR) ? true : false;
1380  src_stride[1] = isnv12frame ? src_stride[0] : src_stride[0] / 2;
1381  src_stride[2] = isnv12frame ? 0 : src_stride[0] / 2;
1382  }
1383 
1385  p_enc_params, width, height,
1386  (const int *)src_stride, true);
1387  }
1388 
1390  if (ret != NI_RETCODE_SUCCESS)
1391  {
1392  ni_log(NI_LOG_ERROR, "Error: %s failure!\n", __func__);
1393  } else
1394  {
1395  ni_log(NI_LOG_INFO, "Encoder device %d session open successful.\n", iXcoderGUID);
1396  }
1397 
1398  // set up ROI QP map for ROI demo modes if enabled
1399  if (p_enc_params->cfg_enc_params.roi_enable &&
1400  (1 == p_enc_params->roi_demo_mode || 2 == p_enc_params->roi_demo_mode))
1401  {
1402  set_demo_roi_map(p_enc_ctx);
1403  }
1404 
1405  return ret;
1406 }
1407 
1408 /*!*****************************************************************************
1409  * \brief Reopen or reconfig encoder upon sequence change
1410  *
1411  * \param
1412  *
1413  * \return 0 - success got packet
1414  * 1 - received eos
1415  * 2 - got nothing, need retry
1416  * -1 - failure
1417  ******************************************************************************/
1419  ni_session_data_io_t *p_in_data,
1420  ni_session_data_io_t *p_out_data)
1421 {
1422  int ret = NI_TEST_RETCODE_SUCCESS;
1423  int new_stride, ori_stride;
1424  bool bIsSmallPicture = false;
1425  ni_frame_t *p_buffered_frame = &(p_in_data->data.frame);
1426  ni_xcoder_params_t *p_api_param = (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
1427  int new_width, new_height;
1428  ni_pix_fmt_t new_pix_fmt;
1429  bool is_semiplanar;
1430  bool is_rgba;
1431  int src_stride[NI_MAX_NUM_DATA_POINTERS];
1432 
1433  new_width = p_buffered_frame->video_width;
1434  new_height = p_buffered_frame->video_height;
1435  new_pix_fmt = p_buffered_frame->pixel_format;
1436 
1437  // check if resolution is zero copy compatible and set linesize according to new resolution
1438  is_semiplanar = (new_pix_fmt == NI_PIX_FMT_NV12 || new_pix_fmt == NI_PIX_FMT_P010LE);
1439 
1440  is_rgba = (new_pix_fmt == NI_PIX_FMT_ABGR || new_pix_fmt == NI_PIX_FMT_ARGB
1441  || new_pix_fmt == NI_PIX_FMT_RGBA || new_pix_fmt == NI_PIX_FMT_BGRA);
1442 
1443  // NOTE - FFmpeg / Gstreamer users should use linesize array in frame structure instead of src_stride in the following sample code
1444  src_stride[0] = new_width * p_enc_ctx->bit_depth_factor;
1445  if (is_rgba)
1446  {
1447  src_stride[1] = 0;
1448  src_stride[2] = 0;
1449  }
1450  else
1451  {
1452  src_stride[1] = is_semiplanar ? src_stride[0] : src_stride[0] / 2;
1453  src_stride[2] = is_semiplanar ? 0 : src_stride[0] / 2;
1454  }
1455 
1456  if (ni_encoder_frame_zerocopy_check(p_enc_ctx,
1457  p_api_param, new_width, new_height,
1458  (const int *)src_stride, true) == NI_RETCODE_SUCCESS)
1459  {
1460  new_stride = p_api_param->luma_linesize; // new sequence is zero copy compatible
1461  }
1462  else
1463  {
1464  new_stride = NI_ALIGN(new_width * p_enc_ctx->bit_depth_factor, 128);
1465  }
1466 
1467  if (p_enc_ctx->ori_luma_linesize && p_enc_ctx->ori_chroma_linesize)
1468  {
1469  ori_stride = p_enc_ctx->ori_luma_linesize; // previous sequence was zero copy compatible
1470  }
1471  else
1472  {
1473  ori_stride = NI_ALIGN(p_enc_ctx->ori_width * p_enc_ctx->bit_depth_factor, 128);
1474  }
1475 
1476  if (p_api_param->cfg_enc_params.lookAheadDepth) {
1477  ni_log(NI_LOG_DEBUG, "xcoder_encode_reinit 2-pass "
1478  "lookaheadDepth %d\n",
1479  p_api_param->cfg_enc_params.lookAheadDepth);
1480  if ((new_width < NI_2PASS_ENCODE_MIN_WIDTH) ||
1481  (new_height < NI_2PASS_ENCODE_MIN_HEIGHT)) {
1482  bIsSmallPicture = true;
1483  }
1484  }
1485  else {
1486  if ((new_width < NI_MIN_WIDTH) ||
1487  (new_height < NI_MIN_HEIGHT)) {
1488  bIsSmallPicture = true;
1489  }
1490  }
1491 
1492  if (p_api_param->cfg_enc_params.multicoreJointMode) {
1493  ni_log(NI_LOG_DEBUG, "xcoder_encode_reinit multicore "
1494  "joint mode\n");
1495  if ((new_width < NI_MULTICORE_ENCODE_MIN_WIDTH) ||
1496  (new_height < NI_MULTICORE_ENCODE_MIN_HEIGHT)) {
1497  bIsSmallPicture = true;
1498  }
1499  }
1500 
1501  if (p_api_param->cfg_enc_params.crop_width || p_api_param->cfg_enc_params.crop_height) {
1502  ni_log(NI_LOG_DEBUG, "xcoder_encode_reinit needs to close and re-open "
1503  "due to crop width x height\n");
1504  bIsSmallPicture = true;
1505  }
1506 
1507  ni_log(NI_LOG_DEBUG, "xcoder_encode_reinit resolution: %dx%d->%dx%d "
1508  "pix fmt: %d->%d bIsSmallPicture %d codec %d\n",
1509  ori_stride, p_enc_ctx->ori_height, new_stride, new_height,
1510  p_enc_ctx->ori_pix_fmt, new_pix_fmt, bIsSmallPicture,
1511  p_enc_ctx->codec_format);
1512 
1513  // fast sequence change without close / open only if new resolution < original resolution
1514  if (ori_stride*p_enc_ctx->ori_height < new_stride*new_height ||
1515  p_enc_ctx->ori_pix_fmt != new_pix_fmt ||
1516  bIsSmallPicture ||
1517  p_enc_ctx->codec_format == NI_CODEC_FORMAT_JPEG)
1518  {
1519  ni_log(NI_LOG_INFO, "XCoder encode sequence change by close / re-open session\n");
1520  encoder_close_session(p_enc_ctx, p_in_data, p_out_data);
1521  ret = encoder_open_session(p_enc_ctx, p_enc_ctx->codec_format,
1522  p_enc_ctx->hw_id, p_api_param, new_width,
1523  new_height, new_pix_fmt, true);
1524  if (NI_RETCODE_SUCCESS != ret)
1525  {
1526  ni_log(NI_LOG_ERROR, "Failed to Re-open Encoder Session upon Sequence Change (status = %d)\n", ret);
1527  return ret;
1528  }
1529  p_out_data->data.packet.end_of_stream = 0;
1530  p_in_data->data.frame.start_of_stream = 1;
1531  // clear crop parameters upon sequence change because cropping values may not be compatible to new resolution
1532  p_api_param->cfg_enc_params.crop_width = p_api_param->cfg_enc_params.crop_height = 0;
1533  p_api_param->cfg_enc_params.hor_offset = p_api_param->cfg_enc_params.ver_offset = 0;
1534  }
1535  else
1536  {
1537  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_AV1) {
1538  // AV1 8x8 alignment HW limitation is now worked around by FW cropping input resolution
1539  if (new_width % NI_PARAM_AV1_ALIGN_WIDTH_HEIGHT)
1541  "resolution change: AV1 Picture Width not aligned to %d - picture will be cropped\n",
1543 
1544  if (new_height % NI_PARAM_AV1_ALIGN_WIDTH_HEIGHT)
1546  "resolution change: AV1 Picture Height not aligned to %d - picture will be cropped\n",
1548  }
1549  ni_log(NI_LOG_INFO, "XCoder encode sequence change by re-config session (fast path)\n");
1550  ret = encoder_sequence_change(p_enc_ctx, p_in_data, p_out_data, new_width, new_height, new_pix_fmt);
1551  }
1552 
1553  // this state is referenced when sending first frame after sequence change
1555 
1556  ni_log(NI_LOG_DEBUG, "%s: session_run_state change to %d \n", __func__,
1557  p_enc_ctx->session_run_state);
1558 
1559  return ret;
1560 }
1561 
1562 void write_av1_ivf_header(ni_demo_context_t *p_ctx, uint32_t width, uint32_t height, uint32_t frame_num,
1563  uint32_t frame_denom, FILE *p_file)
1564 {
1565  // write the global ivf start header
1566  if (!p_ctx->ivf_header_written[p_ctx->curr_enc_index] && p_file != NULL && !p_ctx->av1_output_obu)
1567  {
1568  uint8_t start_header[32] = {
1569  0x44, 0x4b, 0x49, 0x46, /* signature: 'DKIF' */
1570  0x00, 0x00, /* version: 0 */
1571  0x20, 0x00, /* length of header in bytes: 32 */
1572  0x41, 0x56, 0x30, 0x31, /* codec FourCC: AV01 */
1573  0x00, 0x07, /* width in pixels(little endian), default 1280 */
1574  0xd0, 0x02, /* height in pixels(little endian), default 720 */
1575  0x1e, 0x00, 0x00, 0x00, /* time base numerator, default 30 */
1576  0x01, 0x00, 0x00, 0x00, /* time base denominator, default 1 */
1577  0x00, 0x00, 0x00, 0x00, /* number of frames in file */
1578  0x00, 0x00, 0x00, 0x00 /* reserved */
1579  };
1580 
1581  if (width && height)
1582  {
1583  start_header[12] = width & 0xff;
1584  start_header[13] = ((width >> 8) & 0xff);
1585  start_header[14] = height & 0xff;
1586  start_header[15] = ((height >> 8) & 0xff);
1587  }
1588 
1589  if (frame_num && frame_denom)
1590  {
1591  start_header[16] = frame_num & 0xff;
1592  start_header[17] = ((frame_num >> 8) & 0xff);
1593  start_header[18] = ((frame_num >> 16) & 0xff);
1594  start_header[19] = ((frame_num >> 24) & 0xff);
1595  start_header[20] = frame_denom & 0xff;
1596  start_header[21] = ((frame_denom >> 8) & 0xff);
1597  start_header[22] = ((frame_denom >> 16) & 0xff);
1598  start_header[23] = ((frame_denom >> 24) & 0xff);
1599  }
1600 
1601  if (fwrite(start_header, sizeof(start_header), 1, p_file) != 1)
1602  {
1603  ni_log(NI_LOG_ERROR, "Error: writing ivf start header fail!\n");
1604  ni_log(NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
1605  }
1606 
1607  p_ctx->ivf_header_written[p_ctx->curr_enc_index] = 1;
1608  }
1609 }
1610 
1611 void write_av1_ivf_packet(ni_demo_context_t *p_ctx, ni_packet_t *p_out_pkt, uint32_t meta_size, FILE *p_file)
1612 {
1613  int i;
1614  uint8_t enc_id = p_ctx->curr_enc_index;
1615 
1616  if (!p_file)
1617  {
1618  return;
1619  }
1620 
1621  // write ivf frame header
1622  if (!p_ctx->av1_output_obu)
1623  {
1624  uint32_t pts = p_ctx->av1_muxed_num_packets[enc_id];
1625  uint32_t pkt_size = p_out_pkt->data_len - meta_size;
1626 
1627  if (p_ctx->av1_seq_header_len[enc_id] > 0)
1628  {
1629  pkt_size += p_ctx->av1_seq_header_len[enc_id] - meta_size;
1630  }
1631  for (i = 0; i < p_out_pkt->av1_buffer_index; i++)
1632  {
1633  pkt_size += p_out_pkt->av1_data_len[i] - meta_size;
1634  }
1635 
1636  // ivf frame header
1637  // bytes 0-3: size of frame in bytes(not including the 12-byte header
1638  // byte 4-11: 64-bit pts (here pts=num_of_packets(32-bit), thus here only saves 32-bit
1639  uint8_t ivf_frame_header[12] = {((pkt_size & 0xff)),
1640  ((pkt_size >> 8) & 0xff),
1641  ((pkt_size >> 16) & 0xff),
1642  ((pkt_size >> 24) & 0xff),
1643  ((pts & 0xff)),
1644  ((pts >> 8) & 0xff),
1645  ((pts >> 16) & 0xff),
1646  ((pts >> 24) & 0xff),
1647  0x00, 0x00, 0x00, 0x00};
1648  if (fwrite(ivf_frame_header, 12, 1, p_file) != 1)
1649  {
1650  ni_log(NI_LOG_ERROR, "Error: writing ivf frame header fail!\n");
1651  ni_log(NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
1652  }
1653  }
1654 
1655  // write the leftover sequence header if there is any
1656  if (p_ctx->av1_seq_header_len[enc_id] > 0)
1657  {
1658  if (fwrite(p_ctx->p_av1_seq_header[enc_id] + meta_size,
1659  p_ctx->av1_seq_header_len[enc_id] - meta_size, 1, p_file) != 1)
1660  {
1661  ni_log(NI_LOG_ERROR, "Error: writing av1 sequence header fail!\n");
1662  ni_log(NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
1663  }
1664  ni_aligned_free(p_ctx->p_av1_seq_header[enc_id]);
1665  p_ctx->av1_seq_header_len[enc_id] = 0;
1666  }
1667 
1668  // write the leftover av1 packets
1669  for (i = 0; i < p_out_pkt->av1_buffer_index; i++)
1670  {
1671  if (fwrite((uint8_t *)p_out_pkt->av1_p_data[i] + meta_size,
1672  p_out_pkt->av1_data_len[i] - meta_size, 1, p_file) != 1)
1673  {
1674  ni_log(NI_LOG_ERROR, "Error: writing av1 packets fail!\n");
1675  ni_log(NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
1676  }
1677  }
1678 
1679  // write the current packet
1680  if (fwrite((uint8_t *)p_out_pkt->p_data + meta_size,
1681  p_out_pkt->data_len - meta_size, 1, p_file) != 1)
1682  {
1683  ni_log(NI_LOG_ERROR, "Error: writing av1 packets fail!\n");
1684  ni_log(NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
1685  }
1686 
1687  p_ctx->av1_muxed_num_packets[enc_id]++;
1688 }
1689 
1690 int write_av1_ivf_trailer(ni_demo_context_t *p_ctx, ni_packet_t *p_out_pkt, uint32_t meta_size, FILE *p_file)
1691 {
1692  uint32_t muxed_num_packets = p_ctx->av1_muxed_num_packets[p_ctx->curr_enc_index];
1693  if (p_file)
1694  {
1695  // write the leftover packets
1696  if (p_out_pkt->av1_buffer_index > 0)
1697  {
1698  write_av1_ivf_packet(p_ctx, p_out_pkt, meta_size, p_file);
1699  }
1700 
1701  // update frame_count in ivf start header
1702  if (muxed_num_packets && !p_ctx->av1_output_obu)
1703  {
1704  uint8_t frame_cnt[4] = {
1705  (muxed_num_packets & 0xff),
1706  ((muxed_num_packets >> 8) & 0xff),
1707  ((muxed_num_packets >> 16) & 0xff),
1708  ((muxed_num_packets >> 24) & 0xff)};
1709  fseek(p_file, 24, SEEK_SET);
1710  if (fwrite(frame_cnt, 4, 1, p_file) != 1)
1711  {
1712  ni_log(NI_LOG_ERROR, "Error: failed to update frame_cnt in ivf "
1713  "header!\n");
1714  ni_log(NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
1715  return -1;
1716  }
1717  }
1718  }
1719 
1720  return 0;
1721 }
1722 
1723 /*!*****************************************************************************
1724  * \brief Receive output data from encoder
1725  *
1726  * \param p_in_data is passed in to specify new frame resolution upon sequence
1727  * change
1728  *
1729  * \return 0 - success got packet
1730  * 1 - received eos
1731  * 2 - got nothing, need retry
1732  * -1 - failure
1733  ******************************************************************************/
1735  ni_session_data_io_t *p_out_data, int output_video_width,
1736  int output_video_height, FILE *p_file, ni_session_data_io_t * p_in_data)
1737 {
1738  int packet_size = NI_MAX_TX_SZ;
1739  int rc = 0;
1740  int end_flag = 0;
1741  int rx_size = 0;
1742  uint8_t enc_id = p_ctx->curr_enc_index;
1743  ni_packet_t *p_out_pkt = &(p_out_data->data.packet);
1744  int meta_size = p_enc_ctx->meta_size;
1745  ni_xcoder_params_t *p_api_param = (ni_xcoder_params_t *)p_enc_ctx->p_session_config;
1746  int pts = -1;
1747  int dts = -1;
1748 
1749  ni_log(NI_LOG_DEBUG, "===> encoder_receive_data <===\n");
1750  if (NI_INVALID_SESSION_ID == p_enc_ctx->session_id)
1751  {
1752  // keep-alive-thread timeout will set session_id to invalid, should exit
1754  "encode session id invalid, the session should be closed\n");
1755  return NI_TEST_RETCODE_FAILURE;
1756  }
1757 
1758 receive_data:
1759  rc = ni_packet_buffer_alloc(p_out_pkt, packet_size);
1760  if (rc != NI_RETCODE_SUCCESS)
1761  {
1762  ni_log(NI_LOG_ERROR, "Error: malloc packet failed, ret = %d!\n", rc);
1763  return NI_TEST_RETCODE_FAILURE;
1764  }
1765 
1766  rc = ni_device_session_read(p_enc_ctx, p_out_data, NI_DEVICE_TYPE_ENCODER);
1767 
1768  end_flag = p_out_pkt->end_of_stream;
1769  rx_size = rc;
1770 
1771  ni_log(NI_LOG_DEBUG, "encoder_receive_data: received data size=%d\n", rx_size);
1772 
1773  if (rx_size > meta_size)
1774  {
1775  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_AV1)
1776  {
1777  if (p_enc_ctx->pkt_num == 0)
1778  {
1779  write_av1_ivf_header(p_ctx, output_video_width, output_video_height,
1780  p_api_param->fps_number,
1781  p_api_param->fps_denominator, p_file);
1782  // store the sequence header for next packet writing
1783  p_ctx->p_av1_seq_header[enc_id] = (uint8_t *)p_out_pkt->p_data;
1784  p_ctx->av1_seq_header_len[enc_id] = p_out_pkt->data_len;
1785  p_out_pkt->p_buffer = NULL;
1786  p_out_pkt->p_data = NULL;
1787  p_out_pkt->buffer_size = 0;
1788  p_out_pkt->data_len = 0;
1789  p_enc_ctx->pkt_num = 1;
1790  } else
1791  {
1792  // store the av1 unshown frames for next packet writing
1793  if (!p_out_pkt->av1_show_frame)
1794  {
1795  p_out_pkt->av1_p_buffer[p_out_pkt->av1_buffer_index] =
1796  p_out_pkt->p_buffer;
1797  p_out_pkt->av1_p_data[p_out_pkt->av1_buffer_index] =
1798  p_out_pkt->p_data;
1799  p_out_pkt->av1_buffer_size[p_out_pkt->av1_buffer_index] =
1800  p_out_pkt->buffer_size;
1801  p_out_pkt->av1_data_len[p_out_pkt->av1_buffer_index] =
1802  p_out_pkt->data_len;
1803  p_out_pkt->av1_buffer_index++;
1804  p_out_pkt->p_buffer = NULL;
1805  p_out_pkt->p_data = NULL;
1806  p_out_pkt->buffer_size = 0;
1807  p_out_pkt->data_len = 0;
1808  if (p_out_pkt->av1_buffer_index >= MAX_AV1_ENCODER_GOP_NUM)
1809  {
1810  ni_log(NI_LOG_ERROR, "Error: recv AV1 not shown frame "
1811  "number %d >= %d\n", p_out_pkt->av1_buffer_index,
1813  return NI_TEST_RETCODE_FAILURE;
1814  }
1815  } else
1816  {
1817  ni_log(NI_LOG_DEBUG, "AV1 output packet "
1818  "pts %lld dts %lld\n", p_out_pkt->pts, p_out_pkt->dts);
1819  write_av1_ivf_packet(p_ctx, p_out_pkt, p_enc_ctx->meta_size, p_file);
1820  ni_packet_buffer_free_av1(p_out_pkt);
1821  }
1822 
1823  // recycle hw frame before next read
1824  if (p_enc_ctx->hw_action)
1825  {
1826  // encoder only returns valid recycle index
1827  // when there's something to recycle.
1828  // This range is suitable for all memory bins
1829  if (p_out_pkt->recycle_index > 0 &&
1830  p_out_pkt->recycle_index <
1832  {
1833  ni_hw_frame_unref(p_out_pkt->recycle_index);
1834  p_out_pkt->recycle_index = 0; //clear to not double count
1835  }
1836  }
1837  }
1838  } else
1839  {
1840  if (p_file &&
1841  (fwrite((uint8_t *)p_out_pkt->p_data + meta_size,
1842  p_out_pkt->data_len - meta_size, 1, p_file) != 1))
1843  {
1844  ni_log(NI_LOG_ERROR, "Error: writing data %u bytes error!\n",
1845  p_out_pkt->data_len - meta_size);
1846  ni_log(NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
1847  }
1848  }
1849 
1850  p_ctx->enc_total_bytes_received[enc_id] += rx_size - meta_size;
1851 
1852  // The first packet is the sequence head packet and it will be read before the first frame is sent
1853  if(p_ctx->num_packets_received[enc_id] != 0)
1854  {
1855  pts = p_out_pkt->pts;
1856  ni_pts_dequeue(p_ctx->enc_pts_queue[enc_id], &dts);
1857  ni_log(NI_LOG_DEBUG, "PTS: %d, DTS: %d\n", pts, dts);
1858  }
1859 
1860  (p_ctx->num_packets_received[enc_id])++;
1861 
1862  ni_log(NI_LOG_DEBUG, "Got: Packets= %u\n", p_ctx->num_packets_received[enc_id]);
1863  } else if (rx_size != 0)
1864  {
1865  ni_log(NI_LOG_ERROR, "Error: received %d bytes, <= metadata size %d!\n",
1866  rx_size, meta_size);
1867  return NI_TEST_RETCODE_FAILURE;
1868  } else if (end_flag)
1869  {
1871  p_enc_ctx->session_run_state)
1872  {
1873  // after sequence change completes, reset codec state
1874  ni_log(NI_LOG_INFO, "encoder_receive_data: sequence "
1875  "change completed, return SEQ_CHANGE_DONE and will reopen "
1876  "or reconfig codec!\n");
1877  rc = encoder_reinit_session(p_enc_ctx, p_in_data, p_out_data);
1878  ni_log(NI_LOG_TRACE, "encoder_receive_data: encoder_reinit_session ret %d\n", rc);
1879  if (rc == NI_RETCODE_SUCCESS)
1880  {
1882  }
1883  else
1884  {
1885  return NI_TEST_RETCODE_FAILURE;
1886  }
1887  }
1888 
1890  {
1891  // restart the encoder after sending flushing command
1892  rc = ni_device_session_restart(p_enc_ctx,
1893  p_in_data->data.frame.video_width,
1894  p_in_data->data.frame.video_height,
1896  ni_log(NI_LOG_INFO, "ni_device_session_restart() ret %d\n", rc);
1897  if (rc == NI_RETCODE_SUCCESS)
1898  {
1899  // need to reset the packet end_of_stream and run state
1900  p_out_pkt->end_of_stream = 0;
1902  return NI_TEST_RETCODE_EAGAIN;
1903  }
1904  else
1905  {
1906  return NI_TEST_RETCODE_FAILURE;
1907  }
1908  }
1909 
1910  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_AV1)
1911  {
1912  rc = write_av1_ivf_trailer(p_ctx, p_out_pkt, p_enc_ctx->meta_size, p_file);
1913  ni_packet_buffer_free_av1(p_out_pkt);
1914  if (rc < 0)
1915  {
1916  return NI_TEST_RETCODE_FAILURE;
1917  }
1918  }
1919  ni_log(NI_LOG_INFO, "Encoder Receiving done.\n");
1921  } else if (p_api_param->low_delay_mode && p_enc_ctx->frame_num >= p_enc_ctx->pkt_num) {
1922  ni_log(NI_LOG_DEBUG, "low delay mode and NO pkt, keep reading ..\n");
1923  ni_usleep(200);
1924  goto receive_data;
1925  } else { //rx_size == 0 && !end_flag
1926  ni_log(NI_LOG_DEBUG, "no packet received from encoder, return EAGAIN and retry\n");
1927  return NI_TEST_RETCODE_EAGAIN;
1928  }
1929 
1930  ni_log(NI_LOG_DEBUG, "encoder_receive_data: success\n");
1931 
1932  return NI_TEST_RETCODE_SUCCESS;
1933 }
1934 
1935 /*!*****************************************************************************
1936  * \brief encoder session close
1937  *
1938  * \param
1939  *
1940  * \return 0 if successful, < 0 otherwise
1941  ******************************************************************************/
1943  ni_session_data_io_t *p_in_data,
1944  ni_session_data_io_t *p_out_data)
1945 {
1946  int ret = 0;
1948 
1949  ni_log(NI_LOG_DEBUG, "encoder_close_session - close encoder blk_io_handle %d device_handle %d\n", p_enc_ctx->blk_io_handle, p_enc_ctx->device_handle);
1950 #ifdef _WIN32
1951  ni_device_close(p_enc_ctx->device_handle);
1952 #elif __linux__
1953  ni_device_close(p_enc_ctx->device_handle);
1954  ni_device_close(p_enc_ctx->blk_io_handle);
1955 #endif
1956 
1957  if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_AV1 &&
1958  p_out_data->data.packet.av1_buffer_index)
1959  {
1960  ni_packet_buffer_free_av1(&(p_out_data->data.packet));
1961  }
1962  ni_frame_buffer_free(&(p_in_data->data.frame));
1963  ni_packet_buffer_free(&(p_out_data->data.packet));
1964  return ret;
1965 }
1966 
1968  ni_session_data_io_t *p_in_data,
1969  ni_session_data_io_t *p_out_data,
1970  int width, int height, ni_pix_fmt_t pix_fmt)
1971 {
1972  ni_retcode_t ret = 0;
1973  int bit_depth;
1974  int bit_depth_factor;
1975 
1976  ni_log(NI_LOG_DEBUG, "XCoder encode sequence change (reconfig): session_run_state %d\n", p_enc_ctx->session_run_state);
1977 
1978  switch (pix_fmt)
1979  {
1980  case NI_PIX_FMT_YUV420P:
1981  case NI_PIX_FMT_NV12:
1982  bit_depth = 8;
1983  bit_depth_factor = 1;
1984  break;
1986  case NI_PIX_FMT_P010LE:
1987  bit_depth = 10;
1988  bit_depth_factor = 2;
1989  break;
1990  default:
1991  bit_depth = 8;
1992  bit_depth_factor = 1;
1993  break;
1994  }
1995 
1996  ret = ni_device_session_sequence_change(p_enc_ctx, width, height, bit_depth_factor, NI_DEVICE_TYPE_ENCODER);
1997  if (NI_RETCODE_SUCCESS != ret)
1998  {
1999  ni_log(NI_LOG_ERROR, "Failed to send Sequence Change to Encoder Session (status = %d)\n", ret);
2000  return ret;
2001  }
2002 
2003  // update session context
2004  p_enc_ctx->bit_depth_factor = bit_depth_factor;
2005  p_enc_ctx->src_bit_depth = bit_depth;
2006  // xcoder demo only support little endian (for 10-bit pixel format)
2007  p_enc_ctx->src_endian = NI_FRAME_LITTLE_ENDIAN;
2008  p_enc_ctx->ready_to_close = 0;
2009  p_enc_ctx->frame_num = 0; // need to reset frame_num because pkt_num is set to 1 when header received after sequnce change, and low delay mode compares frame_num and pkt_num
2010  p_enc_ctx->pkt_num = 0; // also need to reset pkt_num because before header received, pkt_num > frame_num will also cause low delay mode stuck
2011  p_enc_ctx->pixel_format = p_in_data->data.frame.pixel_format;
2012  p_out_data->data.packet.end_of_stream = 0;
2013  p_in_data->data.frame.start_of_stream = 1;
2014  return ret;
2015 }
2016 
2018  ni_session_context_t *enc_ctx_list,
2019  ni_xcoder_params_t *p_api_param_list,
2020  int output_total, char p_enc_conf_params[][2048],
2021  char p_enc_conf_gop[][2048],
2022  ni_frame_t *p_ni_frame, int width, int height,
2023  int fps_num, int fps_den, int bitrate,
2024  int codec_format, ni_pix_fmt_t pix_fmt,
2025  int aspect_ratio_idc, int xcoder_guid,
2026  niFrameSurface1_t *p_surface, int multi_thread,
2027  bool check_zerocopy)
2028 {
2029  int i, ret = 0;
2030  int color_prim = NI_COL_PRI_UNSPECIFIED;
2031  int color_trc = NI_COL_TRC_UNSPECIFIED;
2032  int color_space = NI_COL_SPC_UNSPECIFIED;
2033  int sar_num = 0;
2034  int sar_den = 0;
2035  int video_full_range_flag = 0;
2036 
2037  if (p_ni_frame != NULL)
2038  {
2039  // open the encode session when the first frame arrives and the session
2040  // is not opened yet, with the source stream and user-configured encode
2041  // info both considered when constructing VUI in the stream headers
2042  color_prim = p_ni_frame->color_primaries;
2043  color_trc = p_ni_frame->color_trc;
2044  color_space = p_ni_frame->color_space;
2045  sar_num = p_ni_frame->sar_width;
2046  sar_den = p_ni_frame->sar_height;
2047  video_full_range_flag = p_ni_frame->video_full_range_flag;
2048 
2049  // calculate the source fps and set it as the default target fps, based
2050  // on the timing_info passed in from the decoded frame
2051  if (p_ni_frame->vui_num_units_in_tick && p_ni_frame->vui_time_scale)
2052  {
2053  if (NI_CODEC_FORMAT_H264 == p_ni_frame->src_codec)
2054  {
2055  if (0 == p_ni_frame->vui_time_scale % 2)
2056  {
2057  fps_num = (int)(p_ni_frame->vui_time_scale / 2);
2058  fps_den = (int)(p_ni_frame->vui_num_units_in_tick);
2059  } else
2060  {
2061  fps_num = (int)(p_ni_frame->vui_time_scale);
2062  fps_den = (int)(2 * p_ni_frame->vui_num_units_in_tick);
2063  }
2064  } else if (NI_CODEC_FORMAT_H265 == p_ni_frame->src_codec)
2065  {
2066  fps_num = p_ni_frame->vui_time_scale;
2067  fps_den = p_ni_frame->vui_num_units_in_tick;
2068  }
2069  }
2070  }
2071 
2072  for (i = 0; i < output_total; i++)
2073  {
2074 
2075  if(!p_ctx->enc_pts_queue[i])
2076  {
2077  p_ctx->enc_pts_queue[i] = (ni_pts_queue *)calloc(1, sizeof(ni_pts_queue));
2078  if(!p_ctx->enc_pts_queue[i])
2079  {
2080  ni_log(NI_LOG_ERROR, "Failed to allocate ni_pts_queue\n");
2081  return -1;
2082  }
2083  }
2084 
2085  // set up encoder p_config, using some info from source
2086  ret = ni_encoder_init_default_params(&p_api_param_list[i], fps_num,
2087  fps_den, bitrate, width, height,
2088  enc_ctx_list[i].codec_format);
2089  if (ret < 0)
2090  {
2091  ni_log(NI_LOG_ERROR, "Error encoder[%d] init default set up error\n", i);
2092  return -1;
2093  }
2094 
2095  // check and set ni_encoder_params from --xcoder-params
2096  // Note: the parameter setting has to be in this order so that user
2097  // configured values can overwrite the source/default ones if
2098  // desired.
2099  if (ni_retrieve_xcoder_params(p_enc_conf_params[i],
2100  &p_api_param_list[i], &enc_ctx_list[i]))
2101  {
2102  ni_log(NI_LOG_ERROR, "Error: encoder[%d] p_config parsing error\n", i);
2103  return -1;
2104  }
2105 
2106  if (ni_retrieve_xcoder_gop(p_enc_conf_gop[i],
2107  &p_api_param_list[i], &enc_ctx_list[i]))
2108  {
2109  ni_log(NI_LOG_ERROR, "Error: encoder[%d] p_config_gop parsing error\n", i);
2110  return -1;
2111  }
2112 
2113  // set async mode in enc_ctx if encoding is multi-threaded
2114  if (multi_thread)
2115  {
2116  ni_log(NI_LOG_INFO, "Encoder[%d] is multi-threaded, set async mode "
2117  "in the session context!\n", i);
2118  enc_ctx_list[i].async_mode = 1;
2119  p_api_param_list[i].cfg_enc_params.enable_acq_limit = 1;
2120  }
2121 
2122  // check color primaries configuration
2123  if (color_prim != p_api_param_list[i].color_primaries &&
2124  NI_COL_PRI_UNSPECIFIED != p_api_param_list[i].color_primaries)
2125  {
2126  ni_log(NI_LOG_DEBUG, "Encoder[%d] user-configured color primaries "
2127  "%d to overwrite source %d\n",
2128  i, p_api_param_list[i].color_primaries, color_prim);
2129  color_prim = p_api_param_list[i].color_primaries;
2130  }
2131 
2132  // check color transfer characteristic configuration
2133  if (color_trc != p_api_param_list[i].color_transfer_characteristic &&
2134  NI_COL_TRC_UNSPECIFIED != p_api_param_list[i].color_transfer_characteristic)
2135  {
2136  ni_log(NI_LOG_DEBUG, "Encoder[%d] user-configured color trc %d to "
2137  "overwrite source %d\n", i,
2138  p_api_param_list[i].color_transfer_characteristic, color_trc);
2139  color_trc = p_api_param_list[i].color_transfer_characteristic;
2140  }
2141 
2142  // check color space configuration
2143  if (color_space != p_api_param_list[i].color_space &&
2144  NI_COL_SPC_UNSPECIFIED != p_api_param_list[i].color_space)
2145  {
2146  ni_log(NI_LOG_DEBUG, "Encoder[%d] user-configured color space %d "
2147  "to overwrite source %d\n",
2148  i, p_api_param_list[i].color_space, color_space);
2149  color_space = p_api_param_list[i].color_space;
2150  }
2151 
2152  // check video full range flag configuration
2153  if (p_api_param_list[i].video_full_range_flag >= 0)
2154  {
2155  ni_log(NI_LOG_DEBUG, "Encoder[%d] user-configured video full range "
2156  "flag %d\n", i, p_api_param_list[i].video_full_range_flag);
2157  video_full_range_flag = p_api_param_list[i].video_full_range_flag;
2158  }
2159 
2160  // check aspect ratio indicator configuration
2161  if (aspect_ratio_idc > 0 && aspect_ratio_idc < NI_NUM_PIXEL_ASPECT_RATIO)
2162  {
2163  sar_num = ni_h264_pixel_aspect_list[aspect_ratio_idc].num;
2164  sar_den = ni_h264_pixel_aspect_list[aspect_ratio_idc].den;
2165  } else if (p_api_param_list[i].sar_denom)
2166  {
2167  sar_num = p_api_param_list[i].sar_num;
2168  sar_den = p_api_param_list[i].sar_denom;
2169  }
2170 
2171  // check hwframe configuration
2172  if (p_surface != NULL)
2173  {
2174  //Items in this else condition could be improved by being handled in libxcoder
2175  enc_ctx_list[i].hw_action = NI_CODEC_HW_ENABLE;
2176  p_api_param_list[i].hwframes = 1;
2177  enc_ctx_list[i].sender_handle =
2178  (ni_device_handle_t)(int64_t)p_surface->device_handle;
2179  p_api_param_list[i].rootBufId = p_surface->ui16FrameIdx;
2180  }
2181 
2182  // VUI setting including color setting is done by specifying them in the
2183  // encoder config
2184  p_api_param_list[i].cfg_enc_params.colorDescPresent = 0;
2185  if ((color_prim != NI_COL_PRI_UNSPECIFIED) ||
2186  (color_space != NI_COL_SPC_UNSPECIFIED) ||
2187  (color_trc != NI_COL_TRC_UNSPECIFIED))
2188  {
2189  p_api_param_list[i].cfg_enc_params.colorDescPresent = 1;
2190  }
2191  p_api_param_list[i].cfg_enc_params.colorPrimaries = color_prim;
2192  p_api_param_list[i].cfg_enc_params.colorTrc = color_trc;
2193  p_api_param_list[i].cfg_enc_params.colorSpace = color_space;
2194  p_api_param_list[i].cfg_enc_params.videoFullRange = video_full_range_flag;
2195  p_api_param_list[i].cfg_enc_params.aspectRatioWidth = sar_num;
2196  p_api_param_list[i].cfg_enc_params.aspectRatioHeight = sar_den;
2197 
2198  ret = encoder_open_session(&enc_ctx_list[i], codec_format, xcoder_guid,
2199  &p_api_param_list[i], width, height,
2200  pix_fmt, check_zerocopy);
2201  if (ret != 0)
2202  {
2203  ni_log(NI_LOG_ERROR, "Error encoder[%d] open session failed!\n", i);
2204  return -1;
2205  }
2206 
2207  ni_init_pts_queue(p_ctx->enc_pts_queue[i]);
2208  p_ctx->pts[i] = 0;
2209  ni_prepare_pts_queue(p_ctx->enc_pts_queue[i], &p_api_param_list[i], p_ctx->pts[i]);
2210  }
2211 
2212  return ret;
2213 }
2214 
2216  ni_session_context_t *enc_ctx_list,
2217  ni_session_data_io_t *in_frame,
2218  ni_session_data_io_t *pkt, int width, int height,
2219  int output_total, FILE **pfs_list)
2220 {
2221  int i, recycle_index;
2222  int recv_fin_flag = NI_TEST_RETCODE_SUCCESS;
2223  uint32_t prev_num_pkt[MAX_OUTPUT_FILES] = {0};
2224  ni_session_data_io_t *p_out_pkt = pkt;
2225 
2226  for (i = 0; i < output_total; i++)
2227  {
2228  if (enc_ctx_list[i].codec_format == NI_CODEC_FORMAT_AV1)
2229  {
2230  p_out_pkt = &pkt[i];
2231  }
2232  p_out_pkt->data.packet.end_of_stream = 0;
2233  prev_num_pkt[i] = p_ctx->num_packets_received[i];
2234 
2235  p_ctx->curr_enc_index = i;
2236  recv_fin_flag = encoder_receive_data(p_ctx, &enc_ctx_list[i], p_out_pkt, width,
2237  height, pfs_list[i], in_frame);
2238 
2239  recycle_index = p_out_pkt->data.packet.recycle_index;
2240  if (prev_num_pkt[i] < p_ctx->num_packets_received[i] &&
2241  enc_ctx_list[i].hw_action && recycle_index > 0 &&
2242  recycle_index < NI_GET_MAX_HWDESC_FRAME_INDEX(enc_ctx_list[i].ddr_config))
2243  {
2244  //encoder only returns valid recycle index
2245  //when there's something to recycle.
2246  //This range is suitable for all memory bins
2247  ni_hw_frame_unref(recycle_index);
2248  } else
2249  {
2250  ni_log(NI_LOG_DEBUG, "enc %d recv, prev_num_pkt %u "
2251  "number_of_packets_list %u recycle_index %u\n", i,
2252  prev_num_pkt[i], p_ctx->num_packets_received[i], recycle_index);
2253  }
2254 
2255  if (prev_num_pkt[i] < p_ctx->num_packets_received[i] &&
2256  enc_ctx_list[i].codec_format == NI_CODEC_FORMAT_AV1 &&
2257  p_ctx->num_packets_received[i] > 1)
2258  {
2259  // For low delay mode encoding, only one packet is received for one
2260  // frame sent. For non low delay mode, there will be multiple
2261  // packets received for one frame sent. So we need to read out all
2262  // the packets encoded.
2263  ni_xcoder_params_t *p_api_param =
2264  (ni_xcoder_params_t *)enc_ctx_list[i].p_session_config;
2265  if (!p_api_param->low_delay_mode)
2266  {
2267  i--;
2268  continue;
2269  }
2270  }
2271 
2272  p_ctx->enc_eos_received[i] = p_out_pkt->data.packet.end_of_stream;
2273 
2274  if (recv_fin_flag < 0)
2275  {
2276  ni_log(NI_LOG_DEBUG, "enc %d error, quit !\n", i);
2277  break;
2278  } else if (recv_fin_flag == NI_TEST_RETCODE_EAGAIN)
2279  {
2280  ni_usleep(100);
2281  }
2282  }
2283 
2284  return recv_fin_flag;
2285 }
2286 
2287 void encoder_stat_report_and_close(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx_list, int output_total)
2288 {
2289  int i;
2290  int nb_recycled;
2291  uint64_t current_time;
2292 
2294 
2295  nb_recycled = scan_and_clean_hwdescriptors();
2296 
2297  for (i = 0; i < output_total; i++)
2298  {
2299  ni_log(NI_LOG_ERROR, "Encoder %d closing, Got: Packets=%u FPS=%.2f Total bytes %llu\n",
2300  (int)i, p_ctx->num_packets_received[i],
2301  (float)p_enc_ctx_list[i].frame_num / (float)(current_time - p_ctx->start_time) * (float)1000000000,
2302  p_ctx->enc_total_bytes_received[i]);
2303 
2304  ni_device_session_close(&p_enc_ctx_list[i], 1, NI_DEVICE_TYPE_ENCODER);
2305  }
2306 
2307  ni_log(NI_LOG_DEBUG, "Cleanup recycled %d internal buffers\n",
2308  nb_recycled);
2309 }
2310 
2311 void *encoder_send_thread(void *args)
2312 {
2313  enc_send_param_t *p_enc_send_param = args;
2314  ni_demo_context_t *p_ctx = p_enc_send_param->p_ctx;
2315  ni_session_context_t *p_enc_ctx_list = p_enc_send_param->p_enc_ctx;
2316  ni_test_frame_list_t *frame_list = p_enc_send_param->frame_list;
2317  ni_session_data_io_t *p_dec_frame = NULL;
2318  ni_session_data_io_t enc_in_frame = {0};
2319  ni_frame_t *p_ni_frame = NULL;
2320  niFrameSurface1_t *p_surface;
2321  int i, ret = 0;
2322 
2323  ni_log(NI_LOG_INFO, "%s start\n", __func__);
2324 
2325  for (;;)
2326  {
2327  while (frame_list_is_empty(frame_list) && !p_ctx->end_all_threads)
2328  {
2329  ni_usleep(100);
2330  }
2331 
2332  if (p_ctx->end_all_threads)
2333  {
2334  break;
2335  }
2336 
2337  p_dec_frame = &frame_list->frames[frame_list->head];
2338  p_ni_frame = &p_dec_frame->data.frame;
2339 
2340  for (i = 0; i < p_enc_send_param->output_total; i++)
2341  {
2342  p_ctx->curr_enc_index = i;
2343  ret = encoder_send_data2(p_ctx, &p_enc_ctx_list[i], p_dec_frame,
2344  &enc_in_frame,
2345  p_enc_send_param->output_width,
2346  p_enc_send_param->output_height);
2347  if (ret < 0) //Error
2348  {
2349  if (p_enc_ctx_list[i].hw_action)
2350  {
2351  //pre close cleanup will clear it out
2352  p_surface = (niFrameSurface1_t *)p_ni_frame->p_data[3];
2353  ni_hw_frame_ref(p_surface);
2354  } else
2355  {
2356  ni_decoder_frame_buffer_free(p_ni_frame);
2357  }
2358  frame_list_drain(frame_list);
2359  ni_log(NI_LOG_ERROR, "Error: encoder send frame failed\n");
2360  break;
2361  } else if (ret == NI_TEST_RETCODE_EAGAIN) {
2362  ni_usleep(100);
2363  i--; //resend frame
2364  continue;
2365  } else if (p_enc_ctx_list[0].hw_action && !p_ctx->enc_eos_sent[i])
2366  {
2367  p_surface = (niFrameSurface1_t *)p_ni_frame->p_data[3];
2368  ni_hw_frame_ref(p_surface);
2369  }
2370  }
2371 
2372  if (ret < 0)
2373  {
2374  break;
2375  } else if (p_enc_ctx_list[0].hw_action)
2376  {
2377  ni_frame_wipe_aux_data(p_ni_frame); //reuse buffer
2378  } else
2379  {
2380  ni_decoder_frame_buffer_free(p_ni_frame);
2381  }
2382  frame_list_drain(frame_list);
2383 
2384  if (p_enc_send_param->p_ctx->enc_eos_sent[0]) // eos
2385  {
2386  ni_log(NI_LOG_INFO, "%s EOS sent\n", __func__);
2387  break;
2388  }
2389  }
2390 
2391  ni_frame_buffer_free(&enc_in_frame.data.frame);
2392 
2393  // Broadcast all codec threads to quit on exception such as NVMe IO
2394  if (ret < 0)
2395  {
2396  p_ctx->end_all_threads = 1;
2397  }
2398 
2399  ni_log(NI_LOG_TRACE, "%s exit\n", __func__);
2400  return (void *)(long)ret;
2401 }
2402 
2403 void *encoder_receive_thread(void *args)
2404 {
2405  enc_recv_param_t *p_enc_recv_param = args;
2406  ni_demo_context_t *p_ctx = p_enc_recv_param->p_ctx;
2407  ni_session_context_t *p_enc_ctx = p_enc_recv_param->p_enc_ctx;
2408  ni_session_data_io_t out_packet[MAX_OUTPUT_FILES] = {0};
2409  int i, ret = 0;
2410  int end_of_all_streams = 0;
2411  uint64_t current_time, previous_time = p_ctx->start_time;
2412 
2413  ni_log(NI_LOG_INFO, "encoder_receive_thread start\n");
2414 
2415  while (!end_of_all_streams && ret >= 0 && !p_ctx->end_all_threads)
2416  {
2417  ret = encoder_receive(p_ctx, p_enc_ctx,
2418  &p_enc_recv_param->frame_list->frames[p_enc_recv_param->frame_list->head],
2419  out_packet, p_enc_recv_param->output_width,
2420  p_enc_recv_param->output_height, p_enc_recv_param->output_total,
2421  p_enc_recv_param->p_file);
2422  for (i = 0; ret >= 0 && i < p_enc_recv_param->output_total; i++)
2423  {
2424  if (!p_ctx->enc_eos_received[i])
2425  {
2426  ni_log(NI_LOG_DEBUG, "enc %d continues to read!\n", i);
2427  end_of_all_streams = 0;
2428  break;
2429  } else
2430  {
2431  ni_log(NI_LOG_DEBUG, "enc %d eos !\n", i);
2432  end_of_all_streams = 1;
2433  }
2434  }
2435 
2437  if (current_time - previous_time >= (uint64_t)1000000000) {
2438  for (i = 0; i < p_enc_recv_param->output_total; i++)
2439  {
2440  ni_log(NI_LOG_INFO, "Encoder %d stats: received %u packets, fps %.2f, total bytes %u\n",
2441  i, p_ctx->num_packets_received[i],
2442  (float)p_enc_ctx[i].frame_num / (float)(current_time - p_ctx->start_time) * (float)1000000000,
2443  p_ctx->enc_total_bytes_received[i]);
2444  }
2446  }
2447  }
2448 
2449  for (i = 0; i < p_enc_recv_param->output_total; i++)
2450  {
2451  ni_packet_buffer_free(&out_packet[i].data.packet);
2452  }
2453 
2454  // Broadcast all codec threads to quit on exception such as NVMe IO.
2455  if (ret < 0)
2456  {
2457  p_ctx->end_all_threads = 1;
2458  }
2459 
2460  ni_log(NI_LOG_TRACE, "%s exit\n", __func__);
2461  return (void *)(long)ret;
2462 }
2463 
2465 {
2466  q->front = 0;
2467  q->rear = 0;
2468  q->size = 0;
2469 }
2471 {
2472  return q->size == 0;
2473 }
2475 {
2476  return q->size == NI_MAX_PTS_QUEUE_SIZE;
2477 }
2478 int ni_pts_enqueue(ni_pts_queue *q, int value)
2479 {
2480  if(ni_pts_queue_full(q))
2481  {
2482  ni_log(NI_LOG_ERROR, "Failed to enqueue, ni_pts_queue is full\n");
2483  return 0;
2484  }
2485 
2486  q->data[q->rear] = value;
2487  q->rear = (q->rear + 1) % NI_MAX_PTS_QUEUE_SIZE;
2488  ++q->size;
2489  return 1;
2490 }
2491 int ni_pts_dequeue(ni_pts_queue *q, int *value)
2492 {
2493  if(ni_pts_queue_empty(q))
2494  {
2495  ni_log(NI_LOG_ERROR, "Failed to dequeue, ni_pts_queue is empty\n");
2496  }
2497  *value = q->data[q->front];
2498  q->front = (q->front + 1) % NI_MAX_PTS_QUEUE_SIZE;
2499  --q->size;
2500  return 1;
2501 }
2502 
2503 void ni_prepare_pts_queue(ni_pts_queue *q, ni_xcoder_params_t *enc_param, int pts_start)
2504 {
2505  int dtsOffset = 0;
2506 
2507  switch (enc_param->cfg_enc_params.gop_preset_index)
2508  {
2509  /* dtsOffset is the max number of non-reference frames in a GOP
2510  * (derived from x264/5 algo) In case of IBBBP the first dts of the I
2511  * frame should be input_pts-(3*ticks_per_frame) In case of IBP the
2512  * first dts of the I frame should be input_pts-(1*ticks_per_frame)
2513  * thus we ensure pts>dts in all cases
2514  * */
2515  case 1:
2516  case 9:
2517  case 10:
2518  dtsOffset = 0;
2519  break;
2520  /* ts requires dts/pts of I fraem not same when there are B frames in
2521  * streams */
2522  case 3:
2523  case 4:
2524  case 7:
2525  dtsOffset = 1;
2526  break;
2527  case 5:
2528  dtsOffset = 2;
2529  break;
2530  case -1: // adaptive GOP
2531  case 8:
2532  dtsOffset = 3;
2533  break;
2534  default:
2535  dtsOffset = 7;
2536  break;
2537  }
2538 
2540  {
2541  int dts_offset;
2542  dtsOffset = 0;
2543  int has_b_frame = 0;
2544  for (int idx = 0;
2546  idx++)
2547  {
2548  if (enc_param->cfg_enc_params.custom_gop_params.pic_param[idx].poc_offset < idx + 1)
2549  {
2550  dts_offset = (idx + 1) - enc_param->cfg_enc_params.custom_gop_params.pic_param[idx].poc_offset;
2551  if (dtsOffset < dts_offset)
2552  {
2553  dtsOffset = dts_offset;
2554  }
2555  }
2556 
2557  if (!has_b_frame &&
2559  {
2560  has_b_frame = 1;
2561  }
2562  }
2563 
2564  if (has_b_frame && !dtsOffset)
2565  {
2566  dtsOffset = 1;
2567  }
2568  }
2569 
2570  for (int i = 0; i < dtsOffset; ++i)
2571  {
2572  ni_pts_enqueue(q, i - dtsOffset + pts_start);
2573  }
2574 }
XCODER_TEST_RECONF_LTR_INTERVAL_API
@ XCODER_TEST_RECONF_LTR_INTERVAL_API
Definition: ni_device_api.h:1772
_ni_xcoder_params::reconf_demo_mode
int reconf_demo_mode
Definition: ni_device_api.h:2761
_ni_long_term_ref::use_long_term_ref
uint8_t use_long_term_ref
Definition: ni_device_api.h:693
_ni_xcoder_params::fps_denominator
uint32_t fps_denominator
Definition: ni_device_api.h:2749
_ni_xcoder_params::luma_linesize
int luma_linesize
Definition: ni_device_api.h:2814
NI_PIX_FMT_BGRA
@ NI_PIX_FMT_BGRA
Definition: ni_device_api.h:268
NI_CODEC_FORMAT_JPEG
@ NI_CODEC_FORMAT_JPEG
Definition: ni_device_api.h:916
NI_MAX_TX_SZ
#define NI_MAX_TX_SZ
Definition: ni_defs.h:261
_ni_encoder_cfg_params::ver_offset
int ver_offset
Definition: ni_device_api.h:2412
NI_FRAME_AUX_DATA_MAX_FRAME_SIZE
@ NI_FRAME_AUX_DATA_MAX_FRAME_SIZE
Definition: ni_device_api.h:568
encoder_send_data
int encoder_send_data(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_in_data, void *yuv_buf, int input_video_width, int input_video_height, int is_last_input)
Send encoder input data, read from input file.
Definition: ni_encode_utils.c:735
NI_DEVICE_TYPE_ENCODER
@ NI_DEVICE_TYPE_ENCODER
Definition: ni_defs.h:359
ni_pts_queue_full
int ni_pts_queue_full(ni_pts_queue *q)
Definition: ni_encode_utils.c:2474
XCODER_TEST_RECONF_CRF_FLOAT
@ XCODER_TEST_RECONF_CRF_FLOAT
Definition: ni_device_api.h:1762
encoder_reinit_session
int encoder_reinit_session(ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_in_data, ni_session_data_io_t *p_out_data)
Reopen or reconfig encoder upon sequence change.
Definition: ni_encode_utils.c:1418
_ni_demo_context::av1_muxed_num_packets
uint32_t av1_muxed_num_packets[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:146
ni_pix_fmt_t
ni_pix_fmt_t
Definition: ni_device_api.h:261
_ni_encoder_cfg_params::hor_offset
int hor_offset
Definition: ni_device_api.h:2411
XCODER_TEST_CRF_API
@ XCODER_TEST_CRF_API
Definition: ni_device_api.h:1777
ni_init_pts_queue
void ni_init_pts_queue(ni_pts_queue *q)
Definition: ni_encode_utils.c:2464
ni_frame_buffer_free
ni_retcode_t ni_frame_buffer_free(ni_frame_t *p_frame)
Free frame buffer that was previously allocated with either ni_frame_buffer_alloc or ni_encoder_frame...
Definition: ni_device_api.c:3562
_ni_packet::pts
long long pts
Definition: ni_device_api.h:2858
_ni_frame::sar_width
uint16_t sar_width
Definition: ni_device_api.h:2713
XCODER_TEST_RECONF_MAX_FRAME_SIZE
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE
Definition: ni_device_api.h:1759
ni_hw_frame_ref
void ni_hw_frame_ref(const niFrameSurface1_t *p_surface)
Definition: ni_generic_utils.c:657
ni_retrieve_xcoder_gop
int ni_retrieve_xcoder_gop(char xcoderGop[], ni_xcoder_params_t *params, ni_session_context_t *ctx)
Retrieve custom gop config values from –xcoder-gop.
Definition: ni_util.c:3861
encoder_stat_report_and_close
void encoder_stat_report_and_close(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx_list, int output_total)
Definition: ni_encode_utils.c:2287
_ni_packet::recycle_index
int recycle_index
Definition: ni_device_api.h:2866
enc_recv_param::p_file
FILE ** p_file
Definition: ni_encode_utils.h:53
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.
XCODER_TEST_RECONF_LTR_INTERVAL
@ XCODER_TEST_RECONF_LTR_INTERVAL
Definition: ni_device_api.h:1756
XCODER_TEST_RECONF_FRAMERATE_API
@ XCODER_TEST_RECONF_FRAMERATE_API
Definition: ni_device_api.h:1774
ni_enc_copy_aux_data
void ni_enc_copy_aux_data(ni_session_context_t *p_enc_ctx, ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame, ni_codec_format_t codec_format, const uint8_t *mdcv_data, const uint8_t *cll_data, const uint8_t *cc_data, const uint8_t *udu_data, const uint8_t *hdrp_data, int is_hwframe, int is_semiplanar)
Copy auxiliary data that should be sent together with this frame to encoder.
Definition: ni_av_codec.c:2266
_ni_vui_hrd
Definition: ni_device_api.h:656
_ni_rc_min_max_qp::minQpI
int32_t minQpI
Definition: ni_device_api.h:708
ni_device_close
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
Definition: ni_device_api.c:503
SESSION_RUN_STATE_FLUSHING
@ SESSION_RUN_STATE_FLUSHING
Definition: ni_device_api.h:1183
encoder_send_thread
void * encoder_send_thread(void *args)
Definition: ni_encode_utils.c:2311
ni_force_idr_frame_type
ni_retcode_t ni_force_idr_frame_type(ni_session_context_t *p_ctx)
Force next frame to be IDR frame during encoding.
Definition: ni_device_api.c:10080
XCODER_TEST_RECONF_RC_MIN_MAX_QP_API
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP_API
Definition: ni_device_api.h:1776
_ni_session_context::session_id
uint32_t session_id
Definition: ni_device_api.h:1482
ni_hw_frame_unref
void ni_hw_frame_unref(uint16_t hwframe_index)
Definition: ni_generic_utils.c:678
_ni_xcoder_params::source_width
int source_width
Definition: ni_device_api.h:2753
_ni_frame::reconf_len
unsigned int reconf_len
Definition: ni_device_api.h:2681
ni_reconfig_intraprd
ni_retcode_t ni_reconfig_intraprd(ni_session_context_t *p_ctx, int32_t intra_period)
Reconfigure intraPeriod dynamically during encoding.
Definition: ni_device_api.c:9997
_ni_pts_queue::size
int size
Definition: ni_generic_utils.h:117
ni_generic_utils.h
_ni_session_context::target_bitrate
int32_t target_bitrate
Definition: ni_device_api.h:1601
ni_device_session_sequence_change
ni_retcode_t ni_device_session_sequence_change(ni_session_context_t *p_ctx, int width, int height, int bit_depth_factor, ni_device_type_t device_type)
Send sequence change information to device.
Definition: ni_device_api.c:11410
NI_CODEC_HW_NONE
@ NI_CODEC_HW_NONE
Definition: ni_device_api.h:941
NI_PIX_FMT_YUV420P
@ NI_PIX_FMT_YUV420P
Definition: ni_device_api.h:263
_ni_rc_min_max_qp
Definition: ni_device_api.h:706
_ni_packet::end_of_stream
uint32_t end_of_stream
Definition: ni_device_api.h:2861
_ni_demo_context::enc_pts_queue
ni_pts_queue * enc_pts_queue[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:162
_ni_session_data_io::packet
ni_packet_t packet
Definition: ni_device_api.h:2901
_ni_frame::src_codec
ni_codec_format_t src_codec
Definition: ni_device_api.h:2630
_ni_packet::dts
long long dts
Definition: ni_device_api.h:2857
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:439
XCODER_TEST_RECONF_SLICE_ARG
@ XCODER_TEST_RECONF_SLICE_ARG
Definition: ni_device_api.h:1765
_ni_gop_params::poc_offset
int poc_offset
Definition: ni_device_api.h:1968
_ni_framerate::framerate_denom
int32_t framerate_denom
Definition: ni_device_api.h:703
ni_encoder_sw_frame_buffer_alloc
ni_retcode_t ni_encoder_sw_frame_buffer_alloc(bool planar, ni_frame_t *p_frame, int video_width, int video_height, int linesize[], int alignment, int extra_len, bool alignment_2pass_wa)
This API is a wrapper for ni_encoder_frame_buffer_alloc(), used for planar pixel formats,...
Definition: ni_device_api.c:3532
ni_reconfig_framerate
ni_retcode_t ni_reconfig_framerate(ni_session_context_t *p_ctx, ni_framerate_t *framerate)
Reconfigure framerate dynamically during encoding.
Definition: ni_device_api.c:10195
_ni_frame::color_trc
uint8_t color_trc
Definition: ni_device_api.h:2709
NI_2PASS_ENCODE_MIN_WIDTH
#define NI_2PASS_ENCODE_MIN_WIDTH
Definition: ni_device_api.h:128
ni_encode_utils.h
XCODER_TEST_RECONF_CRF
@ XCODER_TEST_RECONF_CRF
Definition: ni_device_api.h:1761
NI_INVALID_SESSION_ID
#define NI_INVALID_SESSION_ID
Definition: ni_device_api.h:111
NI_FRAME_AUX_DATA_CRF
@ NI_FRAME_AUX_DATA_CRF
Definition: ni_device_api.h:576
_ni_xcoder_params::color_primaries
int color_primaries
Definition: ni_device_api.h:2786
_ni_session_context::ori_chroma_linesize
int ori_chroma_linesize
Definition: ni_device_api.h:1683
current_time
struct timeval current_time
Definition: ni_p2p_read_test.c:80
ni_retrieve_xcoder_params
int ni_retrieve_xcoder_params(char xcoderParams[], ni_xcoder_params_t *params, ni_session_context_t *ctx)
retrieve encoder config parameter values from –xcoder-params
Definition: ni_util.c:3787
prep_reconf_demo_data
void prep_reconf_demo_data(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx, ni_frame_t *frame)
Definition: ni_encode_utils.c:124
XCODER_TEST_RECONF_VUI_HRD
@ XCODER_TEST_RECONF_VUI_HRD
Definition: ni_device_api.h:1751
ni_gettime_ns
uint64_t ni_gettime_ns(void)
Definition: ni_util.c:1998
MAX_OUTPUT_FILES
#define MAX_OUTPUT_FILES
Definition: ni_generic_utils.h:48
ni_enc_write_from_yuv_buffer
int ni_enc_write_from_yuv_buffer(ni_session_context_t *p_ctx, ni_frame_t *p_enc_frame, uint8_t *p_yuv_buffer)
Send an input data frame to the encoder with YUV data given in the inputs.
Definition: ni_av_codec.c:2624
XCODER_TEST_RECONF_RC_MIN_MAX_QP_REDUNDANT
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP_REDUNDANT
Definition: ni_device_api.h:1760
_ni_xcoder_params::rootBufId
int rootBufId
Definition: ni_device_api.h:2805
_ni_frame::vui_num_units_in_tick
uint32_t vui_num_units_in_tick
Definition: ni_device_api.h:2715
ni_set_frame_ref_invalid
ni_retcode_t ni_set_frame_ref_invalid(ni_session_context_t *p_ctx, int32_t frame_num)
Set frame reference invalidation.
Definition: ni_device_api.c:10170
XCODER_TEST_RECONF_FRAMERATE
@ XCODER_TEST_RECONF_FRAMERATE
Definition: ni_device_api.h:1758
ni_av_codec.h
Audio/video related utility definitions.
NI_2PASS_ENCODE_MIN_HEIGHT
#define NI_2PASS_ENCODE_MIN_HEIGHT
Definition: ni_device_api.h:129
ni_reconfig_crf
ni_retcode_t ni_reconfig_crf(ni_session_context_t *p_ctx, int32_t crf)
Reconfigure crf value dynamically during encoding.
Definition: ni_device_api.c:10389
_ni_encoder_cfg_params::enable_acq_limit
int enable_acq_limit
Definition: ni_device_api.h:2443
XCODER_TEST_RECONF_INTRAPRD
@ XCODER_TEST_RECONF_INTRAPRD
Definition: ni_device_api.h:1750
ni_packet_buffer_free
ni_retcode_t ni_packet_buffer_free(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc.
Definition: ni_device_api.c:3844
_ni_session_context::blk_io_handle
ni_device_handle_t blk_io_handle
Definition: ni_device_api.h:1467
enc_recv_param::p_ctx
ni_demo_context_t * p_ctx
Definition: ni_encode_utils.h:49
_ni_demo_context::p_av1_seq_header
uint8_t * p_av1_seq_header[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:147
_ni_encoder_cfg_params::roi_enable
int roi_enable
Definition: ni_device_api.h:2271
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_demo_context::end_all_threads
uint8_t end_all_threads
Definition: ni_generic_utils.h:122
_ni_demo_context::enc_sos_sent
int enc_sos_sent[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:157
_ni_gop_params::pic_type
int pic_type
Definition: ni_device_api.h:1972
NI_MULTICORE_ENCODE_MIN_HEIGHT
#define NI_MULTICORE_ENCODE_MIN_HEIGHT
Definition: ni_device_api.h:132
NI_FRAME_AUX_DATA_SLICE_ARG
@ NI_FRAME_AUX_DATA_SLICE_ARG
Definition: ni_device_api.h:592
_ni_encoder_cfg_params::gop_preset_index
int gop_preset_index
Definition: ni_device_api.h:2265
_ni_frame::sei_user_data_unreg_len
unsigned int sei_user_data_unreg_len
Definition: ni_device_api.h:2670
_ni_packet::av1_p_data
uint8_t * av1_p_data[MAX_AV1_ENCODER_GOP_NUM]
Definition: ni_device_api.h:2875
ni_copy_hw_descriptors
void ni_copy_hw_descriptors(uint8_t *p_dst[NI_MAX_NUM_DATA_POINTERS], uint8_t *p_src[NI_MAX_NUM_DATA_POINTERS])
Copy Descriptor data to Netint HW descriptor frame layout to be sent to encoder for encoding....
Definition: ni_util.c:3576
_ni_pts_queue::data
int data[NI_MAX_PTS_QUEUE_SIZE]
Definition: ni_generic_utils.h:114
encoder_sequence_change
int encoder_sequence_change(ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_in_data, ni_session_data_io_t *p_out_data, int width, int height, ni_pix_fmt_t pix_fmt)
Definition: ni_encode_utils.c:1967
_ni_xcoder_params::roi_demo_mode
int roi_demo_mode
Definition: ni_device_api.h:2760
_ni_session_context::src_endian
int src_endian
Definition: ni_device_api.h:1495
_ni_packet::av1_buffer_size
uint32_t av1_buffer_size[MAX_AV1_ENCODER_GOP_NUM]
Definition: ni_device_api.h:2876
_ni_frame::sei_total_len
unsigned int sei_total_len
Definition: ni_device_api.h:2655
ni_reconfig_vbv_value
ni_retcode_t ni_reconfig_vbv_value(ni_session_context_t *p_ctx, int32_t vbvMaxRate, int32_t vbvBufferSize)
Reconfigure vbv buffer size and vbv max rate dynamically during encoding.
Definition: ni_device_api.c:10506
_ni_xcoder_params::video_full_range_flag
int video_full_range_flag
Definition: ni_device_api.h:2791
_ni_encoder_change_params_t::aspectRatioHeight
uint16_t aspectRatioHeight
Definition: ni_device_api.h:1026
_ni_encoder_change_params_t::enable_option
uint32_t enable_option
Definition: ni_device_api.h:986
XCODER_TEST_RECONF_VBV
@ XCODER_TEST_RECONF_VBV
Definition: ni_device_api.h:1763
_ni_encoder_cfg_params::aspectRatioWidth
int aspectRatioWidth
Definition: ni_device_api.h:2254
XCODER_TEST_INVALID_REF_FRAME
@ XCODER_TEST_INVALID_REF_FRAME
Definition: ni_device_api.h:1757
NI_TEST_RETCODE_NEXT_INPUT
#define NI_TEST_RETCODE_NEXT_INPUT
Definition: ni_generic_utils.h:54
ni_pts_queue_empty
int ni_pts_queue_empty(ni_pts_queue *q)
Definition: ni_encode_utils.c:2470
_ni_packet::av1_data_len
uint32_t av1_data_len[MAX_AV1_ENCODER_GOP_NUM]
Definition: ni_device_api.h:2877
_ni_session_context::bit_depth_factor
int bit_depth_factor
Definition: ni_device_api.h:1496
XCODER_TEST_RECONF_RC_MIN_MAX_QP_API_REDUNDANT
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP_API_REDUNDANT
Definition: ni_device_api.h:1771
_ni_encoder_change_params_t
This is a data structure for encoding parameters that have changed.
Definition: ni_device_api.h:984
NI_ALIGN
#define NI_ALIGN(x, a)
Definition: ni_generic_utils.h:57
scan_and_clean_hwdescriptors
int scan_and_clean_hwdescriptors(void)
Definition: ni_generic_utils.c:634
_ni_frame::force_pic_qp
uint16_t force_pic_qp
Definition: ni_device_api.h:2685
_ni_packet::av1_buffer_index
int av1_buffer_index
Definition: ni_device_api.h:2878
_ni_encoder_cfg_params::crf
int crf
Definition: ni_device_api.h:2283
_ni_session_context::hw_id
int hw_id
Definition: ni_device_api.h:1480
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_FRAME_AUX_DATA_VBV_BUFFER_SIZE
@ NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE
Definition: ni_device_api.h:588
ni_reconfig_crf2
ni_retcode_t ni_reconfig_crf2(ni_session_context_t *p_ctx, float crf)
Reconfigure crf float point value dynamically during encoding.
Definition: ni_device_api.c:10446
_ni_session_context::ori_width
int ori_width
Definition: ni_device_api.h:1564
_ni_xcoder_params::fps_number
uint32_t fps_number
Definition: ni_device_api.h:2748
NI_FRAME_AUX_DATA_VBV_MAX_RATE
@ NI_FRAME_AUX_DATA_VBV_MAX_RATE
Definition: ni_device_api.h:584
_ni_enc_quad_roi_custom_map::roiAbsQp_flag
uint8_t roiAbsQp_flag
Definition: ni_device_api.h:889
_ni_session_context::ddr_config
uint8_t ddr_config
Definition: ni_device_api.h:1628
enc_send_param::p_ctx
ni_demo_context_t * p_ctx
Definition: ni_encode_utils.h:39
_ni_test_frame_list
Definition: ni_generic_utils.h:105
NI_SET_CHANGE_PARAM_VUI_HRD_PARAM
@ NI_SET_CHANGE_PARAM_VUI_HRD_PARAM
Definition: ni_device_api.h:970
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:437
NI_FRAME_AUX_DATA_MAX_MIN_QP
@ NI_FRAME_AUX_DATA_MAX_MIN_QP
Definition: ni_device_api.h:572
_ni_vui_hrd::colorPrimaries
int32_t colorPrimaries
Definition: ni_device_api.h:663
SESSION_RUN_STATE_SEQ_CHANGE_DRAINING
@ SESSION_RUN_STATE_SEQ_CHANGE_DRAINING
Definition: ni_device_api.h:1180
ni_enc_prep_aux_data
void ni_enc_prep_aux_data(ni_session_context_t *p_enc_ctx, ni_frame_t *p_enc_frame, ni_frame_t *p_dec_frame, ni_codec_format_t codec_format, int should_send_sei_with_frame, uint8_t *mdcv_data, uint8_t *cll_data, uint8_t *cc_data, uint8_t *udu_data, uint8_t *hdrp_data)
Prepare auxiliary data that should be sent together with this frame to encoder based on the auxiliary...
Definition: ni_av_codec.c:857
SESSION_RUN_STATE_NORMAL
@ SESSION_RUN_STATE_NORMAL
Definition: ni_device_api.h:1179
ni_packet_buffer_alloc
ni_retcode_t ni_packet_buffer_alloc(ni_packet_t *p_packet, int packet_size)
Allocate memory for the packet buffer based on provided packet size.
Definition: ni_device_api.c:3714
frame_list_is_empty
bool frame_list_is_empty(ni_test_frame_list_t *list)
Definition: ni_generic_utils.c:174
ni_frame_new_aux_data
ni_aux_data_t * ni_frame_new_aux_data(ni_frame_t *frame, ni_aux_data_type_t type, int data_size)
Add a new auxiliary data to a frame.
Definition: ni_device_api.c:4006
_ni_encoder_change_params_t::colorPrimaries
uint8_t colorPrimaries
Definition: ni_device_api.h:1022
_ni_session_context::framerate
ni_framerate_t framerate
Definition: ni_device_api.h:1606
previous_time
struct timeval previous_time
Definition: ni_p2p_read_test.c:79
ni_log.h
Logging definitions.
_ni_custom_gop_params::custom_gop_size
int custom_gop_size
Definition: ni_device_api.h:2059
XCODER_TEST_RECONF_OFF
@ XCODER_TEST_RECONF_OFF
Definition: ni_device_api.h:1748
_niFrameSurface1::ui16FrameIdx
uint16_t ui16FrameIdx
Definition: ni_device_api.h:2825
enc_send_param
Definition: ni_encode_utils.h:37
_ni_demo_context::ivf_header_written
uint8_t ivf_header_written[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:150
enc_send_param::p_enc_ctx
ni_session_context_t * p_enc_ctx
Definition: ni_encode_utils.h:40
_ni_long_term_ref
Definition: ni_device_api.h:685
_ni_demo_context
Definition: ni_generic_utils.h:120
NI_LOG_INFO
@ NI_LOG_INFO
Definition: ni_log.h:61
_ni_vui_hrd::colorDescPresent
int32_t colorDescPresent
Definition: ni_device_api.h:659
_ni_xcoder_params::source_height
int source_height
Definition: ni_device_api.h:2758
NI_MULTICORE_ENCODE_MIN_WIDTH
#define NI_MULTICORE_ENCODE_MIN_WIDTH
Definition: ni_device_api.h:131
NI_APP_ENC_FRAME_META_DATA_SIZE
#define NI_APP_ENC_FRAME_META_DATA_SIZE
Definition: ni_defs.h:320
_ni_encoder_change_params_t::colorSpace
uint8_t colorSpace
Definition: ni_device_api.h:1024
XCODER_TEST_RECONF_BR_API
@ XCODER_TEST_RECONF_BR_API
Definition: ni_device_api.h:1767
NI_LOG_ERROR
@ NI_LOG_ERROR
Definition: ni_log.h:60
_ni_session_context::src_bit_depth
int src_bit_depth
Definition: ni_device_api.h:1494
_ni_frame::ni_pict_type
ni_pic_type_t ni_pict_type
Definition: ni_device_api.h:2653
_ni_vui_hrd::colorTrc
int32_t colorTrc
Definition: ni_device_api.h:667
_ni_framerate::framerate_num
int32_t framerate_num
Definition: ni_device_api.h:700
NI_TEST_RETCODE_END_OF_STREAM
#define NI_TEST_RETCODE_END_OF_STREAM
Definition: ni_generic_utils.h:52
_ni_xcoder_params::cfg_enc_params
ni_encoder_cfg_params_t cfg_enc_params
Definition: ni_device_api.h:2795
NI_PIX_FMT_NV12
@ NI_PIX_FMT_NV12
Definition: ni_device_api.h:265
XCODER_TEST_RECONF_INTRAPRD_API
@ XCODER_TEST_RECONF_INTRAPRD_API
Definition: ni_device_api.h:1768
_ni_frame::data_len
uint32_t data_len[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2690
_ni_frame::extra_data_len
unsigned int extra_data_len
Definition: ni_device_api.h:2683
_ni_demo_context::enc_eos_sent
int enc_eos_sent[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:158
_ni_demo_context::enc_resend
int enc_resend[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:156
PIC_TYPE_B
@ PIC_TYPE_B
Definition: ni_device_api.h:388
_ni_encoder_cfg_params::multicoreJointMode
int multicoreJointMode
Definition: ni_device_api.h:2303
ni_encoder_init_default_params
ni_retcode_t ni_encoder_init_default_params(ni_xcoder_params_t *p_param, int fps_num, int fps_denom, long bit_rate, int width, int height, ni_codec_format_t codec_format)
Initialize default encoder parameters.
Definition: ni_device_api.c:4148
_ni_encoder_change_params_t::colorDescPresent
uint8_t colorDescPresent
Definition: ni_device_api.h:1021
_ni_xcoder_params::reconf_hash
int reconf_hash[NI_BITRATE_RECONFIG_FILE_MAX_LINES][NI_BITRATE_RECONFIG_FILE_MAX_ENTRIES_PER_LINE]
Definition: ni_device_api.h:2803
NI_FRAME_AUX_DATA_FRAMERATE
@ NI_FRAME_AUX_DATA_FRAMERATE
Definition: ni_device_api.h:564
NI_TEST_RETCODE_EAGAIN
#define NI_TEST_RETCODE_EAGAIN
Definition: ni_generic_utils.h:53
_ni_test_frame_list::head
int head
Definition: ni_generic_utils.h:108
encoder_open_session
int encoder_open_session(ni_session_context_t *p_enc_ctx, int dst_codec_format, int iXcoderGUID, ni_xcoder_params_t *p_enc_params, int width, int height, ni_pix_fmt_t pix_fmt, bool check_zerocopy)
Encoder session open.
Definition: ni_encode_utils.c:1271
enc_send_param::output_total
int output_total
Definition: ni_encode_utils.h:43
_ni_demo_context::pts
int pts[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:163
encoder_receive
int encoder_receive(ni_demo_context_t *p_ctx, ni_session_context_t *enc_ctx_list, ni_session_data_io_t *in_frame, ni_session_data_io_t *pkt, int width, int height, int output_total, FILE **pfs_list)
Definition: ni_encode_utils.c:2215
NI_LOG_TRACE
@ NI_LOG_TRACE
Definition: ni_log.h:63
_ni_frame::end_of_stream
uint32_t end_of_stream
Definition: ni_device_api.h:2634
NI_NUM_PIXEL_ASPECT_RATIO
#define NI_NUM_PIXEL_ASPECT_RATIO
Definition: ni_av_codec.h:38
write_av1_ivf_trailer
int write_av1_ivf_trailer(ni_demo_context_t *p_ctx, ni_packet_t *p_out_pkt, uint32_t meta_size, FILE *p_file)
Definition: ni_encode_utils.c:1690
NI_TEST_RETCODE_FAILURE
#define NI_TEST_RETCODE_FAILURE
Definition: ni_generic_utils.h:50
_ni_xcoder_params::hwframes
int hwframes
Definition: ni_device_api.h:2804
_ni_session_context::device_handle
ni_device_handle_t device_handle
Definition: ni_device_api.h:1464
_ni_session_context::enc_change_params
ni_encoder_change_params_t * enc_change_params
Definition: ni_device_api.h:1594
_ni_session_context::p_session_config
void * p_session_config
Definition: ni_device_api.h:1475
NI_CODEC_FORMAT_AV1
@ NI_CODEC_FORMAT_AV1
Definition: ni_device_api.h:917
_ni_frame::sei_hdr_plus_len
unsigned int sei_hdr_plus_len
Definition: ni_device_api.h:2667
XCODER_TEST_RECONF_SLICE_ARG_API
@ XCODER_TEST_RECONF_SLICE_ARG_API
Definition: ni_device_api.h:1781
_ni_packet::av1_p_buffer
uint8_t * av1_p_buffer[MAX_AV1_ENCODER_GOP_NUM]
Definition: ni_device_api.h:2874
get_pixel_planar
ni_pixel_planar_format get_pixel_planar(ni_pix_fmt_t pix_fmt)
Definition: ni_generic_utils.c:145
_ni_packet::p_data
void * p_data
Definition: ni_device_api.h:2867
_ni_session_data_io
Definition: ni_device_api.h:2896
_ni_enc_quad_roi_custom_map::ipcm_flag
uint8_t ipcm_flag
Definition: ni_device_api.h:893
encoder_receive_thread
void * encoder_receive_thread(void *args)
Definition: ni_encode_utils.c:2403
_ni_enc_quad_roi_custom_map::field
struct _ni_enc_quad_roi_custom_map::@6 field
NI_MAX_PTS_QUEUE_SIZE
#define NI_MAX_PTS_QUEUE_SIZE
Definition: ni_generic_utils.h:77
encoder_close_session
int encoder_close_session(ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_in_data, ni_session_data_io_t *p_out_data)
encoder session close
Definition: ni_encode_utils.c:1942
NI_PIX_FMT_YUV420P10LE
@ NI_PIX_FMT_YUV420P10LE
Definition: ni_device_api.h:264
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_session_context::sender_handle
ni_device_handle_t sender_handle
Definition: ni_device_api.h:1470
_ni_frame::vui_time_scale
uint32_t vui_time_scale
Definition: ni_device_api.h:2716
set_demo_roi_map
void set_demo_roi_map(ni_session_context_t *p_enc_ctx)
Set up hard coded demo ROI map.
Definition: ni_encode_utils.c:41
NI_TEST_RETCODE_SUCCESS
#define NI_TEST_RETCODE_SUCCESS
Definition: ni_generic_utils.h:51
_ni_demo_context::num_frames_sent
uint64_t num_frames_sent[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:140
enc_recv_param::p_enc_ctx
ni_session_context_t * p_enc_ctx
Definition: ni_encode_utils.h:50
ni_reconfig_bitrate
ni_retcode_t ni_reconfig_bitrate(ni_session_context_t *p_ctx, int32_t bitrate)
Reconfigure bitrate dynamically during encoding.
Definition: ni_device_api.c:9957
ni_packet_buffer_free_av1
ni_retcode_t ni_packet_buffer_free_av1(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc for AV1 packets merge.
Definition: ni_device_api.c:3885
ni_usleep
void ni_usleep(int64_t usec)
Definition: ni_util.c:358
_ni_frame::force_key_frame
int force_key_frame
Definition: ni_device_api.h:2650
NI_GET_MAX_HWDESC_FRAME_INDEX
#define NI_GET_MAX_HWDESC_FRAME_INDEX(x)
Definition: ni_defs.h:290
NI_PIXEL_PLANAR_FORMAT_SEMIPLANAR
@ NI_PIXEL_PLANAR_FORMAT_SEMIPLANAR
Definition: ni_device_api.h:922
ni_pts_dequeue
int ni_pts_dequeue(ni_pts_queue *q, int *value)
Definition: ni_encode_utils.c:2491
enc_recv_param::frame_list
ni_test_frame_list_t * frame_list
Definition: ni_encode_utils.h:55
_ni_xcoder_params::sar_num
int sar_num
Definition: ni_device_api.h:2789
XCODER_TEST_RECONF_RC_MIN_MAX_QP
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP
Definition: ni_device_api.h:1754
_ni_test_frame_list::frames
ni_session_data_io_t frames[NI_MAX_BUFFERED_FRAME]
Definition: ni_generic_utils.h:107
_ni_packet
Definition: ni_device_api.h:2855
_ni_session_context::frame_num
uint64_t frame_num
Definition: ni_device_api.h:1533
write_av1_ivf_header
void write_av1_ivf_header(ni_demo_context_t *p_ctx, uint32_t width, uint32_t height, uint32_t frame_num, uint32_t frame_denom, FILE *p_file)
Definition: ni_encode_utils.c:1562
_ni_session_context::ori_luma_linesize
int ori_luma_linesize
Definition: ni_device_api.h:1682
_ni_session_context::roi_map
ni_enc_quad_roi_custom_map * roi_map
Definition: ni_device_api.h:1584
_ni_encoder_cfg_params::colorDescPresent
int colorDescPresent
Definition: ni_device_api.h:2325
_ni_frame::p_data
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2689
_ni_encoder_cfg_params::custom_gop_params
ni_custom_gop_params_t custom_gop_params
Definition: ni_device_api.h:2269
_ni_xcoder_params::sar_denom
int sar_denom
Definition: ni_device_api.h:2790
XCODER_TEST_RECONF_VBV_API
@ XCODER_TEST_RECONF_VBV_API
Definition: ni_device_api.h:1779
XCODER_TEST_FORCE_IDR_FRAME
@ XCODER_TEST_FORCE_IDR_FRAME
Definition: ni_device_api.h:1766
NI_TEST_RETCODE_SEQ_CHANGE_DONE
#define NI_TEST_RETCODE_SEQ_CHANGE_DONE
Definition: ni_generic_utils.h:55
_ni_frame::roi_len
unsigned int roi_len
Definition: ni_device_api.h:2679
NI_COL_TRC_UNSPECIFIED
@ NI_COL_TRC_UNSPECIFIED
Definition: ni_av_codec.h:125
NI_PARAM_AV1_ALIGN_WIDTH_HEIGHT
#define NI_PARAM_AV1_ALIGN_WIDTH_HEIGHT
Definition: ni_device_api.h:148
_ni_session_context::hw_action
int hw_action
Definition: ni_device_api.h:1611
_ni_session_context
Definition: ni_device_api.h:1410
_ni_rc_min_max_qp::minQpPB
int32_t minQpPB
Definition: ni_device_api.h:711
NI_PIX_FMT_P010LE
@ NI_PIX_FMT_P010LE
Definition: ni_device_api.h:266
ni_device_session_read
int ni_device_session_read(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, ni_device_type_t device_type)
Read data from the device If device_type is NI_DEVICE_TYPE_DECODER reads data packet from decoder If ...
Definition: ni_device_api.c:1769
_niFrameSurface1
Definition: ni_device_api.h:2823
NI_CODEC_HW_ENABLE
@ NI_CODEC_HW_ENABLE
Definition: ni_device_api.h:942
ni_frame_buffer_alloc_hwenc
ni_retcode_t ni_frame_buffer_alloc_hwenc(ni_frame_t *p_frame, int video_width, int video_height, int extra_len)
Allocate memory for the hwDescriptor buffer based on provided parameters taking into account pic size...
Definition: ni_device_api.c:8484
NI_MAX_NUM_DATA_POINTERS
#define NI_MAX_NUM_DATA_POINTERS
Definition: ni_defs.h:244
ni_device_session_restart
ni_retcode_t ni_device_session_restart(ni_session_context_t *p_ctx, int video_width, int video_height, ni_device_type_t device_type)
Send a restart command after flush command Only support Encoder now.
Definition: ni_device_api.c:13009
_ni_session_data_io::data
union _ni_session_data_io::@19 data
encoder_open
int encoder_open(ni_demo_context_t *p_ctx, ni_session_context_t *enc_ctx_list, ni_xcoder_params_t *p_api_param_list, int output_total, char p_enc_conf_params[][2048], char p_enc_conf_gop[][2048], ni_frame_t *p_ni_frame, int width, int height, int fps_num, int fps_den, int bitrate, int codec_format, ni_pix_fmt_t pix_fmt, int aspect_ratio_idc, int xcoder_guid, niFrameSurface1_t *p_surface, int multi_thread, bool check_zerocopy)
Definition: ni_encode_utils.c:2017
_ni_frame
Definition: ni_device_api.h:2627
enc_recv_param::output_height
int output_height
Definition: ni_encode_utils.h:52
NI_PIX_FMT_RGBA
@ NI_PIX_FMT_RGBA
Definition: ni_device_api.h:267
_ni_encoder_cfg_params::conf_win_bottom
int conf_win_bottom
Definition: ni_device_api.h:2312
_ni_frame::color_space
uint8_t color_space
Definition: ni_device_api.h:2710
ni_device_session_open
ni_retcode_t ni_device_session_open(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Open a new device session depending on the device_type parameter If device_type is NI_DEVICE_TYPE_DEC...
Definition: ni_device_api.c:710
_ni_session_context::roi_len
uint32_t roi_len
Definition: ni_device_api.h:1498
XCODER_TEST_RECONF_VUI_HRD_API
@ XCODER_TEST_RECONF_VUI_HRD_API
Definition: ni_device_api.h:1769
_ni_encoder_cfg_params::colorSpace
int colorSpace
Definition: ni_device_api.h:2328
XCODER_TEST_RECONF_LONG_TERM_REF
@ XCODER_TEST_RECONF_LONG_TERM_REF
Definition: ni_device_api.h:1752
NI_PIX_FMT_ABGR
@ NI_PIX_FMT_ABGR
Definition: ni_device_api.h:270
_ni_frame::color_primaries
uint8_t color_primaries
Definition: ni_device_api.h:2708
_ni_demo_context::start_time
uint64_t start_time
Definition: ni_generic_utils.h:143
NI_PIX_FMT_ARGB
@ NI_PIX_FMT_ARGB
Definition: ni_device_api.h:269
ni_reconfig_max_frame_size
ni_retcode_t ni_reconfig_max_frame_size(ni_session_context_t *p_ctx, int32_t max_frame_size)
Reconfigure maxFrameSize dynamically during encoding.
Definition: ni_device_api.c:10264
_ni_xcoder_params
Definition: ni_device_api.h:2743
_ni_frame::sei_hdr_content_light_level_info_len
unsigned int sei_hdr_content_light_level_info_len
Definition: ni_device_api.h:2664
enc_recv_param::output_width
int output_width
Definition: ni_encode_utils.h:51
frame_list_drain
int frame_list_drain(ni_test_frame_list_t *list)
Definition: ni_generic_utils.c:218
_ni_frame::sei_hdr_mastering_display_color_vol_len
unsigned int sei_hdr_mastering_display_color_vol_len
Definition: ni_device_api.h:2662
NI_COL_PRI_UNSPECIFIED
@ NI_COL_PRI_UNSPECIFIED
Definition: ni_av_codec.h:99
_ni_frame::video_full_range_flag
int video_full_range_flag
Definition: ni_device_api.h:2711
XCODER_TEST_RECONF_MAX_FRAME_SIZE_RATIO_API
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE_RATIO_API
Definition: ni_device_api.h:1780
_ni_session_context::ready_to_close
uint32_t ready_to_close
Definition: ni_device_api.h:1546
_ni_encoder_cfg_params::crop_width
int crop_width
Definition: ni_device_api.h:2409
ni_reconfig_max_frame_size_ratio
ni_retcode_t ni_reconfig_max_frame_size_ratio(ni_session_context_t *p_ctx, int32_t max_frame_size_ratio)
Reconfigure maxFrameSizeRatio dynamically during encoding.
Definition: ni_device_api.c:10556
ni_reconfig_vui
ni_retcode_t ni_reconfig_vui(ni_session_context_t *p_ctx, ni_vui_hrd_t *vui)
Reconfigure VUI HRD dynamically during encoding.
Definition: ni_device_api.c:10033
XCODER_TEST_RECONF_LTR_API
@ XCODER_TEST_RECONF_LTR_API
Definition: ni_device_api.h:1770
_ni_session_context::codec_format
uint32_t codec_format
Definition: ni_device_api.h:1488
_ni_rc_min_max_qp::maxQpPB
int32_t maxQpPB
Definition: ni_device_api.h:712
XCODER_TEST_RECONF_MAX_FRAME_SIZE_API
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE_API
Definition: ni_device_api.h:1775
_ni_encoder_cfg_params::colorPrimaries
int colorPrimaries
Definition: ni_device_api.h:2326
_ni_demo_context::enc_total_bytes_sent
uint64_t enc_total_bytes_sent[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:137
_ni_demo_context::av1_seq_header_len
uint32_t av1_seq_header_len[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:148
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
XCODER_TEST_CRF_FLOAT_API
@ XCODER_TEST_CRF_FLOAT_API
Definition: ni_device_api.h:1778
XCODER_TEST_RECONF_MAX_FRAME_SIZE_RATIO
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE_RATIO
Definition: ni_device_api.h:1764
ni_set_ltr_interval
ni_retcode_t ni_set_ltr_interval(ni_session_context_t *p_ctx, int32_t ltr_interval)
Set Long Term Reference interval.
Definition: ni_device_api.c:10142
_ni_encoder_cfg_params::crfFloat
float crfFloat
Definition: ni_device_api.h:2424
_ni_frame::sar_height
uint16_t sar_height
Definition: ni_device_api.h:2714
ni_pts_enqueue
int ni_pts_enqueue(ni_pts_queue *q, int value)
Definition: ni_encode_utils.c:2478
_ni_session_data_io::frame
ni_frame_t frame
Definition: ni_device_api.h:2900
_ni_session_context::ori_pix_fmt
int ori_pix_fmt
Definition: ni_device_api.h:1564
_ni_pts_queue::rear
int rear
Definition: ni_generic_utils.h:116
enc_send_param::output_width
int output_width
Definition: ni_encode_utils.h:41
NI_FRAME_AUX_DATA_LTR_INTERVAL
@ NI_FRAME_AUX_DATA_LTR_INTERVAL
Definition: ni_device_api.h:555
_ni_xcoder_params::color_space
int color_space
Definition: ni_device_api.h:2788
_ni_packet::av1_show_frame
int av1_show_frame
Definition: ni_device_api.h:2879
_ni_demo_context::reconfig_count
uint64_t reconfig_count
Definition: ni_generic_utils.h:142
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
MAX_AV1_ENCODER_GOP_NUM
#define MAX_AV1_ENCODER_GOP_NUM
Definition: ni_defs.h:325
_ni_frame::video_height
uint32_t video_height
Definition: ni_device_api.h:2637
_ni_packet::p_buffer
void * p_buffer
Definition: ni_device_api.h:2871
ni_reconfig_min_max_qp
ni_retcode_t ni_reconfig_min_max_qp(ni_session_context_t *p_ctx, ni_rc_min_max_qp *p_min_max_qp)
Reconfigure min&max qp dynamically during encoding.
Definition: ni_device_api.c:10339
_ni_vui_hrd::colorSpace
int32_t colorSpace
Definition: ni_device_api.h:670
_ni_demo_context::num_packets_received
uint64_t num_packets_received[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:141
_ni_encoder_cfg_params::colorTrc
int colorTrc
Definition: ni_device_api.h:2327
_ni_pts_queue::front
int front
Definition: ni_generic_utils.h:115
NI_FRAME_AUX_DATA_LONG_TERM_REF
@ NI_FRAME_AUX_DATA_LONG_TERM_REF
Definition: ni_device_api.h:550
NI_MAX_SEI_DATA
#define NI_MAX_SEI_DATA
Definition: ni_device_api.h:428
encoder_receive_data
int encoder_receive_data(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_out_data, int output_video_width, int output_video_height, FILE *p_file, ni_session_data_io_t *p_in_data)
Receive output data from encoder.
Definition: ni_encode_utils.c:1734
NI_COL_SPC_UNSPECIFIED
@ NI_COL_SPC_UNSPECIFIED
Definition: ni_av_codec.h:161
write_av1_ivf_packet
void write_av1_ivf_packet(ni_demo_context_t *p_ctx, ni_packet_t *p_out_pkt, uint32_t meta_size, FILE *p_file)
Definition: ni_encode_utils.c:1611
NI_MAX_FRAME_SIZE
#define NI_MAX_FRAME_SIZE
Definition: ni_device_api.h:178
_ni_encoder_cfg_params::conf_win_right
int conf_win_right
Definition: ni_device_api.h:2314
_ni_session_context::session_run_state
ni_session_run_state_t session_run_state
Definition: ni_device_api.h:1549
_ni_long_term_ref::use_cur_src_as_long_term_pic
uint8_t use_cur_src_as_long_term_pic
Definition: ni_device_api.h:689
_niFrameSurface1::device_handle
int32_t device_handle
Definition: ni_device_api.h:2830
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_demo_context::read_framerate
int read_framerate
Definition: ni_generic_utils.h:131
_ni_demo_context::enc_eos_received
int enc_eos_received[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:159
XCODER_TEST_INVALID_REF_FRAME_API
@ XCODER_TEST_INVALID_REF_FRAME_API
Definition: ni_device_api.h:1773
_ni_enc_quad_roi_custom_map
encoder AVC ROI custom map (1 MB = 8bits)
Definition: ni_device_api.h:885
_ni_session_context::meta_size
uint32_t meta_size
Params used in VFR mode Done///.
Definition: ni_device_api.h:1640
_ni_encoder_cfg_params::crop_height
int crop_height
Definition: ni_device_api.h:2410
_ni_encoder_cfg_params::aspectRatioHeight
int aspectRatioHeight
Definition: ni_device_api.h:2255
NI_MIN_HEIGHT
#define NI_MIN_HEIGHT
Definition: ni_device_api.h:126
XCODER_TEST_RECONF_BR
@ XCODER_TEST_RECONF_BR
Definition: ni_device_api.h:1749
_ni_encoder_cfg_params::planar
int planar
Definition: ni_device_api.h:2256
_ni_frame::start_of_stream
uint32_t start_of_stream
Definition: ni_device_api.h:2635
_ni_encoder_change_params_t::colorTrc
uint8_t colorTrc
Definition: ni_device_api.h:1023
_ni_packet::buffer_size
uint32_t buffer_size
Definition: ni_device_api.h:2872
_ni_vui_hrd::videoFullRange
int32_t videoFullRange
Definition: ni_device_api.h:681
_ni_vui_hrd::aspectRatioHeight
int32_t aspectRatioHeight
Definition: ni_device_api.h:677
_ni_frame::pts
long long pts
Definition: ni_device_api.h:2633
_ni_frame::pixel_format
int pixel_format
Definition: ni_device_api.h:2698
enc_send_param::frame_list
ni_test_frame_list_t * frame_list
Definition: ni_encode_utils.h:44
enc_recv_param::output_total
int output_total
Definition: ni_encode_utils.h:54
_ni_demo_context::av1_output_obu
uint8_t av1_output_obu
Definition: ni_generic_utils.h:149
ni_util.h
Utility definitions.
_ni_encoder_cfg_params::videoFullRange
int videoFullRange
Definition: ni_device_api.h:2304
_ni_rc_min_max_qp::maxQpI
int32_t maxQpI
Definition: ni_device_api.h:709
_ni_encoder_cfg_params::lookAheadDepth
int lookAheadDepth
Definition: ni_device_api.h:2281
SESSION_RUN_STATE_SEQ_CHANGE_OPENING
@ SESSION_RUN_STATE_SEQ_CHANGE_OPENING
Definition: ni_device_api.h:1181
encoder_send_data2
int encoder_send_data2(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_dec_out_data, ni_session_data_io_t *p_enc_in_data, int input_video_width, int input_video_height)
Definition: ni_encode_utils.c:880
NI_FRAME_AUX_DATA_CRF_FLOAT
@ NI_FRAME_AUX_DATA_CRF_FLOAT
Definition: ni_device_api.h:580
_ni_custom_gop_params::pic_param
ni_gop_params_t pic_param[NI_MAX_GOP_NUM]
Definition: ni_device_api.h:2060
ni_aligned_free
#define ni_aligned_free(p_memptr)
Definition: ni_util.h:399
_ni_xcoder_params::low_delay_mode
int low_delay_mode
Definition: ni_device_api.h:2763
ni_device_session_flush
ni_retcode_t ni_device_session_flush(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Send a flush command to the device If device_type is NI_DEVICE_TYPE_DECODER sends EOS command to deco...
Definition: ni_device_api.c:1512
_ni_session_context::pkt_num
uint64_t pkt_num
Definition: ni_device_api.h:1534
NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_H264
Definition: ni_device_api.h:913
_ni_frame::use_cur_src_as_long_term_pic
uint8_t use_cur_src_as_long_term_pic
Definition: ni_device_api.h:2647
NI_FRAME_AUX_DATA_INVALID_REF_FRAME
@ NI_FRAME_AUX_DATA_INVALID_REF_FRAME
Definition: ni_device_api.h:560
_ni_frame::video_width
uint32_t video_width
Definition: ni_device_api.h:2636
ni_should_send_sei_with_frame
int ni_should_send_sei_with_frame(ni_session_context_t *p_enc_ctx, ni_pic_type_t pic_type, ni_xcoder_params_t *p_param)
Whether SEI (HDR) should be sent together with this frame to encoder.
Definition: ni_av_codec.c:186
NI_FRAME_LITTLE_ENDIAN
#define NI_FRAME_LITTLE_ENDIAN
Definition: ni_device_api.h:108
_ni_xcoder_params::bitrate
int bitrate
Definition: ni_device_api.h:2759
enc_send_param::output_height
int output_height
Definition: ni_encode_utils.h:42
NI_MIN_WIDTH
#define NI_MIN_WIDTH
Definition: ni_device_api.h:124
_ni_session_context::pixel_format
int pixel_format
Definition: ni_device_api.h:1618
_ni_demo_context::enc_total_bytes_received
uint64_t enc_total_bytes_received[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:138
_ni_aux_data
Definition: ni_device_api.h:620
NI_LOG_DEBUG
@ NI_LOG_DEBUG
Definition: ni_log.h:62
_ni_framerate
Definition: ni_device_api.h:697
_ni_vui_hrd::aspectRatioWidth
int32_t aspectRatioWidth
Definition: ni_device_api.h:674
_ni_encoder_change_params_t::aspectRatioWidth
uint16_t aspectRatioWidth
Definition: ni_device_api.h:1025
NI_FRAME_AUX_DATA_INTRAPRD
@ NI_FRAME_AUX_DATA_INTRAPRD
Definition: ni_device_api.h:541
_ni_demo_context::curr_enc_index
uint8_t curr_enc_index
Definition: ni_generic_utils.h:134
_ni_session_context::ori_bit_depth_factor
int ori_bit_depth_factor
Definition: ni_device_api.h:1564
_ni_session_context::ori_height
int ori_height
Definition: ni_device_api.h:1564
_ni_pts_queue
Definition: ni_generic_utils.h:112
_ni_xcoder_params::color_transfer_characteristic
int color_transfer_characteristic
Definition: ni_device_api.h:2787
ni_device_session_close
ni_retcode_t ni_device_session_close(ni_session_context_t *p_ctx, int eos_recieved, ni_device_type_t device_type)
Close device session that was previously opened by calling ni_device_session_open() If device_type is...
Definition: ni_device_api.c:1379
encoder_send_data3
int encoder_send_data3(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_in_data, int input_video_width, int input_video_height, int eos)
Send encoder input data, read from uploader instance hwframe.
Definition: ni_encode_utils.c:1188
_ni_enc_quad_roi_custom_map::qp_info
uint8_t qp_info
Definition: ni_device_api.h:891
_ni_rc_min_max_qp::maxDeltaQp
int32_t maxDeltaQp
Definition: ni_device_api.h:710
ni_set_ltr
ni_retcode_t ni_set_ltr(ni_session_context_t *p_ctx, ni_long_term_ref_t *ltr)
Set a frame's support of Long Term Reference frame during encoding.
Definition: ni_device_api.c:10114
ni_decoder_frame_buffer_free
ni_retcode_t ni_decoder_frame_buffer_free(ni_frame_t *p_frame)
Free decoder frame buffer that was previously allocated with ni_decoder_frame_buffer_alloc,...
Definition: ni_device_api.c:3645
_ni_session_context::roi_avg_qp
uint32_t roi_avg_qp
Definition: ni_device_api.h:1499
ni_reconfig_slice_arg
ni_retcode_t ni_reconfig_slice_arg(ni_session_context_t *p_ctx, int16_t sliceArg)
Reconfigure sliceArg dynamically during encoding.
Definition: ni_device_api.c:10629
ni_prepare_pts_queue
void ni_prepare_pts_queue(ni_pts_queue *q, ni_xcoder_params_t *enc_param, int pts_start)
Definition: ni_encode_utils.c:2503
_ni_session_context::async_mode
int async_mode
Definition: ni_device_api.h:1665
NI_FRAME_AUX_DATA_BITRATE
@ NI_FRAME_AUX_DATA_BITRATE
Definition: ni_device_api.h:537
_ni_encoder_change_params_t::videoFullRange
uint8_t videoFullRange
Definition: ni_device_api.h:1027
enc_recv_param
Definition: ni_encode_utils.h:47
NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_H265
Definition: ni_device_api.h:914
_ni_frame::use_long_term_ref
uint8_t use_long_term_ref
Definition: ni_device_api.h:2648
ni_frame_wipe_aux_data
void ni_frame_wipe_aux_data(ni_frame_t *frame)
Free and remove all auxiliary data from the frame.
Definition: ni_device_api.c:4116
_ni_packet::data_len
uint32_t data_len
Definition: ni_device_api.h:2868